int mnt_context_prepare_target(struct libmnt_context *cxt)
{
const char *tgt, *prefix;
- struct libmnt_cache *cache;
int rc = 0;
struct libmnt_ns *ns_old;
if (!ns_old)
return -MNT_ERR_NAMESPACE;
- /* mkdir target */
+ /* X-mount.mkdir target */
if (cxt->action == MNT_ACT_MOUNT
- && !mnt_context_is_restricted(cxt)
&& (cxt->user_mountflags & MNT_MS_XCOMMENT ||
cxt->user_mountflags & MNT_MS_XFSTABCOMM)) {
- rc = mkdir_target(tgt, cxt->fs);
- if (rc) {
- if (!mnt_context_switch_ns(cxt, ns_old))
- return -MNT_ERR_NAMESPACE;
- return rc; /* mkdir or parse error */
- }
+ /* supported only for root or non-suid mount(8) */
+ if (!mnt_context_is_restricted(cxt))
+ rc = mkdir_target(tgt, cxt->fs);
+ else
+ rc = -EPERM;
}
/* canonicalize the path */
- cache = mnt_context_get_cache(cxt);
- if (cache) {
- char *path = mnt_resolve_path(tgt, cache);
- if (path && strcmp(path, tgt) != 0)
- rc = mnt_fs_set_target(cxt->fs, path);
+ if (rc == 0) {
+ struct libmnt_cache *cache = mnt_context_get_cache(cxt);
+
+ if (cache) {
+ char *path = mnt_resolve_path(tgt, cache);
+ if (path && strcmp(path, tgt) != 0)
+ 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
- DBG(CXT, ul_debugobj(cxt, "final target '%s'",
- mnt_fs_get_target(cxt->fs)));
- return 0;
+ DBG(CXT, ul_debugobj(cxt, "final target '%s' [rc=%d]",
+ mnt_fs_get_target(cxt->fs), rc));
+ return rc;
}
/* Guess type, but not set to cxt->fs, always use free() for the result. It's
specifies the filesystem access mode used for
.BR mkdir (2)
in octal notation. The default mode is 0755. This functionality is supported
-only for root users. The option is also supported as x-mount.mkdir, this notation
-is deprecated for mount.mkdir since v2.30.
+only for root users or when mount executed without suid permissions. The option
+is also supported as x-mount.mkdir, this notation is deprecated for mount.mkdir
+since v2.30.
.SH "FILESYSTEM-SPECIFIC MOUNT OPTIONS"
You should consult the respective man page for the filesystem first.
* Check source and target paths -- non-root user should not be able to
* resolve paths which are unreadable for him.
*/
-static void sanitize_paths(struct libmnt_context *cxt)
+static int sanitize_paths(struct libmnt_context *cxt)
{
const char *p;
struct libmnt_fs *fs = mnt_context_get_fs(cxt);
if (!fs)
- return;
+ return 0;
p = mnt_fs_get_target(fs);
if (p) {
char *np = canonicalize_path_restricted(p);
if (!np)
- err(MNT_EX_USAGE, "%s", p);
+ return -EPERM;
mnt_fs_set_target(fs, np);
free(np);
}
if (p) {
char *np = canonicalize_path_restricted(p);
if (!np)
- err(MNT_EX_USAGE, "%s", p);
+ return -EPERM;
mnt_fs_set_source(fs, np);
free(np);
}
+ return 0;
}
static void append_option(struct libmnt_context *cxt, const char *opt)
errtryhelp(MNT_EX_USAGE);
}
- if (mnt_context_is_restricted(cxt))
- sanitize_paths(cxt);
+ if (mnt_context_is_restricted(cxt) && sanitize_paths(cxt) != 0)
+ suid_drop(cxt);
if (is_move)
/* "move" as option string is not supported by libmount */