]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: switch namespace when appropriate
authorVaclav Dolezal <vdolezal@redhat.com>
Wed, 11 Apr 2018 13:52:52 +0000 (15:52 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 11 Jun 2018 14:12:55 +0000 (16:12 +0200)
Signed-off-by: Vaclav Dolezal <vdolezal@redhat.com>
libmount/src/context.c
libmount/src/context_loopdev.c
libmount/src/context_mount.c
libmount/src/context_umount.c

index fdaa233c17fa12540f819acbc8d017eb6a718003..50ce5ca44b76ce080f35d98c3f24b5ba35810aa5 100644 (file)
@@ -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;
 }
 
index b1608dd458a494eafa54c2517ad381d1a0c691a6..05ff71ae78897cf8b51a3bd4281900b0d11a6e33 100644 (file)
@@ -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;
 }
 
index 5723958116dc9fdd1ebf09c161ee040acbb81b98..bc3c993bcf4bf0b7384abca96339605f0f74c9de 100644 (file)
@@ -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;
 }
 
index 70628b6cb6c4ae9dd862e43cee33647385b67193..b28e6faea1caa153a70878acc61de32bf0da1cc1 100644 (file)
@@ -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;
 }