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 21 of file chroot_fd.c.

Referenced by chroot_mkdirp(), and chroot_secure_chdir().

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

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 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)

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 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 }


Generated on Tue Jun 19 20:38:45 2007 for lucid by  doxygen 1.5.2