The chroot family of functions provide wrappers for other library functions to happen in a chroot while the caller still remains in the old root after the functions have returned.
One can break out of the chroot in many ways due to the nature of the chroot system call:
The main usage of these functions is to get a file descriptor, safe against symlink attacks, reffering to a directory inside a new root.
Functions | |
int | chroot_fd (int fd) |
chroot(2) to the directory pointed to by a filedescriptor | |
int | chroot_mkdirp (const char *root, const char *dir, mode_t mode) |
recursive mkdir(2) inside a secure chroot | |
int | chroot_secure_chdir (const char *root, const char *dir) |
symlink-attack safe chdir(2) in chroot(2) |
int chroot_fd | ( | int | fd | ) |
chroot(2) to the directory pointed to by a filedescriptor
[in] | fd | file descriptor refering to a directory (fchdir(2)) |
fchdir(2)
Definition at line 21 of file chroot_fd.c.
Referenced by chroot_mkdirp(), and chroot_secure_chdir().
int chroot_mkdirp | ( | const char * | root, | |
const char * | dir, | |||
mode_t | mode | |||
) |
recursive mkdir(2) inside a secure chroot
[in] | root | new root path |
[in] | dir | dir to be created in root |
[in] | mode | file permissions |
mkdir(2)
Definition at line 27 of file chroot_mkdirp.c.
References chroot_fd(), mkdirp(), and open_read().
00028 { 00029 int orig_root, new_root; 00030 int errno_orig; 00031 00032 if ((orig_root = open_read("/")) == -1) 00033 return -1; 00034 00035 if (chdir(root) == -1) 00036 return -1; 00037 00038 if ((new_root = open_read(".")) == -1) 00039 return -1; 00040 00041 /* check cwdfd */ 00042 if (chroot_fd(new_root) == -1) 00043 return -1; 00044 00045 /* now create the dir in the chroot */ 00046 if (mkdirp(dir, mode) == -1) 00047 goto err; 00048 00049 /* break out of the chroot */ 00050 chroot_fd(orig_root); 00051 00052 return 0; 00053 00054 err: 00055 errno_orig = errno; 00056 chroot_fd(orig_root); 00057 errno = errno_orig; 00058 return -1; 00059 }
int chroot_secure_chdir | ( | const char * | root, | |
const char * | dir | |||
) |
symlink-attack safe chdir(2) in chroot(2)
[in] | root | new root path |
[in] | dir | dir to chdir(2) in root |
chdir(2)
Definition at line 26 of file chroot_secure_chdir.c.
References chroot_fd(), and open_read().
00027 { 00028 int orig_root, new_root; 00029 00030 if ((orig_root = open_read("/")) == -1) 00031 return -1; 00032 00033 if (chdir(root) == -1) 00034 return -1; 00035 00036 if ((new_root = open_read(".")) == -1) 00037 return -1; 00038 00039 int dirfd; 00040 int errno_orig; 00041 00042 /* check cwdfd */ 00043 if (chroot_fd(new_root) == -1) 00044 return -1; 00045 00046 /* now go to dir in the chroot */ 00047 if (chdir(dir) == -1) 00048 goto err; 00049 00050 /* save a file descriptor of the target dir */ 00051 dirfd = open_read("."); 00052 00053 if (dirfd == -1) 00054 goto err; 00055 00056 /* break out of the chroot */ 00057 chroot_fd(orig_root); 00058 00059 /* now go to the saved target dir (but outside the chroot) */ 00060 if (fchdir(dirfd) == -1) 00061 goto err2; 00062 00063 close(dirfd); 00064 return 0; 00065 00066 err2: 00067 errno_orig = errno; 00068 close(dirfd); 00069 errno = errno_orig; 00070 err: 00071 errno_orig = errno; 00072 chroot_fd(orig_root); 00073 errno = errno_orig; 00074 return -1; 00075 }