summaryrefslogtreecommitdiff
path: root/libmount/src/context_mount.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmount/src/context_mount.c')
-rw-r--r--libmount/src/context_mount.c130
1 files changed, 88 insertions, 42 deletions
diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
index d6691eb6a..89d1f4f29 100644
--- a/libmount/src/context_mount.c
+++ b/libmount/src/context_mount.c
@@ -21,6 +21,7 @@
#include "linux_version.h"
#include "mountP.h"
+#include "strutils.h"
/*
* Kernel supports only one MS_PROPAGATION flag change by one mount(2) syscall,
@@ -101,6 +102,30 @@ static int init_propagation(struct libmnt_context *cxt)
return 0;
}
+#if defined(HAVE_LIBSELINUX) || defined(HAVE_SMACK)
+struct libmnt_optname {
+ const char *name;
+ size_t namesz;
+};
+
+#define DEF_OPTNAME(n) { .name = n, .namesz = sizeof(n) - 1 }
+#define DEF_OPTNAME_LAST { .name = NULL }
+
+static int is_option(const char *name, size_t namesz,
+ const struct libmnt_optname *names)
+{
+ const struct libmnt_optname *p;
+
+ for (p = names; p && p->name; p++) {
+ if (p->namesz == namesz
+ && strncmp(name, p->name, namesz) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+#endif /* HAVE_LIBSELINUX || HAVE_SMACK */
+
/*
* this has to be called after mnt_context_evaluate_permissions()
*/
@@ -113,6 +138,25 @@ static int fix_optstr(struct libmnt_context *cxt)
struct libmnt_fs *fs;
#ifdef HAVE_LIBSELINUX
int se_fix = 0, se_rem = 0;
+ static const struct libmnt_optname selinux_options[] = {
+ DEF_OPTNAME("context"),
+ DEF_OPTNAME("fscontext"),
+ DEF_OPTNAME("defcontext"),
+ DEF_OPTNAME("rootcontext"),
+ DEF_OPTNAME("seclabel"),
+ DEF_OPTNAME_LAST
+ };
+#endif
+#ifdef HAVE_SMACK
+ int sm_rem = 0;
+ static const struct libmnt_optname smack_options[] = {
+ DEF_OPTNAME("smackfsdef"),
+ DEF_OPTNAME("smackfsfloor"),
+ DEF_OPTNAME("smackfshat"),
+ DEF_OPTNAME("smackfsroot"),
+ DEF_OPTNAME("smackfstransmute"),
+ DEF_OPTNAME_LAST
+ };
#endif
assert(cxt);
assert(cxt->fs);
@@ -129,8 +173,8 @@ static int fix_optstr(struct libmnt_context *cxt)
/*
* The "user" options is our business (so we can modify the option),
- * but exception is command line for /sbin/mount.<type> helpers. Let's
- * save the original user=<name> to call the helpers with unchanged
+ * the exception is command line for /sbin/mount.<type> helpers. Let's
+ * save the original user=<name> to call the helpers with an unchanged
* "user" setting.
*/
if (cxt->user_mountflags & MNT_MS_USER) {
@@ -168,7 +212,6 @@ static int fix_optstr(struct libmnt_context *cxt)
free(fs->user_optstr);
fs->user_optstr = NULL;
}
-
if (cxt->mountflags & MS_PROPAGATION) {
rc = init_propagation(cxt);
if (rc)
@@ -198,13 +241,15 @@ static int fix_optstr(struct libmnt_context *cxt)
if (!se_rem) {
/* de-duplicate SELinux options */
- mnt_optstr_deduplicate_option(&fs->fs_optstr, "context");
- mnt_optstr_deduplicate_option(&fs->fs_optstr, "fscontext");
- mnt_optstr_deduplicate_option(&fs->fs_optstr, "defcontext");
- mnt_optstr_deduplicate_option(&fs->fs_optstr, "rootcontext");
- mnt_optstr_deduplicate_option(&fs->fs_optstr, "seclabel");
+ const struct libmnt_optname *p;
+ for (p = selinux_options; p && p->name; p++)
+ mnt_optstr_deduplicate_option(&fs->fs_optstr, p->name);
}
#endif
+#ifdef HAVE_SMACK
+ if (access("/sys/fs/smackfs", F_OK) != 0)
+ sm_rem = 1;
+#endif
while (!mnt_optstr_next_option(&next, &name, &namesz, &val, &valsz)) {
if (namesz == 3 && !strncmp(name, "uid", 3))
@@ -212,12 +257,9 @@ static int fix_optstr(struct libmnt_context *cxt)
else if (namesz == 3 && !strncmp(name, "gid", 3))
rc = mnt_optstr_fix_gid(&fs->fs_optstr, val, valsz, &next);
#ifdef HAVE_LIBSELINUX
- else if ((se_rem || se_fix) &&
- namesz >= 7 && (!strncmp(name, "context", 7) ||
- !strncmp(name, "fscontext", 9) ||
- !strncmp(name, "defcontext", 10) ||
- !strncmp(name, "rootcontext", 11) ||
- !strncmp(name, "seclabel", 8))) {
+ else if ((se_rem || se_fix)
+ && is_option(name, namesz, selinux_options)) {
+
if (se_rem) {
/* remove context= option */
next = name;
@@ -231,6 +273,15 @@ static int fix_optstr(struct libmnt_context *cxt)
val, valsz, &next);
}
#endif
+#ifdef HAVE_SMACK
+ else if (sm_rem && is_option(name, namesz, smack_options)) {
+
+ next = name;
+ rc = mnt_optstr_remove_option_at(&fs->fs_optstr,
+ name,
+ val ? val + valsz : name + namesz);
+ }
+#endif
if (rc)
goto done;
}
@@ -255,7 +306,7 @@ done:
}
/*
- * Converts already evaluated and fixed options to the form that is compatible
+ * Converts the already evaluated and fixed options to the form that is compatible
* with /sbin/mount.type helpers.
*/
static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr)
@@ -278,13 +329,13 @@ static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr)
if (cxt->user_mountflags & MNT_MS_USER) {
/*
* This is unnecessary for real user-mounts as mount.<type>
- * helpers have to always follow fstab rather than mount
- * options on command line.
+ * helpers always have to follow fstab rather than mount
+ * options on the command line.
*
- * But if you call mount.<type> as root then the helper follows
- * command line. If there is (for example) "user,exec" in fstab
+ * However, if you call mount.<type> as root, then the helper follows
+ * the command line. If there is (for example) "user,exec" in fstab,
* then we have to manually append the "exec" back to the options
- * string, bacause there is nothing like MS_EXEC (we have only
+ * string, bacause there is nothing like MS_EXEC (we only have
* MS_NOEXEC in mount flags and we don't care about the original
* mount string in libmount for VFS options).
*/
@@ -330,7 +381,7 @@ err:
/*
* this has to be called before fix_optstr()
*
- * Note that user=<name> maybe be used by some filesystems as filesystem
+ * Note that user=<name> may be used by some filesystems as a filesystem
* specific option (e.g. cifs). Yes, developers of such filesystems have
* allocated pretty hot place in hell...
*/
@@ -361,7 +412,7 @@ static int evaluate_permissions(struct libmnt_context *cxt)
/*
* user mount
*/
- if (!(cxt->flags & MNT_FL_TAB_APPLIED))
+ if (!mnt_context_tab_applied(cxt))
{
DBG(CXT, mnt_debug_h(cxt, "perms: fstab not applied, ignore user mount"));
return -EPERM;
@@ -433,7 +484,7 @@ static int evaluate_permissions(struct libmnt_context *cxt)
/*
* mnt_context_helper_setopt() backend
*
- * This function applies mount.type command line option (for example parsed
+ * This function applies the mount.type command line option (for example parsed
* by getopt() or getopt_long()) to @cxt. All unknown options are ignored and
* then 1 is returned.
*
@@ -519,7 +570,7 @@ static int exec_helper(struct libmnt_context *cxt)
/*
* TODO: remove the exception for "nfs", -s is documented
- * for years should be usable everywhere.
+ * for years and should be usable everywhere.
*/
if (mnt_context_is_sloppy(cxt) &&
type && startswith(type, "nfs"))
@@ -651,7 +702,7 @@ static int do_mount(struct libmnt_context *cxt, const char *try_type)
return -EINVAL;
if (!src) {
/* unnecessary, should be already resolved in
- * mnt_context_prepare_srcpath(), but for sure... */
+ * mnt_context_prepare_srcpath(), but to be sure... */
DBG(CXT, mnt_debug_h(cxt, "WARNING: source is NULL -- using \"none\"!"));
src = "none";
}
@@ -831,10 +882,10 @@ int mnt_context_prepare_mount(struct libmnt_context *cxt)
* Call mount(2) or mount.type helper. Unnecessary for mnt_context_mount().
*
* Note that this function could be called only once. If you want to mount
- * another source or target than you have to call mnt_reset_context().
+ * another source or target, then you have to call mnt_reset_context().
*
- * If you want to call mount(2) for the same source and target with a different
- * mount flags or fstype then call mnt_context_reset_status() and then try
+ * If you want to call mount(2) for the same source and target with different
+ * mount flags or fstype, then call mnt_context_reset_status() and then try
* again mnt_context_do_mount().
*
* WARNING: non-zero return code does not mean that mount(2) syscall or
@@ -867,7 +918,7 @@ int mnt_context_do_mount(struct libmnt_context *cxt)
type = mnt_fs_get_fstype(cxt->fs);
if (type) {
if (strchr(type, ','))
- /* this only happens if fstab contains list of filesystems */
+ /* this only happens if fstab contains a list of filesystems */
res = do_mount_by_pattern(cxt, type);
else
res = do_mount(cxt, NULL);
@@ -935,7 +986,7 @@ int mnt_context_finalize_mount(struct libmnt_context *cxt)
* mnt_context_mount:
* @cxt: mount context
*
- * High-level, mounts filesystem by mount(2) or fork()+exec(/sbin/mount.type).
+ * High-level, mounts the filesystem by mount(2) or fork()+exec(/sbin/mount.type).
*
* This is similar to:
*
@@ -945,10 +996,10 @@ int mnt_context_finalize_mount(struct libmnt_context *cxt)
*
* See also mnt_context_disable_helpers().
*
- * Note that this function could be called only once. If you want to mount with
- * different setting than you have to call mnt_reset_context(). It's NOT enough
- * to call mnt_context_reset_status() if you want call this function more than
- * once, whole context has to be reseted.
+ * Note that this function should be called only once. If you want to mount with
+ * different settings, then you have to call mnt_reset_context(). It's NOT enough
+ * to call mnt_context_reset_status(). If you want to call this function more than
+ * once, the whole context has to be reset.
*
* WARNING: non-zero return code does not mean that mount(2) syscall or
* mount.type helper wasn't successfully called.
@@ -973,11 +1024,6 @@ int mnt_context_mount(struct libmnt_context *cxt)
rc = mnt_context_prepare_update(cxt);
if (!rc)
rc = mnt_context_do_mount(cxt);
-
- /* TODO: if mtab update is expected then check if the
- * target is really mounted read-write to avoid 'ro' in
- * mtab and 'rw' in /proc/mounts.
- */
if (!rc)
rc = mnt_context_update_tabs(cxt);
return rc;
@@ -989,7 +1035,7 @@ int mnt_context_mount(struct libmnt_context *cxt)
* @itr: iterator
* @fs: returns the current filesystem
* @mntrc: returns the return code from mnt_context_mount()
- * @ignored: returns 1 for not matching and 2 for already mounted filesystems
+ * @ignored: returns 1 for non-matching and 2 for already mounted filesystems
*
* This function tries to mount the next filesystem from fstab (as returned by
* mnt_context_get_fstab()). See also mnt_context_set_fstab().
@@ -1057,11 +1103,11 @@ int mnt_context_next_mount(struct libmnt_context *cxt,
/* ignore noauto filesystems */
(o && mnt_optstr_get_option(o, "noauto", NULL, NULL) == 0) ||
- /* ignore filesystems not match with options patterns */
+ /* ignore filesystems which don't match options patterns */
(cxt->fstype_pattern && !mnt_fs_match_fstype(*fs,
cxt->fstype_pattern)) ||
- /* ignore filesystems not match with type patterns */
+ /* ignore filesystems which don't match type patterns */
(cxt->optstr_pattern && !mnt_fs_match_options(*fs,
cxt->optstr_pattern))) {
if (ignored)