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 22 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 28 of file chroot_mkdirp.c.
References chroot_fd(), mkdirp(), and open_read().
00029 { 00030 int orig_root, new_root; 00031 int errno_orig; 00032 00033 if ((orig_root = open_read("/")) == -1) 00034 return -1; 00035 00036 if (chdir(root) == -1) 00037 return -1; 00038 00039 if ((new_root = open_read(".")) == -1) 00040 return -1; 00041 00042 /* check cwdfd */ 00043 if (chroot_fd(new_root) == -1) 00044 return -1; 00045 00046 /* now create the dir in the chroot */ 00047 if (mkdirp(dir, mode) == -1) 00048 goto err; 00049 00050 /* break out of the chroot */ 00051 chroot_fd(orig_root); 00052 00053 return 0; 00054 00055 err: 00056 errno_orig = errno; 00057 chroot_fd(orig_root); 00058 errno = errno_orig; 00059 return -1; 00060 }
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 27 of file chroot_secure_chdir.c.
References chroot_fd(), and open_read().
00028 { 00029 int orig_root, new_root; 00030 00031 if ((orig_root = open_read("/")) == -1) 00032 return -1; 00033 00034 if (chdir(root) == -1) 00035 return -1; 00036 00037 if ((new_root = open_read(".")) == -1) 00038 return -1; 00039 00040 int dirfd; 00041 int errno_orig; 00042 00043 /* check cwdfd */ 00044 if (chroot_fd(new_root) == -1) 00045 return -1; 00046 00047 /* now go to dir in the chroot */ 00048 if (chdir(dir) == -1) 00049 goto err; 00050 00051 /* save a file descriptor of the target dir */ 00052 dirfd = open_read("."); 00053 00054 if (dirfd == -1) 00055 goto err; 00056 00057 /* break out of the chroot */ 00058 chroot_fd(orig_root); 00059 00060 /* now go to the saved target dir (but outside the chroot) */ 00061 if (fchdir(dirfd) == -1) 00062 goto err2; 00063 00064 close(dirfd); 00065 return 0; 00066 00067 err2: 00068 errno_orig = errno; 00069 close(dirfd); 00070 errno = errno_orig; 00071 err: 00072 errno_orig = errno; 00073 chroot_fd(orig_root); 00074 errno = errno_orig; 00075 return -1; 00076 }