Changes in fork ?

Richard B. Johnson root en chaos.analogic.com
Sab Ene 22 10:09:29 CST 2000


On Fri, 21 Jan 2000, Sergey Kubushin wrote:

> Hi, everybody!
> 
> I have a question about fork() (?) behaviour. The problem shows itself as
> truncated lines in ps output on processes that are forked outta daemons
> which use setproctitle() (from sendmail sources) such as sendmail, inetd
> etc. All's fine on 2.2.xx kernels, but I have the following under 2.3.xx :
> 
> === Cut ===
> 22352  ?  S    0:00 sendmail: accepting connectio
> 22353  ?  S    0:00  \_ sendmail: LAA14150 relay1.cha
> .
> .
> .
>   701  ?  S    0:13 inetd
>  2765  ?  S    0:01  \_ ftpd: 19
>  5294  ?  S    0:00  \_ ftpd: sa
> 13547  ?  S    0:00  \_ ftpd: fi
> 14656  ?  S    0:00  \_ ftpd: 19
> 14760  ?  S    0:00  \_ ftpd: 21
> 15685  ?  S    0:00  \_ ftpd: sa
> 16160  ?  S    0:00  \_ ftpd: at
> 18482  ?  S    0:00  \_ ftpd: 21
> .
> .
> .
> === Cut ===
> 

Yes. This was previously reported by myself. Basically, what the
daemons are doing is:

	int main (int argc, *argv[])
        {                 /* setproctitle() */
            strcpy(argv[0], "New Name to be seen by `ps`");

This is NotGood(tm) because no child knows how much space was
available for the string. However, it's been done for ages. New
/proc/###/cmdline code (where `ps` gets the command-line), now
only allows you to read the length of the initial allocation.

The `fix` is not a kernel fix. Any child of a parent which desires
to overwrite argv[0], has to make sure the parent has enough space
allocated. This means that the child should be kicked-off with
its own arguments, with enough space allocated like:

	parent's main(int args, char *argv[])
        {
            extract_command_line_pars(args, argv);  /* Do first */

            argv[0] = buffer0[0x100];     /* Replace pointers */
            argv[1] = buffer1[0x100];
            argv[2] = NULL;

            switch(fork())
            {
            case 0:    /* child */
                 strncpy(argv[0], "New stuff", 0x100);


If you fix all the `parent` daemons, you will have a good `ps` output.
Here is an example, program `status` before/after.

PID   Name            Stat  CPU     Mem   Exe   Command line
1     (init)          S     0.02    220   188   init [5]  
2     (kswapd)        S     0.00    220   188             
3     (kflushd)       S     0.00    220   188             
4     (kupdate)       S     0.00    220   188             
40    (crond)         S     0.04    844   0     /usr/sbin/crond 
59    (klogd)               0.02    796   20    /usr/sbin/klogd -s -k /System.ma
[Snipped...]

15241 (status)        R     0.00    712   4     really big command
                                                ^^^^^^^^^^^^^^^^ Truncated
15625 (pine)          S     0.14    2688  0     pine      
15754 (status)        R     0.01    712   4     really big command
line that _has_a_lot_of_stuff_in_it    
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Fixed.

Cheers,
Dick Johnson

Penguin : Linux version 2.3.39 on an i686 machine (800.63 BogoMips).


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo en vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



Más información sobre la lista de distribución Ayuda