X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsecure-mount.c;h=53863e3af886e300d57c6a8528733284e037efa1;hb=HEAD;hp=3ca425719565dcad8ac9a2fd572c30e7673cb375;hpb=a8dc4bb25bee0d14ff8f8b7f88e35db86d263190;p=util-vserver.git diff --git a/src/secure-mount.c b/src/secure-mount.c index 3ca4257..53863e3 100644 --- a/src/secure-mount.c +++ b/src/secure-mount.c @@ -63,9 +63,10 @@ typedef enum { rfsYES, rfsNO, rfsONLY } RootFsOption; struct MountInfo { - char const * src; - char const * dst; - char const * type; + char * src; + char * dst; + char * name; + char * type; unsigned long flag; unsigned long xflag; unsigned long mask; @@ -81,6 +82,7 @@ struct Options { bool mount_all; RootFsOption rootfs; + char cur_dir_path[PATH_MAX]; int cur_dir_fd; int cur_rootdir_fd; }; @@ -95,6 +97,8 @@ struct Options { #define OPTION_ROOTFS 1031 #define XFLAG_NOAUTO 0x01 +#define XFLAG_FILE 0x02 +#define XFLAG_NOMTAB 0x04 static struct option const CMDLINE_OPTIONS[] = { @@ -170,6 +174,7 @@ static struct FstabOption { { "private", MS_PRIVATE, MS_PRIVATE, 0, false }, { "slave", MS_SLAVE, MS_SLAVE, 0, false }, { "shared", MS_SHARED, MS_SHARED, 0, false }, + { "nomtab", 0, 0, XFLAG_NOMTAB, false }, }; int wrapper_exit_code = 1; @@ -304,6 +309,8 @@ updateMtab(struct MountInfo const *mnt, struct Options const *opt) if (writeStrX(fd, mnt->src)==-1 || writeStrX(fd, " ")==-1 || writeStrX(fd, mnt->dst)==-1 || + writeStrX(fd, mnt->xflag & XFLAG_FILE ? "/" : "")==-1 || + writeStrX(fd, mnt->xflag & XFLAG_FILE ? mnt->name : "")==-1 || writeStrX(fd, " ")==-1 || writeStrX(fd, getType(mnt))==-1 || writeStrX(fd, " ")==-1 || @@ -358,7 +365,7 @@ callExternalMount(struct MountInfo const *mnt) } argv[idx++] = mnt->src; - argv[idx++] = "."; + argv[idx++] = mnt->name; argv[idx] = 0; pid = fork(); @@ -441,7 +448,7 @@ canHandleInternal(struct MountInfo const *mnt) } static bool -mountSingle(struct MountInfo const *mnt, struct Options const *opt) +mountSingle(struct MountInfo const *mnt, struct Options *opt) { assert(mnt->dst!=0); @@ -449,18 +456,29 @@ mountSingle(struct MountInfo const *mnt, struct Options const *opt) return false; if (canHandleInternal(mnt)) { - if (mount(mnt->src, ".", + if (mount(mnt->src, mnt->name, mnt->type ? mnt->type : "", mnt->flag, mnt->data_parsed)==-1) { perror("secure-mount: mount()"); return false; } - if ((mnt->flag & MS_BIND) && - (mnt->flag & ~(MS_BIND|MS_REC))) { + if (strcmp(mnt->dst, "/") == 0) { + /* XXX: Hack */ + if (chdir(opt->cur_dir_path) == -1) { + perror("secure-mount: chdir(.)"); + return false; + } + close(opt->cur_dir_fd); + opt->cur_dir_fd = Eopen(".", O_RDONLY|O_DIRECTORY, 0); + Efcntl(opt->cur_dir_fd, F_SETFD, FD_CLOEXEC); + } + if (!vc_isSupported(vcFEATURE_BME) && + (mnt->flag & MS_BIND) && + (mnt->mask & ~(MS_BIND|MS_REC))) { /* This is needed to put us in the new mountpoint */ if (!secureChdir(mnt->dst, opt)) return false; - if (mount(mnt->src, ".", + if (mount(mnt->src, mnt->name, mnt->type ? mnt->type : "", (mnt->flag | MS_REMOUNT), NULL) == -1 && errno != EBUSY) { /* Returned on older kernels */ @@ -472,7 +490,7 @@ mountSingle(struct MountInfo const *mnt, struct Options const *opt) else if (!callExternalMount(mnt)) return false; - if (!opt->ignore_mtab && + if (!opt->ignore_mtab && (mnt->xflag & XFLAG_NOMTAB)==0 && updateMtab(mnt, opt)==-1) { WRITE_MSG(2, "Failed to update mtab-file\n"); // no error @@ -559,6 +577,7 @@ static enum {prDOIT, prFAIL, prIGNORE} info->flag = MS_NODEV; info->mask = 0; info->xflag = 0; + info->name = "."; if (strcmp(info->type, "swap") ==0) return prIGNORE; else if (strcmp(info->type, "none") ==0) info->type = 0; @@ -589,9 +608,20 @@ showFstabPosition(int fd, char const *fname, size_t line_nr, size_t col_nr) Vwrite(fd, buf, len); } +static void +adjustFileMount(struct MountInfo *mnt) +{ + char *buf = strrchr(mnt->dst, '/'); + + if (buf) + *buf++ = 0; + + mnt->name = buf; + mnt->xflag |= XFLAG_FILE; +} static bool -mountFstab(struct Options const *opt) +mountFstab(struct Options *opt) { bool res = false; int fd; @@ -641,9 +671,13 @@ mountFstab(struct Options const *opt) Echdir("/"); if (( is_rootfs && opt->rootfs==rfsNO) || (!is_rootfs && opt->rootfs==rfsONLY)) { /* ignore the entry */ } - else if (!mountSingle(&mnt, opt)) { - showFstabPosition(2, opt->fstab, line_nr, 1); - WRITE_MSG(2, ": failed to mount fstab-entry\n"); + else { + if (utilvserver_isFile(mnt.dst, 0)) + adjustFileMount(&mnt); + if (!mountSingle(&mnt, opt)) { + showFstabPosition(2, opt->fstab, line_nr, 1); + WRITE_MSG(2, ": failed to mount fstab-entry\n"); + } } break; } @@ -667,6 +701,11 @@ initFDs(struct Options *opt) Efcntl(opt->cur_dir_fd, F_SETFD, FD_CLOEXEC); Efcntl(opt->cur_rootdir_fd, F_SETFD, FD_CLOEXEC); + + if (getcwd(opt->cur_dir_path, sizeof(opt->cur_dir_path)) == NULL) { + perror("secure-mount: getcwd()"); + exit(wrapper_exit_code); + } } static RootFsOption @@ -688,6 +727,7 @@ int main(int argc, char *argv[]) struct MountInfo mnt = { .src = 0, .dst = 0, + .name = ".", .type = 0, .flag = MS_NODEV, .xflag = 0, @@ -765,7 +805,10 @@ int main(int argc, char *argv[]) mnt.src = argv[optind++]; mnt.dst = argv[optind++]; - if (!mountSingle(&mnt, &opt)) return EXIT_FAILURE; + if (utilvserver_isFile(mnt.dst, 0)) + adjustFileMount(&mnt); + if (!mountSingle(&mnt, &opt)) + return EXIT_FAILURE; return EXIT_SUCCESS; }