diff options
Diffstat (limited to 'libmount/src/context.c')
-rw-r--r-- | libmount/src/context.c | 149 |
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; } |