6

This question may seem a bit silly, but since in Unix-based systems, replacing an executable's image is done in a single step, replacing the currently running process, in the function call execve (and derivatives), the question is:

Why does sudo fork() by default before execve'ing the replacement process?

By forking before, additional kernel elements have to be initiallized, and although fork is quite optimized in some Unices, there are still some unavoidable elements that must be initialized. If fork() did not occur by default, the PID space would increment slower.

If you are curious, this default behaviour can be inspected by issuing a command such as

sudo sleep 30

the current code [1] is quite more complicated to follow, as many features have been added since; but in the version hosted by Apple [2] it is quite clear what it does.

#ifndef PROFILING
    if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
        exit(0);
    else
        EXEC(safe_cmnd, NewArgv);   /* run the command */
#else
/* Complicated code when profiling is enabled, but we don't care */

I am currently running sudo version 1.8.11p2, and it spawns the sleep either way, with or without the -b switch, so it seems the current code got more complicated.

I am looking for an answer which covers also why is this the default behaviour, and which advantanges it can bring us.

ssice
  • 964

2 Answers2

3

The reason for forking is documented in the Process model section of the man page. The relevant content is:

This extra process makes it possible to, for example, suspend and resume the command. Without it, the command would be in what POSIX terms an “orphaned process group” and it would not receive any job control signals. As a special case, if the policy plugin does not define a close function and no pty is required, sudo will execute the command directly instead of calling fork(2) first. The sudoers policy plugin will only define a close function when I/O logging is enabled, a pty is required, or the pam_session or pam_setcred options are enabled. Note that pam_session and pam_setcred are enabled by default on systems using PAM.

Gray
  • 273
BillThor
  • 11,345
  • 2
  • 28
  • 25
2

The PID space on Linux can be raised to 222 with a simple sysctl; that's really not a problem...

Most Linux distributions nowadays use PAM, and sudo is usually compiled with PAM support as well. Among other things it calls pam_open_session() before running your program, therefore it must also call pam_close_session() from within the same process as well, since your program won't know it needs to do that (and likely wouldn't be allowed to do that).

grawity
  • 501,077