X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fsecure-mount.c;h=08d83d4650f63399c7a4ff837e87f59ae75f1d5d;hb=5f3e8dc9d268523560cae12fdb8e93663a3ead72;hp=7577dae9cc6d79f607e7f61f62e6f115abf23177;hpb=32bda4cf6d0094c95f4720cdc21fa811057915f4;p=util-vserver.git diff --git a/util-vserver/src/secure-mount.c b/util-vserver/src/secure-mount.c index 7577dae..08d83d4 100644 --- a/util-vserver/src/secure-mount.c +++ b/util-vserver/src/secure-mount.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -57,12 +58,15 @@ #define MNTPOINT "/etc" +typedef enum { rfsYES, rfsNO, rfsONLY } RootFsOption; + struct MountInfo { char const * src; char const * dst; char const * type; unsigned long flag; unsigned long xflag; + unsigned long mask; char * data; }; @@ -72,6 +76,7 @@ struct Options { bool do_chroot; bool ignore_mtab; bool mount_all; + RootFsOption rootfs; int cur_dir_fd; int cur_rootdir_fd; @@ -84,6 +89,7 @@ struct Options { #define OPTION_CHROOT 1028 #define OPTION_SECURE 1029 #define OPTION_RBIND 1030 +#define OPTION_ROOTFS 1031 #define XFLAG_NOAUTO 0x01 @@ -95,6 +101,7 @@ CMDLINE_OPTIONS[] = { { "move", no_argument, 0, OPTION_MOVE }, { "mtab", required_argument, 0, OPTION_MTAB }, { "fstab", required_argument, 0, OPTION_FSTAB }, + { "rootfs", required_argument, 0, OPTION_ROOTFS }, { "chroot", no_argument, 0, OPTION_CHROOT }, { "secure", no_argument, 0, OPTION_SECURE }, { "rbind", no_argument, 0, OPTION_RBIND }, @@ -155,9 +162,9 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " [--help] [--version] [--bind] [--move] [--rbind] [-t ] [-n]\n" - " [--mtab ] [--fstab ] [--chroot] \n" - " -a|([-o ] [--] )\n\n" + " [--help] [--version] [--bind] [--move] [--rbind] [-t ] [--chroot]\n" + " [--mtab ] [--fstab ] [--rootfs yes|no|only]\n" + " [-n] -a|([-o ] [--] )\n\n" "Executes mount-operations under the current directory: it assumes sources in\n" "the current root-dir while destinations are expected in the chroot environment.\n\n" "For non-trivial mount-operations it uses the external 'mount' program which\n" @@ -176,6 +183,11 @@ showHelp(int fd, char const *cmd, int res) " --fstab ... use as an alternative fstab file;\n" " this option has an effect only with the '-a'\n" " option [default: /etc/fstab]\n" + " --rootfs yes|no|only ... specifies how to handle an entry for a rootfs\n" + " ('/') when processing an fstab file. 'yes' will\n" + " mount it among the other entries, 'only' will\n" + " mount only the rootfs entry, and 'no' will ignore\n" + " it and mount only the other entries [default: yes]\n" " -a ... mount everything listed in the fstab-file\n\n" " ... the source-filesystem; this path is absolute\n" " to the current root-filesystem. Only valid\n" @@ -305,11 +317,20 @@ callExternalMount(struct MountInfo const *mnt) if (mnt->flag & MS_BIND) argv[idx++] = "--bind"; else if (mnt->flag & MS_MOVE) argv[idx++] = "--move"; - if (mnt->data && + argv[idx++] = "-o"; + if (mnt->data && *mnt->data && strcmp(mnt->data, "defaults")!=0) { - argv[idx++] = "-o"; - argv[idx++] = mnt->data; + if (mnt->mask & MS_NODEV) + argv[idx++] = mnt->data; + else { + char * tmp = alloca(strlen(mnt->data) + sizeof("nodev,")); + strcpy(tmp, "nodev,"); + strcat(tmp, mnt->data); + argv[idx++] = tmp; + } } + else + argv[idx++] = "nodev"; if (mnt->type) { argv[idx++] = "-t"; @@ -385,9 +406,12 @@ mountSingle(struct MountInfo const *mnt, struct Options const *opt) return false; if (mnt->flag & (MS_BIND|MS_MOVE)) { + unsigned long flag = mnt->flag; + if ((flag & MS_NODEV)==0) flag |= MS_NODEV; + if (mount(mnt->src, ".", mnt->type ? mnt->type : "", - mnt->flag, mnt->data)==-1) { + flag, mnt->data)==-1) { perror("secure-mount: mount()"); return false; } @@ -429,6 +453,7 @@ transformOptionList(struct MountInfo *info, size_t UNUSED *col) if (opt!=0) { info->flag &= ~opt->mask; info->flag |= opt->flag; + info->mask |= opt->mask; info->xflag |= opt->xflag; } @@ -468,11 +493,14 @@ static enum {prDOIT, prFAIL, prIGNORE} info->data = buf; MOVE_TO_NEXT_FIELD(buf, true); - if (strcmp(info->type, "swap")==0) return prIGNORE; - if (strcmp(info->type, "none")==0) info->type = 0; + info->flag = MS_NODEV; + info->mask = 0; + info->xflag = 0; + + if (strcmp(info->type, "swap") ==0) return prIGNORE; + else if (strcmp(info->type, "none") ==0) info->type = 0; + else if (strcmp(info->type, "devpts")==0) info->mask |= MS_NODEV; - info->flag = 0; - info->xflag = 0; if (col) *col = err_col; if (!transformOptionList(info,col)) return prFAIL; if (info->xflag & XFLAG_NOAUTO) return prIGNORE; @@ -542,13 +570,17 @@ mountFstab(struct Options const *opt) goto err1; case prIGNORE : break; - case prDOIT : + case prDOIT : { + bool is_rootfs = (strcmp(mnt.dst, "/")==0); chdir("/"); - if (!mountSingle(&mnt, opt)) { + 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"); } break; + } default : assert(false); } @@ -571,6 +603,20 @@ initFDs(struct Options *opt) Efcntl(opt->cur_rootdir_fd, F_SETFD, FD_CLOEXEC); } +static RootFsOption +parseRootFS(char const *str) +{ + if (strcasecmp(str, "yes")==0) return rfsYES; + else if (strcasecmp(str, "no")==0) return rfsNO; + else if (strcasecmp(str, "only")==0) return rfsONLY; + else { + WRITE_MSG(2, "secure-mount: invalid option for '--rootfs': '"); + WRITE_STR(2, str); + WRITE_MSG(2, "'\n"); + exit(wrapper_exit_code); + } +} + int main(int argc, char *argv[]) { struct MountInfo mnt = { @@ -589,7 +635,8 @@ int main(int argc, char *argv[]) .ignore_mtab = false, .mount_all = false, .cur_dir_fd = -1, - .cur_rootdir_fd = -1 + .cur_rootdir_fd = -1, + .rootfs = rfsYES }; while (1) { @@ -609,6 +656,7 @@ int main(int argc, char *argv[]) case OPTION_MTAB : opt.mtab = optarg; break; case OPTION_FSTAB : opt.fstab = optarg; break; case OPTION_CHROOT: opt.do_chroot = true; break; + case OPTION_ROOTFS: opt.rootfs = parseRootFS(optarg); break; case OPTION_SECURE: WRITE_MSG(2, "secure-mount: The '--secure' option is deprecated...\n"); break;