X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fsecure-mount.c;h=57fe87424f61171ac6786c9f509736b17cc7b80e;hb=569b1bfe1e5954fa083532dc37d2fe7418ec2d4a;hp=c3a2b48bb8e0573f3512c72910dee6fb9991b686;hpb=9c78378bebc1a9f3d400f422df8ede9efea57dea;p=util-vserver.git diff --git a/src/secure-mount.c b/src/secure-mount.c index c3a2b48..57fe874 100644 --- a/src/secure-mount.c +++ b/src/secure-mount.c @@ -52,6 +52,7 @@ #include #include #include +#include #define ENSC_WRAPPERS_FCNTL 1 #define ENSC_WRAPPERS_UNISTD 1 @@ -69,6 +70,7 @@ struct MountInfo { unsigned long xflag; unsigned long mask; char * data; + char * data_parsed; }; struct Options { @@ -120,7 +122,7 @@ static struct FstabOption { unsigned long const xflag; bool const is_dflt; } const FSTAB_OPTIONS[] = { - { "defaults", 0, (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC| + { "defaults", MS_NODEV, (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC| MS_SYNCHRONOUS), 0, false }, { "rbind", MS_BIND|MS_REC, MS_BIND|MS_REC, 0, false }, { "bind", MS_BIND, MS_BIND, 0, false }, @@ -151,6 +153,11 @@ static struct FstabOption { { "noauto", 0, 0, XFLAG_NOAUTO, false }, { "user", 0, 0, 0, false }, { "nouser", 0, 0, 0, false }, + { "rec", MS_REC, MS_REC, 0, false }, + { "unbindable", MS_UNBINDABLE, MS_UNBINDABLE, 0, false }, + { "private", MS_PRIVATE, MS_PRIVATE, 0, false }, + { "slave", MS_SLAVE, MS_SLAVE, 0, false }, + { "shared", MS_SHARED, MS_SHARED, 0, false }, }; int wrapper_exit_code = 1; @@ -277,8 +284,8 @@ updateMtab(struct MountInfo const *mnt, struct Options const *opt) goto err0; } - if (flock(fd, LOCK_EX)==-1) { - perror("secure-mount: flock()"); + if (lockf(fd, F_LOCK, 0)==-1) { + perror("secure-mount: lockf()"); goto err1; } @@ -409,9 +416,9 @@ canHandleInternal(struct MountInfo const *mnt) }; char const ** i; - if (mnt!=0) return false; - else if ((mnt->flag & (MS_BIND|MS_MOVE))!=0) return true; - else if (mnt->type==0) return false; + if (!mnt) return false; + else if ((mnt->flag & (MS_BIND|MS_MOVE))) return true; + else if (mnt->type==0) return false; for (i=FS+0; *i!=0; ++i) if (strcmp(mnt->type, *i)==0) return true; @@ -428,15 +435,26 @@ mountSingle(struct MountInfo const *mnt, struct Options const *opt) return false; if (canHandleInternal(mnt)) { - unsigned long flag = mnt->flag; - if ((flag & MS_NODEV)!=0) flag |= MS_NODEV; - if (mount(mnt->src, ".", mnt->type ? mnt->type : "", - flag, mnt->data)==-1) { + mnt->flag, mnt->data_parsed)==-1) { perror("secure-mount: mount()"); return false; } + if ((mnt->flag & MS_BIND) && + (mnt->flag & ~(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, ".", + mnt->type ? mnt->type : "", + ((mnt->flag & ~(MS_BIND|MS_REC)) | + MS_REMOUNT), NULL) == -1 && + errno != EBUSY) { /* Returned on older kernels */ + perror("secure-mount: mount()"); + return false; + } + } } else if (!callExternalMount(mnt)) return false; @@ -464,6 +482,8 @@ static bool transformOptionList(struct MountInfo *info, size_t UNUSED *col) { char const * ptr = info->data; + char * data = malloc(strlen(info->data)); + char * dst = data; do { char const * pos = strchr(ptr, ','); @@ -478,6 +498,13 @@ transformOptionList(struct MountInfo *info, size_t UNUSED *col) info->mask |= opt->mask; info->xflag |= opt->xflag; } + else { + if (dst != data) + *(dst++) = ','; + strncpy(dst, ptr, pos-ptr); + dst += pos - ptr; + *dst = '\0'; + } if (*pos!='\0') ptr = pos+1; @@ -486,6 +513,7 @@ transformOptionList(struct MountInfo *info, size_t UNUSED *col) } while (*ptr!='\0'); + info->data_parsed = data; return true; } @@ -648,7 +676,7 @@ int main(int argc, char *argv[]) .src = 0, .dst = 0, .type = 0, - .flag = 0, + .flag = MS_NODEV, .xflag = 0, .data = 0, }; @@ -688,7 +716,7 @@ int main(int argc, char *argv[]) default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); - WRITE_MSG(2, " --help\" for more information.\n"); + WRITE_MSG(2, " --help' for more information.\n"); return EXIT_FAILURE; break; }