...
Code Block | ||
---|---|---|
| ||
/* * Make sure that the ~/chroot/jail directory exists within * the current working directory. Also assign appropriate * permissions to the directory to restrict access. Close * all file system descriptors to outside resources lest * they escape the jail. */ if (setuid(0) == -1) { /* Handle Error */ } if (chroot("~/chroot/jail") == -1) { /* Handle Error */ } if (chdir("/") == -1) { /* Handle Error */ } /* Drop privileges permanently */ if (setgid(getgid()) == -1) { /* Handle Error */ } if (setuid(getuid()) == -1) { /* Handle Error */ } /* Perform unprivileged operations */ FILE* fp = fopen(argv[1], "w"); |
The chdir()
system call An alternative sequence is to call chdir("chroot/jail")
first and then chroot(".")
. However, calling chdir("/some/path")
then chroot("/some/path")
should be avoided as this sequence may be susceptible to a race condition if called before chroot()
. This is because an attacker with sufficient privileges can delete the 'jail' directory so that the chdir()
operation fails and then recreate it so that chroot()
succeedsarrange for /some/path
to refer to different directories in the two system calls. Consequently, the program will not start in its sandboxed environment (~/chroot/jail) and will not have its current working directory set to ~/chroot/jail. One mitigation strategy is to incorporate error checking to detect if chdir()
failed. A more fool proof method is to use chdir()
after chroot()
so that it the new root directory. Using either chdir("/")
after chroot()
or chroot(".")
after chdir()
guarantees that the current working directory will be set to the chroot'ed directory, that is same directory as the new root.
Risk Assessment
...