diff options
Diffstat (limited to 'libmount/src/context_mount.c')
| -rw-r--r-- | libmount/src/context_mount.c | 130 |
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) |
