From cddd2eaa27c0c35b1a3bfbe7f76a1c7c1ea46517 Mon Sep 17 00:00:00 2001 From: Vaclav Dolezal Date: Wed, 11 Apr 2018 15:52:52 +0200 Subject: libmount: switch namespace when appropriate Signed-off-by: Vaclav Dolezal --- libmount/src/context_mount.c | 54 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'libmount/src/context_mount.c') diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 572395811..bc3c993bc 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -184,6 +184,7 @@ static int is_option(const char *name, size_t namesz, static int fix_optstr(struct libmnt_context *cxt) { int rc = 0; + struct libmnt_ns *ns_old; char *next; char *name, *val; size_t namesz, valsz; @@ -342,9 +343,18 @@ static int fix_optstr(struct libmnt_context *cxt) goto done; } - if (!rc && cxt->restricted && (cxt->user_mountflags & MNT_MS_USER)) + + if (!rc && cxt->restricted && (cxt->user_mountflags & MNT_MS_USER)) { + ns_old = mnt_context_switch_origin_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; + rc = mnt_optstr_fix_user(&fs->user_optstr); + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; + } + /* refresh merged optstr */ free(fs->optstr); fs->optstr = NULL; @@ -629,6 +639,9 @@ static int exec_helper(struct libmnt_context *cxt) if (setuid(getuid()) < 0) _exit(EXIT_FAILURE); + if (!mnt_context_switch_origin_ns(cxt)) + _exit(EXIT_FAILURE); + type = mnt_fs_get_fstype(cxt->fs); args[i++] = cxt->helper; /* 1 */ @@ -887,6 +900,7 @@ static int do_mount_by_pattern(struct libmnt_context *cxt, const char *pattern) int neg = pattern && strncmp(pattern, "no", 2) == 0; int rc = -EINVAL; char **filesystems, **fp; + struct libmnt_ns *ns_old; assert(cxt); assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED)); @@ -904,7 +918,12 @@ static int do_mount_by_pattern(struct libmnt_context *cxt, const char *pattern) /* * Apply pattern to /etc/filesystems and /proc/filesystems */ + ns_old = mnt_context_switch_origin_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; rc = mnt_get_filesystems(&filesystems, neg ? pattern : NULL); + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; if (rc) return rc; @@ -934,6 +953,7 @@ static int do_mount_by_pattern(struct libmnt_context *cxt, const char *pattern) int mnt_context_prepare_mount(struct libmnt_context *cxt) { int rc = -EINVAL; + struct libmnt_ns *ns_old; if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs)) return -EINVAL; @@ -947,6 +967,10 @@ int mnt_context_prepare_mount(struct libmnt_context *cxt) cxt->action = MNT_ACT_MOUNT; + ns_old = mnt_context_switch_target_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; + DBG(CXT, ul_debugobj(cxt, "mount: preparing")); rc = mnt_context_apply_fstab(cxt); @@ -966,9 +990,14 @@ int mnt_context_prepare_mount(struct libmnt_context *cxt) rc = mnt_context_prepare_helper(cxt, "mount", NULL); if (rc) { DBG(CXT, ul_debugobj(cxt, "mount: preparing failed")); - return rc; + goto end; } cxt->flags |= MNT_FL_PREPARED; + +end: + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; + return rc; } @@ -999,6 +1028,7 @@ int mnt_context_do_mount(struct libmnt_context *cxt) { const char *type; int res; + struct libmnt_ns *ns_old; assert(cxt); assert(cxt->fs); @@ -1013,6 +1043,10 @@ int mnt_context_do_mount(struct libmnt_context *cxt) if (!(cxt->flags & MNT_FL_MOUNTDATA)) cxt->mountdata = (char *) mnt_fs_get_fs_options(cxt->fs); + ns_old = mnt_context_switch_target_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; + type = mnt_fs_get_fstype(cxt->fs); if (type) { if (strchr(type, ',')) @@ -1064,6 +1098,8 @@ int mnt_context_do_mount(struct libmnt_context *cxt) } } #endif + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; return res; } @@ -1148,12 +1184,17 @@ int mnt_context_finalize_mount(struct libmnt_context *cxt) int mnt_context_mount(struct libmnt_context *cxt) { int rc; + struct libmnt_ns *ns_old; assert(cxt); assert(cxt->fs); assert(cxt->helper_exec_status == 1); assert(cxt->syscall_status == 1); + ns_old = mnt_context_switch_target_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; + again: rc = mnt_context_prepare_mount(cxt); if (!rc) @@ -1188,6 +1229,8 @@ again: goto again; } } + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; return rc; } @@ -1344,6 +1387,11 @@ static int is_shared_tree(struct libmnt_context *cxt, const char *dir) unsigned long mflags = 0; char *mnt = NULL, *p; int rc = 0; + struct libmnt_ns *ns_old; + + ns_old = mnt_context_switch_target_ns(cxt); + if (!ns_old) + return -MNT_ERR_NAMESPACE; if (!dir) return 0; @@ -1365,6 +1413,8 @@ static int is_shared_tree(struct libmnt_context *cxt, const char *dir) && (mflags & MS_SHARED); done: free(mnt); + if (!mnt_context_switch_ns(cxt, ns_old)) + return -MNT_ERR_NAMESPACE; return rc; } -- cgit v1.2.3-55-g7522