6

I wrote a program that captures the packets from the network interface. As it listens the network adapter, I need to run it with sudo. The question is, why when I run it, does it add two processes to the processes list?

Note : lwdpi is my program

Before execution:

ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ ps ax | grep lwdpi
 4665 pts/21   S+     0:00 grep --color=auto lwdpi
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ 

Execution:
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ sudo ./lwdpi -i enp5s0
2016:10:26 11:07:29 ::   192.168.1.25   9918  -->     239.1.99.222   9918    UDP
2016:10:26 11:07:29 ::  192.168.1.111   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::  192.168.1.153   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::  192.168.1.154   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::   192.168.1.88   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:30 ::   192.168.1.60   5353  -->      224.0.0.251   5353    UDP
2016:10:26 11:07:37 ::  192.168.1.131  17500  -->  255.255.255.255  17500    UDP
2016:10:26 11:07:37 ::  192.168.1.131  17500  -->    192.168.1.255  17500    UDP
2016:10:26 11:07:37 ::  192.168.1.169   5546  -->     192.168.1.38     53    UDP
2016:10:26 11:07:37 ::  192.168.1.169  30955  -->     192.168.1.38     53    UDP
2016:10:26 11:07:38 ::  192.168.1.110  17500  -->  255.255.255.255  17500    UDP
2016:10:26 11:07:38 ::  192.168.1.110  17500  -->    192.168.1.255  17500    UDP
2016:10:26 11:07:42 ::  192.168.1.169  57189  -->     192.168.1.38     53    UDP
2016:10:26 11:07:42 ::  192.168.1.169  26072  -->     192.168.1.38     53    UDP
2016:10:26 11:07:42 ::  192.168.1.169  41674  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169  41676  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169   7190  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  30029  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  41678  -->   199.30.228.113     80    TCP
2016:10:26 11:07:43 ::  192.168.1.169  64975  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  12625  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  29973  -->     192.168.1.38     53    UDP
2016:10:26 11:07:43 ::  192.168.1.169  53300  -->     216.58.211.4    443    TCP
2016:10:26 11:07:43 ::  192.168.1.169  41682  -->   199.30.228.113     80    TCP
.
.
.

Processes list while execution:

ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ ps ax | grep lwdpi
 4685 pts/22   S+     0:00 sudo ./lwdpi -i enp5s0
 4686 pts/22   S+     0:00 ./lwdpi -i enp5s0
 4691 pts/21   S+     0:00 grep --color=auto lwdpi
ghasemi@ghasemi-MS-7693:~/Desktop/lwdpi_cpp$ 

As you see above, after execution, processes with PID = 4685 and PID = 4686 added to process list. Why? I didn't called my program inside it!

  • 1
    and when you do sudo -i insert your admin password and then do ./lwdpi -i enp5s0 you only get 1? ;-) – Rinzwind Oct 26 '16 at 7:50
  • Yes! In cases I use sudo -i and then run the program, only one process adds to the processes list. but why? – Abraham Oct 26 '16 at 7:57
  • 1
    so you get what I meant there? "sudo" is 1 process, your command the 2nd ;-) solution: dont use sudo. Use sudo -i to get a # then use your command. – Rinzwind Oct 26 '16 at 8:02
  • Since sudo is also an executable, you're running two already. – Dmitry Grigoryev Oct 26 '16 at 10:27
10

When you do:

sudo ./lwdpi -i enp5s0
  • sudo is the parent process, it fork(2)s a child, which then do execve(2) with ./lwdpi as the executable name

  • so lwdpi is sudo's child process

This results in two processes as you can see, one is sudo and another is lwdpi.

The best way to see the details is to check the PPID (parent process ID) too:

ps -eo pid,ppid,args | grep '[l]wdpi'

you'll see that lwdpi's parent is sudo itself.


Here is sudo's process model, from man sudo:

When sudo runs a command, it calls fork(2), sets up the execution environment as described above, and calls the execve system call in the child process. The main sudo process waits until the command has completed, then passes the command's exit status to the security policy's close function and exits.

If an I/O logging plugin is configured or if the security policy explicitly requests it, a new pseudo-terminal (“pty”) is created and a second sudo process is used to relay job control signals between the user's existing pty and the new pty the command is being run in. 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.

  • 2
    A more detailed explanation of what sudo is doing with processes is in its man page: sudo.ws/man/sudo.man.html#Process_model . The reason why the sudo process keeps running until the command has finished is that sudo has to do additional work after the command finishes. – pts Oct 26 '16 at 10:21
6

This happens when you start any process with sudo One process is the sudo program and the other is the program launched with sudo, which is a child process of the first. The sudo program will exit only when the process it is running for (its child) exits. Here's an extract from my pstree when running sudo apt update

    ├─mate-terminal─┬
                    ├─bash───sudo───apt
               child of bash--^      ^--child of sudo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.