summaryrefslogtreecommitdiffstats
path: root/libmount/src/context_umount.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_umount.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_umount.c')
-rw-r--r--libmount/src/context_umount.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/libmount/src/context_umount.c b/libmount/src/context_umount.c
index 70628b6cb..b28e6faea 100644
--- a/libmount/src/context_umount.c
+++ b/libmount/src/context_umount.c
@@ -51,6 +51,7 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt,
struct libmnt_fs **pfs)
{
int rc;
+ struct libmnt_ns *ns_old;
struct libmnt_table *mtab = NULL;
struct libmnt_fs *fs;
char *loopdev = NULL;
@@ -100,6 +101,10 @@ int mnt_context_find_umount_fs(struct libmnt_context *cxt,
return 1;
}
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
try_loopdev:
fs = mnt_table_find_target(mtab, tgt, MNT_ITER_BACKWARD);
if (!fs && mnt_context_is_swapmatch(cxt)) {
@@ -159,12 +164,16 @@ try_loopdev:
if (pfs)
*pfs = fs;
free(loopdev);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
DBG(CXT, ul_debugobj(cxt, "umount fs: %s", fs ? mnt_fs_get_target(fs) :
"<not found>"));
return fs ? 0 : 1;
err:
free(loopdev);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc;
}
@@ -488,12 +497,20 @@ static int evaluate_permissions(struct libmnt_context *cxt)
char *curr_user;
char *mtab_user = NULL;
size_t sz;
+ struct libmnt_ns *ns_old;
DBG(CXT, ul_debugobj(cxt,
"umount: checking user=<username> from mtab"));
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
curr_user = mnt_get_username(getuid());
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (!curr_user) {
DBG(CXT, ul_debugobj(cxt, "umount %s: cannot "
"convert %d to username", tgt, getuid()));
@@ -558,6 +575,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 */
@@ -789,6 +809,7 @@ static int do_umount(struct libmnt_context *cxt)
int mnt_context_prepare_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs))
return -EINVAL;
@@ -804,6 +825,10 @@ int mnt_context_prepare_umount(struct libmnt_context *cxt)
cxt->helper = NULL;
cxt->action = MNT_ACT_UMOUNT;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = lookup_umount_fs(cxt);
if (!rc)
rc = mnt_context_merge_mflags(cxt);
@@ -837,6 +862,10 @@ int mnt_context_prepare_umount(struct libmnt_context *cxt)
return rc;
}
cxt->flags |= MNT_FL_PREPARED;
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}
@@ -861,6 +890,7 @@ int mnt_context_prepare_umount(struct libmnt_context *cxt)
int mnt_context_do_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -870,9 +900,13 @@ int mnt_context_do_umount(struct libmnt_context *cxt)
assert((cxt->action == MNT_ACT_UMOUNT));
assert((cxt->flags & MNT_FL_MOUNTFLAGS_MERGED));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = do_umount(cxt);
if (rc)
- return rc;
+ goto end;
if (mnt_context_get_status(cxt) && !mnt_context_is_fake(cxt)) {
/*
@@ -897,6 +931,10 @@ int mnt_context_do_umount(struct libmnt_context *cxt)
cxt->mountflags, NULL, cxt->fs);
}
}
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}
@@ -951,6 +989,7 @@ int mnt_context_finalize_umount(struct libmnt_context *cxt)
int mnt_context_umount(struct libmnt_context *cxt)
{
int rc;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -959,6 +998,10 @@ int mnt_context_umount(struct libmnt_context *cxt)
DBG(CXT, ul_debugobj(cxt, "umount: %s", mnt_context_get_target(cxt)));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = mnt_context_prepare_umount(cxt);
if (!rc)
rc = mnt_context_prepare_update(cxt);
@@ -966,6 +1009,10 @@ int mnt_context_umount(struct libmnt_context *cxt)
rc = mnt_context_do_umount(cxt);
if (!rc)
rc = mnt_context_update_tabs(cxt);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
return rc;
}