Re: mutilog via fifo
Daryl Tester <[email protected]> Wed, 06 Aug 2008 11:53:16 +0930
| Newsgroups | gmane.comp.djb.syslog |
|---|---|
| Message-ID | <[email protected]> |
Sorry, my free cycles were devoted to another problem, but I've now had a look into this further. Paul Jarc wrote: > Daryl Tester <[email protected]> wrote: >> tcpdaemon listens on a socket. When a connection establishes, it >> forks, sets sets up fd 0 & 1 onto the incoming connection, setuid to >> the UID supplied, then execs the elhttp process. > Almost. tcpserver changes its uid/gid after opening the listening > socket (since that's the part that requires root access, for > low-numbered ports), but before entering the loop where it accepts > incoming connections. Ah, mea culpa for going from memory. I keep forgetting it doesn't improve with age (which should be a reminder, but I forget that too :-). >> /dev/stderr should return this file descriptor upon opening, > No, it would be a new descriptor, but connected to the same underlying > pipe. Yep, bad description on my part. > (I would say "as if by dup()", but I don't know if that's > entirely true - descriptor flags and positioning might be kept > separate, FAIK.) I had (still have) that uncertainty as well ... Later, that same thread, Richard wrote: > This works like a charm :) Good. I did forget to mention that a dummy file argument had to be left in place in position 4 of the arguments to cause the fdopen to work (it doesn't matter what argument, just as long as there is one), but I see you cleverly worked this out. :-) I then wrote: >> I'm still intrigued as to why the open of /dev/stderr is failing >> though. It looks to be a kernel problem, which can be replicated simply by running (as root) (note: there may be transcription errors - the vm I'm using can't cut 'n' paste at the moment): # setuidgid nobody sh -c "echo hi; echo there > /dev/stderr" hi sh: /dev/stderr: Permission denied However, stderr (which symlinks to /proc/self/fd/2) appears to have the correct permissions and ownership (of course, it will be a different process id, but it appears to be set correctly for self). # setuidgid nobody ls -l /proc/self/fd total 0 lrwx------ 1 nobody nobody 64 Aug 6 11:25 0 -> /dev/pts/3 lrwx------ 1 nobody nobody 64 Aug 6 11:25 1 -> /dev/pts/3 lrwx------ 1 nobody nobody 64 Aug 6 11:25 2 -> /dev/pts/3 lr-x------ 1 nobody nobody 64 Aug 6 11:25 3 -> /proc/5482/fd The attached C program exhibits the same issue, so it doesn't appear specific to anything setuidgid is doing. The program should emit "open(STDERR) as uid 500: Permission denied" if the issue exists, or silently exit if it works :-). For the record, I'm seeing the issue on a Centos 5.2 box running 2.6.18, and an Ubuntu 8.04 running 2.6.24. So congratulations Richard, it looks like you've unearthed a bug (or two, if you count elhttp's silent fopen error :-). Cheers, --dt
tst.c
(text/x-csrc, 815 B)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int
main(int argc, char *argv[])
{
int fd;
if (getuid() != 0) {
fprintf(stderr, "I insist I must run as root\n");
exit(1);
}
fd = open("/dev/stderr", O_WRONLY);
if (fd == -1) {
perror("open(STDERR) as root");
} else {
close(fd);
}
/* Set ourselves to an arbitrary user id, group first */
if (setgid(500) == -1) {
perror("setgid(500)");
exit(1);
}
if (setuid(500) == -1) {
perror("setuid(500)");
exit(1);
}
fd = open("/dev/stderr", O_WRONLY);
if (fd == -1) {
perror("open(STDERR) as uid 500");
} else {
close(fd);
}
return 0;
}