chroot/chroot_secure_chdir.c

Go to the documentation of this file.
00001 // Copyright (C) 2006-2007 Benedikt Böhm <hollow@gentoo.org>
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00016 
00017 #include <unistd.h>
00018 #include <errno.h>
00019 
00020 #include "chroot.h"
00021 #include "open.h"
00022 
00023 /* go to <dir> in <root> as root
00024 ** going into the chroot before doing chdir(dir) prevents symlink attacks
00025 ** and hence is safer */
00026 int chroot_secure_chdir(const char *root, const char *dir)
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:26 2007 for lucid by  doxygen 1.5.2