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