Bug 4833 - initlog makes daemons depend on stdin of starting session
initlog makes daemons depend on stdin of starting session
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: initscripts (Show other bugs)
6.0
All Linux
medium Severity medium
: ---
: ---
Assigned To: Bill Nottingham
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 1999-09-01 13:49 EDT by rjb
Modified: 2014-03-16 22:09 EDT (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2000-01-21 01:12:54 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


Attachments (Terms of Use)

  None (edit)
Description rjb 1999-09-01 13:49:36 EDT
initlog does a dup of fd 0 (usually getting 10) before
fork(). the parent closes it, but the child does not. Most
daemon programs close 0,1,2 but do not know to close 10.
E.g. consider this extract of strace output....

870   execve("/sbin/initlog", ["initlog", "-c",
"/usr/sbin/snmpd"], [/* 10 vars */]) = 0
870   brk(0)                            = 0x804e2ac
870   open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No
such file or directory)
870   open("/etc/ld.so.cache", O_RDONLY) = 4
870   fstat(4, {st_mode=0, st_size=0, ...}) = 0
870   mmap(0, 21944, PROT_READ, MAP_PRIVATE, 4, 0) =
0x40014000
870   close(4)                          = 0
870   open("/lib/libc.so.6", O_RDONLY)  = 4
870   fstat(4, {st_mode=0, st_size=0, ...}) = 0
870   read(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096)
= 4096
870   mmap(0, 974392, PROT_READ|PROT_EXEC, MAP_PRIVATE, 4,
0) = 0x4001a000
870   mprotect(0x40100000, 32312, PROT_NONE) = 0
870   mmap(0x40100000, 20480, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED, 4, 0xe5000) = 0x40100000
870   mmap(0x40105000, 11832, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40105000
870   close(4)                          = 0
870   munmap(0x40014000, 21944)         = 0
870   personality(PER_LINUX)            = 0
870   getpid()                          = 870
870   brk(0)                            = 0x804e2ac
870   brk(0x804e2e4)                    = 0x804e2e4
870   brk(0x804f000)                    = 0x804f000
870   pipe([4, 5])                      = 0
870   pipe([6, 7])                      = 0
870   pipe([8, 9])                      = 0
870   dup(0)                            = 10
870   fork()                            = 871
870   close(10)                         = 0
870   close(5)                          = 0
870   close(7)                          = 0
870   close(9)                          = 0
870   pipe([5, 7])                      = 0
870   SYS_168(0x804ed20, 0x2, 0x1f4, 0x1f4, 0x804ed20
<unfinished ...>
871   dup2(5, 1)                        = 1
871   dup2(7, 2)                        = 2
871   dup2(9, 21)                       = 21
871   close(5)                          = 0
871   close(7)                          = 0
871   close(9)                          = 0
871   close(4)                          = 0
871   close(6)                          = 0
871   execve("/usr/sbin/snmpd", ["/usr/sbin/snmpd"], [/* 10
vars */]) = 0

This leads to many daemons having a reference to the
stdin of the starting session. (you can see this with lsof)

If the stdin was a real terminal then there is no problem
because the /dev/tty.. entry continues to exist after
the user logs out.

But, if the stdin is a socket (due to use of rsh) then
the rsh does not terminate (the init.d/xxx appears to never
terminate). If the user drops the connection then the
daemon gets killed!

initlog should not do this dup().

This problem can be worked around by editing
init.d/functions andputting a </dev/null on line 78 before
the &&.
Comment 1 Bill Nottingham 1999-09-20 16:49:59 EDT
fixed in initscripts-4.44-1.
Comment 2 rjb 1999-11-24 20:02:59 EST
This behavior is different but not fixed in 4.48-1.
The daemon still ends up with a reference to the socket, and the
rsh is still blocked. E.g.:

bash# rsh revs lsof -p20451
COMMAND   PID USER   FD   TYPE DEVICE   SIZE   NODE NAME
nfsd    20451 root  cwd    DIR    3,3   4096      2 /
nfsd    20451 root  rtd    DIR    3,3   4096      2 /
nfsd    20451 root    0u  sock    0,0        166838 can't identify protocol
nfsd    20451 root    1w  FIFO    0,0        166867 pipe
nfsd    20451 root    2w  FIFO    0,0        166868 pipe
nfsd    20451 root    3w   REG    3,3 255731  59079 /tmp/wibble
nfsd    20451 root    4r   REG    3,3    557  15175 /etc/initlog.conf
nfsd    20451 root    9r  FIFO    0,0        166869 pipe
nfsd    20451 root   21w  FIFO    0,0        166869 pipe

[1]+  Stopped (tty input)     rsh revs strace -f -o /tmp/wibble
/etc/rc.d/init.d/nfs start
bash#

Indeed, the strace shows that initlog now does a close(1073817264)  getting
EBADF arounf about the point where it would be expected to close(0)

Please can this be reopened and fixed.
Comment 3 weejock-rhbug 2000-01-20 17:10:59 EST
A slightly related bug is that the child daemon inherits a descriptor to
/etc/initlog.conf.

This diff fixes that:

--- initscripts-4.48/src/initlog.c.close        Thu Jan 20 16:58:01 2000
+++ initscripts-4.48/src/initlog.c      Thu Jan 20 16:59:43 2000
@@ -42,9 +42,9 @@
     int lfac=-1,lpri=-1;

     if ((fd=open(fname,O_RDONLY))==-1) return;
-    if (fstat(fd,&sbuf)) return;
+    if (fstat(fd,&sbuf)) goto clout;
     data=malloc(sbuf.st_size+1);
-    if (read(fd,data,sbuf.st_size)!=sbuf.st_size) return;
+    if (read(fd,data,sbuf.st_size)!=sbuf.st_size) goto clout;
     data[sbuf.st_size] = '\0';
     while ((line=getLine(&data))) {
        if (line[0]=='#') continue;
@@ -88,6 +88,9 @@
     }
     if (lfac!=-1) logfacility=lfac;
     if (lpri!=-1) logpriority=lpri;
+
+clout:
+    close(fd);
 }

 char *getLine(char **data) {
Comment 4 Bill Nottingham 2000-01-20 17:20:59 EST
Second one is fixed since 4.65 or so.
First one is being worked on.
Comment 5 Bill Nottingham 2000-01-21 01:12:59 EST
The first bug also seems to be fixed as of initscripts-4.5x or so,
and I can't reproduce it in initscripts-latest.

Note You need to log in before you can comment on or make changes to this bug.