How can I get the old root back after chroot(2) given some open file descriptor to it?
In the below program, I first open a file descriptor to /, and then chroot(2) to . and chdir(2) to /.
However, if I then chdir(2) to the old root of fd, Python complains that it cannot print the current working directory getcwd(), since it doesn't exist.
Why can't I change the current working directory to the old root and print it?
This is why we have "pivot_root()" and "chroot()", which can both be used to do what you want to do. You mount the new root somewhere else, and then you chroot (or pivot-root) to it. And THEN you do 'chdir("/")' to move the cwd into the new root too (and only at that point have you "lost" the old root - although you can actually get it back if you have some file descriptor open to it).
https://yarchive.net/comp/linux/pivot_root.html
Program:
import os print(f'cwd: {os.getcwd()}') fd = os.open('/', os.R_OK, os.X_OK) os.chroot('.') os.chdir('/') print(f'cwd: {os.getcwd()}') os.chdir(fd) print(f'cwd: {os.getcwd()}') Output:
$ sudo python3 chdir_fd.py cwd: /home/admin/projects/linux-pwn cwd: / Traceback (most recent call last): File "chdir_fd.py", line 14, in <module> FileNotFoundError: [Errno 2] No such file or directory