Secure chroot wrappers


Detailed Description

The chroot system call changes the root directory of the current process. This directory will be used for pathnames beginning with /. The root directory is inherited by all children of the current process.

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)


Function Documentation

int chroot_fd ( int  fd  ) 

chroot(2) to the directory pointed to by a filedescriptor

Parameters:
[in] fd file descriptor refering to a directory (fchdir(2))
Returns:
0 on success, -1 on error with errno set
See also:
Secure chroot wrappers

fchdir(2)

Definition at line 22 of file chroot_fd.c.

Referenced by chroot_mkdirp(), and chroot_secure_chdir().

00023 {
00024         if (fchdir(fd) == -1)
00025                 return -1;
00026         
00027         return chroot(".");
00028 }

int chroot_mkdirp ( const char *  root,
const char *  dir,
mode_t  mode 
)

recursive mkdir(2) inside a secure chroot

Parameters:
[in] root new root path
[in] dir dir to be created in root
[in] mode file permissions
Returns:
0 on success, -1 on error with errno set
See also:
chroot_secure_chdir

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)

Parameters:
[in] root new root path
[in] dir dir to chdir(2) in root
Returns:
0 on success, -1 on error with errno set
See also:
Secure chroot wrappers

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 }


Generated on Sun Dec 3 17:46:16 2006 for lucid by  doxygen 1.5.1