summaryrefslogtreecommitdiffstats
path: root/libmount/src/context_mount.c
diff options
context:
space:
mode:
authorVaclav Dolezal2018-04-11 15:52:52 +0200
committerKarel Zak2018-06-11 16:12:55 +0200
commitcddd2eaa27c0c35b1a3bfbe7f76a1c7c1ea46517 (patch)
treeeebbe85cc140c70e7ddf40a1b1def6d7d7c913dd /libmount/src/context_mount.c
parentlibmount: support for namespaces for helpers (diff)
downloadkernel-qcow2-util-linux-cddd2eaa27c0c35b1a3bfbe7f76a1c7c1ea46517.tar.gz
kernel-qcow2-util-linux-cddd2eaa27c0c35b1a3bfbe7f76a1c7c1ea46517.tar.xz
kernel-qcow2-util-linux-cddd2eaa27c0c35b1a3bfbe7f76a1c7c1ea46517.zip
libmount: switch namespace when appropriate
Signed-off-by: Vaclav Dolezal <vdolezal@redhat.com>
Diffstat (limited to 'libmount/src/context_mount.c')
-rw-r--r--libmount/src/context_mount.c54
1 files changed, 52 insertions, 2 deletions
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;
}