Unshare --pid / bin / bash - fork cannot allocate memory

I am experimenting with linux namespaces. In particular, the pid namespace.

I thought I would do something with bash, but face this problem:

unshare -p /bin/bash
bash: fork: Cannot allocate memory

      

Running ls from there gave a kernel dump. The exit is only possible.

Why is he doing this?

+3


source to share


2 answers


The error is caused by the process PID 1 exiting a new namespace.

After bash starts, bash will spawn some new subprocesses to do something. If you run unshare without -f, bash will have the same pid as the current "unshare" process. The current "unshare" process calls unshare systemcall, creates a new pid namespace, but the current "unshare" process is not in the new pid namespace. This is the desired behavior of the linux kernel: process A creates a new namespace, process A itself will not be placed in the new namespace, only the subprocesses of process A will be placed in the new namespace. So when you run:

unshare -p / bin / bash

An opaque process will execute exec / bin / bash, and / bin / bash calls multiple subprocesses, the first bash subprocess will become PID 1 of the new namespace, and the subprocess will exit when it exits. So PID 1 of the new namespace comes out.



PID 1 process has a special function: it must become the parent process of all orphan processes. If the PID 1 process in the root namespace exits, the kernel will panic. If the PID 1 process in the secondary namespace terminates, the linux kernel will call disable_pid_allocation, which will clear the PIDNS_HASH_ADDING flag in that namespace. When the linux kernel creates a new process, the kernel will call the alloc_pid function to allocate the PID in the namespace, and if the PIDNS_HASH_ADDING flag is not set, the alloc_pid function will return a -ENOMEM error. This is why you got the message "Can not allocate memory".

You can solve this problem using the '-f' option:

unshare -fp / bin / bash

If you run unshare with the "-f" option, unshare will fork a new process after creating a new pid namespace. And start / bin / bash in a new process. The new process will be pid 1 of the new pid namespace. Then bash will also spawn some sub-processes to do some of the jobs. Since bash is itself pid 1 of the new pid namespace, its subprocesses can exit without any problem.

+3


source


This doesn't explain why this is happening, but it does show you how to properly start the shell in the new pid namespace:

Use a flag -f

to fork the shell from unshare

:

unshare -fp /bin/bash

      

You also need to pass a parameter --mount-proc

to make sure the shell gets PID 1 in the newly created namespace:



unshare -fp --mount-proc /bin/bash

      

Now run ps

:

# ps
   PID TTY          TIME CMD
 1 pts/1    00:00:00 bash
11 pts/1    00:00:00 ps

      

+1


source







All Articles