00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <unistd.h>
00019 #include <errno.h>
00020
00021 #include "chroot.h"
00022 #include "open.h"
00023
00024
00025
00026
00027 int chroot_secure_chdir(const char *root, const char *dir)
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
00044 if (chroot_fd(new_root) == -1)
00045 return -1;
00046
00047
00048 if (chdir(dir) == -1)
00049 goto err;
00050
00051
00052 dirfd = open_read(".");
00053
00054 if (dirfd == -1)
00055 goto err;
00056
00057
00058 chroot_fd(orig_root);
00059
00060
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 }