summaryrefslogtreecommitdiffstats
path: root/libmount
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
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')
-rw-r--r--libmount/src/context.c149
-rw-r--r--libmount/src/context_loopdev.c8
-rw-r--r--libmount/src/context_mount.c54
-rw-r--r--libmount/src/context_umount.c49
4 files changed, 241 insertions, 19 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index fdaa233c1..50ce5ca44 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -213,6 +213,8 @@ int mnt_context_reset_status(struct libmnt_context *cxt)
static int context_init_paths(struct libmnt_context *cxt, int writable)
{
+ struct libmnt_ns *ns_old;
+
assert(cxt);
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
@@ -233,6 +235,10 @@ static int context_init_paths(struct libmnt_context *cxt, int writable)
cxt->mtab_writable = 0;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
mnt_has_regular_mtab(&cxt->mtab_path, &cxt->mtab_writable);
if (!cxt->mtab_writable)
@@ -240,6 +246,9 @@ static int context_init_paths(struct libmnt_context *cxt, int writable)
/* use /run/mount/utab if /etc/mtab is useless */
mnt_has_regular_utab(&cxt->utab_path, &cxt->utab_writable);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
cxt->flags |= MNT_FL_TABPATHS_CHECKED;
return 0;
}
@@ -1034,6 +1043,8 @@ int mnt_context_set_fstab(struct libmnt_context *cxt, struct libmnt_table *tb)
*/
int mnt_context_get_fstab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
+ struct libmnt_ns *ns_old;
+
if (!cxt)
return -EINVAL;
if (!cxt->fstab) {
@@ -1044,8 +1055,17 @@ int mnt_context_get_fstab(struct libmnt_context *cxt, struct libmnt_table **tb)
return -ENOMEM;
if (cxt->table_errcb)
mnt_table_set_parser_errcb(cxt->fstab, cxt->table_errcb);
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
mnt_table_set_cache(cxt->fstab, mnt_context_get_cache(cxt));
rc = mnt_table_parse_fstab(cxt->fstab, NULL);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc)
return rc;
}
@@ -1067,16 +1087,23 @@ int mnt_context_get_fstab(struct libmnt_context *cxt, struct libmnt_table **tb)
*/
int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
{
+ int rc = 0;
+ struct libmnt_ns *ns_old = NULL;
+
if (!cxt)
return -EINVAL;
if (!cxt->mtab) {
- int rc;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
context_init_paths(cxt, 0);
cxt->mtab = mnt_new_table();
- if (!cxt->mtab)
- return -ENOMEM;
+ if (!cxt->mtab) {
+ rc = -ENOMEM;
+ goto end;
+ }
if (cxt->table_errcb)
mnt_table_set_parser_errcb(cxt->mtab, cxt->table_errcb);
@@ -1097,7 +1124,7 @@ int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
else
rc = mnt_table_parse_mtab(cxt->mtab, cxt->mtab_path);
if (rc)
- return rc;
+ goto end;
}
if (tb)
@@ -1105,7 +1132,12 @@ int mnt_context_get_mtab(struct libmnt_context *cxt, struct libmnt_table **tb)
DBG(CXT, ul_debugobj(cxt, "mtab requested [nents=%d]",
mnt_table_get_nents(cxt->mtab)));
- return 0;
+
+end:
+ if (ns_old && !mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
+ return rc;
}
/*
@@ -1135,6 +1167,11 @@ int mnt_context_get_mtab_for_target(struct libmnt_context *cxt,
struct libmnt_cache *cache = NULL;
char *cn_tgt = NULL;
int rc;
+ struct libmnt_ns *ns_old;
+
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
if (mnt_context_is_nocanonicalize(cxt))
mnt_context_set_tabfilter(cxt, mtab_filter, (void *) tgt);
@@ -1149,6 +1186,9 @@ int mnt_context_get_mtab_for_target(struct libmnt_context *cxt,
rc = mnt_context_get_mtab(cxt, mtab);
mnt_context_set_tabfilter(cxt, NULL, NULL);
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (cn_tgt && !cache)
free(cn_tgt);
@@ -1201,6 +1241,7 @@ int mnt_context_get_table(struct libmnt_context *cxt,
const char *filename, struct libmnt_table **tb)
{
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !tb)
return -EINVAL;
@@ -1212,14 +1253,24 @@ int mnt_context_get_table(struct libmnt_context *cxt,
if (cxt->table_errcb)
mnt_table_set_parser_errcb(*tb, cxt->table_errcb);
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
rc = mnt_table_parse_file(*tb, filename);
+
if (rc) {
mnt_unref_table(*tb);
- return rc;
+ goto end;
}
mnt_table_set_cache(*tb, mnt_context_get_cache(cxt));
- return 0;
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
+ return rc;
}
/**
@@ -1530,6 +1581,7 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
struct libmnt_cache *cache;
const char *t, *v, *src;
int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -1551,6 +1603,10 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
DBG(CXT, ul_debugobj(cxt, "srcpath '%s'", src));
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
cache = mnt_context_get_cache(cxt);
if (!mnt_fs_get_tag(cxt->fs, &t, &v)) {
@@ -1573,7 +1629,7 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
if (rc) {
DBG(CXT, ul_debugobj(cxt, "failed to prepare srcpath [rc=%d]", rc));
- return rc;
+ goto end;
}
if (!path)
@@ -1582,7 +1638,7 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
if ((cxt->mountflags & (MS_BIND | MS_MOVE | MS_REMOUNT))
|| mnt_fs_is_pseudofs(cxt->fs)) {
DBG(CXT, ul_debugobj(cxt, "REMOUNT/BIND/MOVE/pseudo FS source: %s", path));
- return rc;
+ goto end;
}
/*
@@ -1591,12 +1647,16 @@ int mnt_context_prepare_srcpath(struct libmnt_context *cxt)
if (mnt_context_is_loopdev(cxt)) {
rc = mnt_context_setup_loopdev(cxt);
if (rc)
- return rc;
+ goto end;
}
DBG(CXT, ul_debugobj(cxt, "final srcpath '%s'",
mnt_fs_get_source(cxt->fs)));
- return 0;
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+ return rc;
}
/* create a mountpoint if X-mount.mkdir[=<mode>] specified */
@@ -1649,6 +1709,7 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
const char *tgt;
struct libmnt_cache *cache;
int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -1660,6 +1721,10 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
if (!tgt)
return 0;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* mkdir target */
if (cxt->action == MNT_ACT_MOUNT
&& !mnt_context_is_restricted(cxt)
@@ -1667,8 +1732,11 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
cxt->user_mountflags & MNT_MS_XFSTABCOMM)) {
rc = mkdir_target(tgt, cxt->fs);
- if (rc)
+ if (rc) {
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc; /* mkdir or parse error */
+ }
}
/* canonicalize the path */
@@ -1679,6 +1747,9 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
rc = mnt_fs_set_target(cxt->fs, path);
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc)
DBG(CXT, ul_debugobj(cxt, "failed to prepare target '%s'", tgt));
else
@@ -1694,6 +1765,7 @@ int mnt_context_prepare_target(struct libmnt_context *cxt)
int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type)
{
int rc = 0;
+ struct libmnt_ns *ns_old;
const char *dev = mnt_fs_get_srcpath(cxt->fs);
*type = NULL;
@@ -1701,6 +1773,10 @@ int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type)
if (!dev)
goto done;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
if (access(dev, F_OK) == 0) {
struct libmnt_cache *cache = mnt_context_get_cache(cxt);
int ambi = 0;
@@ -1718,6 +1794,9 @@ int mnt_context_guess_srcpath_fstype(struct libmnt_context *cxt, char **type)
*type = strdup("cifs");
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
done:
return rc;
}
@@ -1779,6 +1858,7 @@ int mnt_context_prepare_helper(struct libmnt_context *cxt, const char *name,
{
char search_path[] = FS_SEARCH_PATH; /* from config.h */
char *p = NULL, *path;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -1797,6 +1877,10 @@ int mnt_context_prepare_helper(struct libmnt_context *cxt, const char *name,
|| mnt_fs_is_swaparea(cxt->fs))
return 0;
+ ns_old = mnt_context_switch_origin_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
path = strtok_r(search_path, ":", &p);
while (path) {
char helper[PATH_MAX];
@@ -1824,6 +1908,9 @@ int mnt_context_prepare_helper(struct libmnt_context *cxt, const char *name,
if (rc)
continue;
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
free(cxt->helper);
cxt->helper = strdup(helper);
if (!cxt->helper)
@@ -1831,6 +1918,8 @@ int mnt_context_prepare_helper(struct libmnt_context *cxt, const char *name,
return 0;
}
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return 0;
}
@@ -1933,6 +2022,8 @@ int mnt_context_prepare_update(struct libmnt_context *cxt)
int mnt_context_update_tabs(struct libmnt_context *cxt)
{
unsigned long fl;
+ int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
@@ -1945,6 +2036,10 @@ int mnt_context_update_tabs(struct libmnt_context *cxt)
return 0;
}
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* check utab update when external helper executed */
if (mnt_context_helper_executed(cxt)
&& mnt_context_get_helper_status(cxt) == 0
@@ -1952,11 +2047,11 @@ int mnt_context_update_tabs(struct libmnt_context *cxt)
if (mnt_update_already_done(cxt->update, cxt->lock)) {
DBG(CXT, ul_debugobj(cxt, "don't update: error evaluate or already updated"));
- return 0;
+ goto end;
}
} else if (cxt->helper) {
DBG(CXT, ul_debugobj(cxt, "don't update: external helper"));
- return 0;
+ goto end;
}
if (cxt->syscall_status != 0
@@ -1964,7 +2059,7 @@ int mnt_context_update_tabs(struct libmnt_context *cxt)
mnt_context_get_helper_status(cxt) == 0)) {
DBG(CXT, ul_debugobj(cxt, "don't update: syscall/helper failed/not called"));
- return 0;
+ goto end;
}
fl = mnt_update_get_mflags(cxt->update);
@@ -1975,7 +2070,12 @@ int mnt_context_update_tabs(struct libmnt_context *cxt)
mnt_update_force_rdonly(cxt->update,
cxt->mountflags & MS_RDONLY);
- return mnt_update_table(cxt->update, cxt->lock);
+ rc = mnt_update_table(cxt->update, cxt->lock);
+
+end:
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+ return rc;
}
static int apply_table(struct libmnt_context *cxt, struct libmnt_table *tb,
@@ -2063,6 +2163,7 @@ static int apply_table(struct libmnt_context *cxt, struct libmnt_table *tb,
int mnt_context_apply_fstab(struct libmnt_context *cxt)
{
int rc = -1, isremount = 0, iscmdbind = 0;
+ struct libmnt_ns *ns_old;
struct libmnt_table *tab = NULL;
const char *src = NULL, *tgt = NULL;
unsigned long mflags = 0;
@@ -2124,6 +2225,10 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
/* let's initialize cxt->fs */
ignore_result( mnt_context_get_fs(cxt) );
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
/* try fstab */
if (cxt->optsmode & MNT_OMODE_FSTAB) {
DBG(CXT, ul_debugobj(cxt, "trying to apply fstab (src=%s, target=%s)", src, tgt));
@@ -2143,6 +2248,10 @@ int mnt_context_apply_fstab(struct libmnt_context *cxt)
if (!rc)
rc = apply_table(cxt, tab, MNT_ITER_BACKWARD);
}
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
+
if (rc) {
if (!mnt_context_is_restricted(cxt)
&& tgt && !src
@@ -2477,10 +2586,15 @@ int mnt_context_is_fs_mounted(struct libmnt_context *cxt,
{
struct libmnt_table *mtab, *orig;
int rc;
+ struct libmnt_ns *ns_old;
if (!cxt || !fs || !mounted)
return -EINVAL;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
orig = cxt->mtab;
rc = mnt_context_get_mtab(cxt, &mtab);
if (rc == -ENOENT && mnt_fs_streq_target(fs, "/proc") &&
@@ -2495,6 +2609,9 @@ int mnt_context_is_fs_mounted(struct libmnt_context *cxt,
return rc;
*mounted = mnt_table_is_fs_mounted(mtab, fs);
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return 0;
}
diff --git a/libmount/src/context_loopdev.c b/libmount/src/context_loopdev.c
index b1608dd45..05ff71ae7 100644
--- a/libmount/src/context_loopdev.c
+++ b/libmount/src/context_loopdev.c
@@ -89,6 +89,7 @@ is_mounted_same_loopfile(struct libmnt_context *cxt,
struct libmnt_cache *cache;
const char *bf;
int rc = 0;
+ struct libmnt_ns *ns_old;
assert(cxt);
assert(cxt->fs);
@@ -97,6 +98,10 @@ is_mounted_same_loopfile(struct libmnt_context *cxt,
if (mnt_context_get_mtab(cxt, &tb))
return 0;
+ ns_old = mnt_context_switch_target_ns(cxt);
+ if (!ns_old)
+ return -MNT_ERR_NAMESPACE;
+
DBG(LOOP, ul_debugobj(cxt, "checking if %s mounted on %s",
backing_file, target));
@@ -132,6 +137,9 @@ is_mounted_same_loopfile(struct libmnt_context *cxt,
}
if (rc)
DBG(LOOP, ul_debugobj(cxt, "%s already mounted", backing_file));
+
+ if (!mnt_context_switch_ns(cxt, ns_old))
+ return -MNT_ERR_NAMESPACE;
return rc;
}
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;
}
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;
}