6

I am trying to run a python script in a chroot (specifically, the chroot is created with arch-chroot). The python script relies on os.getpid(), but this seems to be returning an incorrect PID within the chroot. If in python I do

import os
os.getpid()

I get a PID that is not listed in /proc/ in either the chroot or real root. Further, what I think is the correct PID is listed in /proc/ in both the chroot or real root.

The issue is not Python specific. If I run the following Bash script in the chroot

echo $$
ps -a
ls /proc

The PID is not listed by ps or in /proc.

What am I doing wrong? Is there a way to get the correct PID?

StrongBad
  • 5,261
  • 2
    I just added the python tag but that got me wondering whether it's python specific or not. Does running a bash script with echo $$ work as expected? – terdon Oct 13 '15 at 22:38
  • 1
    @terdon It does not work as expected in bash. Thanks for the hint. I added a bash example and removed the python tag. – StrongBad Oct 13 '15 at 22:46

1 Answers1

3

arch-chroot does more than create a chroot: it also creates a PID namespace.

unshare --fork --pid chroot "$chrootdir" "$@"

As the name suggests, a PID namespace has its own set of process IDs, distinct from the rest of the system. This means that processes inside the namespace can't see the processes outside the namespace (and in particular can't kill or trace them), and processes outside the namespace¹ see them with different PIDs.

For more information on namespaces, read my summary here and the LWN series by Michael Kerrisk, especially Part 3: PID namespaces and Part 4: more on PID namespaces, as well as the earlier article by Pavel Emelyanov and Kir Kolyshkin. how to find out namespace of a particular process? and Reliable way to jail child processes using `nsenter:` may also be of interest.

If you want to do things to a process running in a namespace from outside, you can use the nsenter utility; see Is there a command to switch to into an existing namespace?. You can also use the nsenter Python package. Or you can arrange to do these operations from inside the namespace (this may or may not be a good solution depending on your architecture and security requirements); it's easier to access something in a chroot from the outside (just prefix the right directory path) than in a PID namespace.

Note that PID namespaces and chroots are independent. If you chroot to the same directory independently, that doesn't let you reach the same PID namespace. If you run arch-chroot twice on the same directory, you end up working in the same directory, but in two different PID namespaces.

¹ More precisely, in an ancestor namespace. (Namespaces have a tree structure where children are confined within the parent.)