password (& host?) file lookups, daemons and stray descriptors
From: Mr. Uh Clem (uhclem_at_DutchElmSt.invalid)
Date: 06/24/05
- Previous message: Michael Kraemer: "Re: Getting HPUX"
- Next in thread: Alan D Johnson: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Alan D Johnson: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Barry Margolin: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Rick Jones: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 23 Jun 2005 18:42:22 -0400
I've run into a strange problem on an HP11i system involving
a daemon program which
* calls getpwuid() as part of a security check during
initialization
* does the normal daemonization things:
forks, setsid, etc.,
close all descriptors,
redirect 0-2 to /dev/null.
* opens a lockfile and does a lockf on it.
* subsequently calls getpwnam() to obtain a uid.
On this system, the getpwnam() call causes the
lock to be lost on the lockfile. (We don't seem
to have this problem on our various other *ix
flavors, although that could be a matter of
system configuration: nsswitch.conf, etc.)
Debugging shows that getpwuid leaves a descriptor
open after it is called. From truss, it looks as
if it creates a socket and leaves it open on fd 3.
It is not hard to believe that Bad Things Happen(tm)
when the daemonizing closes all child fds and the
lockfile winds up with file descriptor 3. Truss
seems to show the getpwnam() call atempting a sendto()
on fd 3, failing, then doing it's thing on 4 and
closing 4.
Well, I thought I could deal with this by calling
endpwent() after the getwpuid(), but the extra
descriptor does not go away and the problem persists.
This is not the post I thought it would be...
It took a while to figure out how to make it fail
from a simple program, but I finally did:
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pwd.h>
#include <errno.h>
int check_fds(char *where);
main()
{
struct passwd *pw;
int status, fd;
check_fds("main");
status = getuid();
printf("getuid() is %d\n", status);
if(status == -1)
exit(11);
pw = getpwuid(status);
if (pw == NULL)
exit(12);
printf("user name is %s\n", pw->pw_name);
check_fds("after getpwuid");
endpwent();
check_fds("after endpwent");
/* simulate daemonize */
close(3);
close(4);
fd = open("/tmp/mylock", O_RDWR);
if (fd == -1)
{
perror("open");
exit(1);
}
printf("locfile open on fd %d\n", fd);
status = lockf(fd, F_TLOCK, 0);
if (status == -1)
exit(2);
printf("locked\n");
getc(stdin);
pw = getpwnam("bin"); [ this call seems to lose the lock ]
if (pw == NULL)
exit(3);
check_fds("after getpwnam");
printf("got uid %d\n", pw->pw_uid);
getc(stdin);
printf("exiting\n");
exit(0);
}
int check_fds(char *where)
{
int status, fd;
for (fd = 0; fd < 10; fd++)
{
status = dup(fd);
if (status != -1)
{
printf("%d ", fd);
close(status);
}
}
printf("- %s\n", where);
return(0);
}
# gcc test2.c
# ./a.out
0 1 2 - main
getuid() is 0
user name is root
0 1 2 3 - after getpwuid
0 1 2 3 - after endpwent
locfile open on fd 3
locked
[the file is locked at this point]
0 1 2 3 - after getpwnam
got uid 2
[the file is unlocked at this point]
exiting
#
[instead of here, when the program exits]
If I run under truss, an extra fd
seems to get injected:
execve("./a.out", 0x7b0404a0, 0x7b0404a8) = 0
[32-bit]
open("/usr/lib/dld.sl", O_RDONLY, 02204) = 4
read(4, "02\v010e0512@ \0\0\0\0\0\0\0\0\0".., 128) = 128
lseek(4, 128, SEEK_SET) = 128
read(4, "10\0\004\0\0\0( \002e884\0\0\0\0".., 48) = 48
mmap(NULL, 190596, PROT_READ|PROT_EXEC,
MAP_SHARED|MAP_SHLIB|MAP_STATICPREDICTION, 4, 0x9000) = 0xc0010000
mmap(NULL, 16104, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_SHLIB,
4, 0x38000) = 0x7b03c000
close(4) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, NULL) = 0x7b03a000
sysconf(_SC_CPU_VERSION) = 532
open("/opt/graphics/OpenGL/lib/libogltls.sl", O_RDONLY, 0) = 4
fstat(4, 0x7b042f98) = 0
read(4, "0210010e0512@ \0\0\0\0\0\0\0\0\0".., 128) = 128
lseek(4, 128, SEEK_SET) = 128
read(4, "10\0\004\0\0\0( \0\013\ \0\010\0".., 48) = 48
read(4, "80\0\001\0\0\0 9 2 4 5 ", 12) = 12
lseek(4, 8192, SEEK_SET) = 8192
read(4, "058cy 10\0\0\0D \0\002$ \0\0\001".., 112) = 112
mmap(NULL, 8192, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_SHLIB, 4, 0x2000) =
0xc0005000
mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_SHLIB,
4, 0x4000) = 0x7b039000
close(4) = 0
open("/usr/lib/libc.2", O_RDONLY, 0) = 4
fstat(4, 0x7b043158) = 0
read(4, "0214010e0512@ \0\0\0\0\0\0\0\0\0".., 128) = 128
lseek(4, 128, SEEK_SET) = 128
read(4, "10\0\004\0\0\0( \013y c4\0\010\0".., 48) = 48
read(4, "80\0\0\v\0\0\004\0\0\0\0", 12) = 12
lseek(4, 430080, SEEK_SET) = 430080
read(4, "058cy 10\0\0\ad \0\0K L \0\0\002".., 112) = 112
mmap(NULL, 1277952, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_SHLIB, 4,
0x69000) = 0xc0100000
mmap(NULL, 45056, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_SHLIB, -1, NULL) = 0x7b02e000
mmap(0x7b026000, 32768, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_FIXED|MAP_SHLIB, 4, 0x1a1000) = 0x7b026000
mmap(NULL, 16384, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, NULL) = 0x7b022000
close(4) = 0
open("/usr/lib/libdld.2", O_RDONLY, 0) = 4
fstat(4, 0x7b043318) = 0
read(4, "02\v010e0512@ \0\0\0\0\0\0\0\0\0".., 128) = 128
lseek(4, 128, SEEK_SET) = 128
read(4, "10\0\004\0\0\0( \0\0) \ \0\010\0".., 48) = 48
read(4, "80\0\0\v\0\0\004\0\0\0\0", 12) = 12
lseek(4, 8192, SEEK_SET) = 8192
read(4, "058cy 10\0\0\0\f\0\00214\0\0\001".., 112) = 112
mmap(NULL, 12288, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_SHLIB, 4, 0x2000)
= 0xc0007000
mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_SHLIB,
4, 0x5000) = 0x7b021000
close(4) = 0
open("/usr/lib/libc.2", O_RDONLY, 0) = 4
fstat(4, 0x7b043498) = 0
close(4) = 0
mmap(NULL, 16384, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, NULL) = 0x7b01d000
mmap(NULL, 3368, PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, NULL) = 0x7b01c000
sigsetreturn(0x7b023f36, 0x6211988, 1392) = 0
looks like we start here...
dup(0) = 4
sysconf(_SC_CPU_VERSION) = 532
brk(0x40001140) = 0
brk(0x40003134) = 0
brk(0x40006000) = 0
ioctl(1, TCGETA, 0x7b040958) = 0
close(4) = 0
dup(1) = 4
close(4) = 0
dup(2) = 4
close(4) = 0
dup(3) = 4
close(4) = 0
dup(4) ERR#9 EBADF
dup(5) ERR#9 EBADF
dup(6) ERR#9 EBADF
dup(7) ERR#9 EBADF
dup(8) ERR#9 EBADF
dup(9) ERR#9 EBADF
write(1, "0 1 2 3 - m a i n \n", 15) = 15
getuid() = 0 (0)
write(1, "g e t u i d ( ) i s 0 \n", 14) = 14
If I close(3) at the start of the program to get rid of the
extraneous fd truss seems to give, the following winds up on
fd 3.
open("/var/spool/pwgr/status", O_RDONLY, 0) = 4
mmap(NULL, 532, PROT_READ, MAP_SHARED|MAP_VARIABLE|MAP_FILE|MAP_ADDR32,
4, NULL) = 0xc0057000
close(4) = 0
socket(AF_UNIX, SOCK_DGRAM, 0) = 4
getpid() = 19401
(19400)
unlink("/var/spool/sockets/pwgr/client19401") ERR#2
ENOENT
bind(4, 0x7b02f580, 38) = 0
fcntl(4, F_SETFD, 1) = 0
time(NULL) =
1119565603
poll(0x7b041798, 1, 0) = 1
sendto(4, "\0\0\00 \0\0\001\0\0\0\0\0\0\001".., 48, 0, NULL, NULL) = 48
poll(0x7b041798, 1, 1000) = 1
recv(4, "\0\0\03 \0\0\0\0\0\0\0\0\0\0\0# ".., 2064, 0) = 51
write(1, "u s e r n a m e i s r o o ".., 18) = 18
dup(0) = 5
close(5) = 0
dup(1) = 5
close(5) = 0
dup(2) = 5
close(5) = 0
dup(3) = 5
close(5) = 0
dup(4) = 5
close(5) = 0
dup(5) ERR#9 EBADF
dup(6) ERR#9 EBADF
dup(7) ERR#9 EBADF
dup(8) ERR#9 EBADF
dup(9) ERR#9 EBADF
write(1, "0 1 2 3 4 - a f t e ".., 27) = 27
dup(0) = 5
close(5) = 0
dup(1) = 5
close(5) = 0
dup(2) = 5
close(5) = 0
dup(3) = 5
close(5) = 0
dup(4) = 5
close(5) = 0
dup(5) ERR#9 EBADF
dup(6) ERR#9 EBADF
dup(7) ERR#9 EBADF
dup(8) ERR#9 EBADF
dup(9) ERR#9 EBADF
write(1, "0 1 2 3 4 - a f t e ".., 27) = 27
close(3) = 0
close(4) = 0
open("/tmp/mylock", O_RDWR, 0160100) = 3
write(1, "l o c f i l e o p e n o n ".., 21) = 21
lockf(3, 0x2, 0) = 0
write(1, "l o c k e d \n", 7) = 7
brk(0x40008000) = 0
ioctl(0, TCGETA, 0x7b040718) = 0
read(0, 0x400059a0, 8192) [sleeping]
read(0, "\n", 8192) = 1
getpid() = 19401
(19400)
poll(0x7b041798, 1, 0) = 1
When I close(3) at the start of the program to get rid of the
fd truss gives, this sendto is performed against the lockfile
and results in ENOTSOCK. In this case, where we don't even
touch 3, the lock STILL gets lost! I don't see how..
sendto(4, "\0\0\00 \0\0\001\0\0\001\0\0\002".., 48, 0, NULL, NULL) ERR#9
EBADF
open("/etc/nsswitch.conf", O_RDONLY, 0666) = 4
brk(0x4000a000) = 0
ioctl(4, TCGETA, 0x7b041618) ERR#25
ENOTTY
read(4, "# \n# / e t c / n s s w i t c ".., 8192) = 376
brk(0x4000b000) = 0
read(4, 0x40007e58, 8192) = 0
close(4) = 0
open("/usr/lib/libnss_files.1", O_RDONLY, 0) = 4
fstat(4, 0x7b041818) = 0
read(4, "0210010e0512@ \0\0\0\0\0\0\0\0\0".., 128) = 128
lseek(4, 128, SEEK_SET) = 128
read(4, "10\0\004\0\0\0( \0\0k T \0\010\0".., 48) = 48
read(4, "80\0\0\v\0\0\004\0\0\0\0", 12) = 12
lseek(4, 12288, SEEK_SET) = 12288
read(4, "058cy 10\0\0\0D \0\004f0\0\0\002".., 112) = 112
mmap(NULL, 28672, PROT_READ|PROT_EXEC, MAP_SHARED|MAP_SHLIB, 4, 0x3000)
= 0xc0058000
mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_SHLIB,
4, 0xa000) = 0x7b01b000
close(4) = 0
open("/usr/lib/libdld.2", O_RDONLY, 0) = 4
fstat(4, 0x7b0419d8) = 0
close(4) = 0
open("/etc/passwd", O_RDONLY, 0666) = 4
brk(0x4000d000) = 0
ioctl(4, TCGETA, 0x7b041418) ERR#25
ENOTTY
read(4, "r o o t : R e 9 b n r j Y 8 i a ".., 8192) = 591
lseek(4, 4294966794, SEEK_CUR) = 89
close(4) = 0
dup(0) = 4
close(4) = 0
dup(1) = 4
close(4) = 0
dup(2) = 4
close(4) = 0
dup(3) = 4
close(4) = 0
dup(4) ERR#9 EBADF
dup(5) ERR#9 EBADF
dup(6) ERR#9 EBADF
dup(7) ERR#9 EBADF
dup(8) ERR#9 EBADF
dup(9) ERR#9 EBADF
write(1, "0 1 2 3 - a f t e r ".., 25) = 25
write(1, "g o t u i d 2 \n", 10) = 10
read(0, 0x400059a0, 8192) [sleeping]
read(0, "\n", 8192) = 1
write(1, "e x i t i n g \n", 8) = 8
getpid() = 19401
(19400)
unlink("/var/spool/sockets/pwgr/client19401") = 0
exit(0)
WIFEXITED(0)
What the Fudd is going on ?? I'm stumped. I'd love
to find out I'm doing Something Stupid(tm).
--
Clem
"If you push something hard enough, it will fall over."
- Fudd's first law of opposition
- Previous message: Michael Kraemer: "Re: Getting HPUX"
- Next in thread: Alan D Johnson: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Alan D Johnson: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Barry Margolin: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Reply: Rick Jones: "Re: password (& host?) file lookups, daemons and stray descriptors"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|
|