summaryrefslogtreecommitdiffstats
path: root/libmount/src/context.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.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.c')
-rw-r--r--libmount/src/context.c149
1 files changed, 133 insertions, 16 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;
}