From dc575b32b129bc2b2a6b71818c045d852ed40216 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Wed, 24 Dec 2008 04:58:16 -0600 Subject: [PATCH] Strip unnecessary mount options Certain options like "rw" should be stripped from the mount options string before being passed to mount(). These stripped options are represented in the mountflags mount() parameter (see the section 2 mount man page). If these options are not removed, the eCryptfs kernel module will complain in the syslog that they are unrecognized mount options. The original eCryptfs mount helper (mount.ecryptfs) handles this properly, but the mount.ecryptfs_private helper did not. This patch moves the ecryptfs_generate_mount_flags function from mount.ecryptfs to libecryptfs so that mount.ecryptfs_private can make use of it. Signed-off-by: Tyler Hicks --- src/include/ecryptfs.h | 1 + src/libecryptfs/main.c | 58 ++++++++++++++++++++++++++++++++++ src/utils/Makefile.am | 2 +- src/utils/mount.ecryptfs.c | 60 +----------------------------------- src/utils/mount.ecryptfs_private.c | 20 ++++++++--- 5 files changed, 75 insertions(+), 66 deletions(-) diff --git a/src/include/ecryptfs.h b/src/include/ecryptfs.h index 139525f..a343771 100644 --- a/src/include/ecryptfs.h +++ b/src/include/ecryptfs.h @@ -507,6 +507,7 @@ int ecryptfs_process_decision_graph(struct ecryptfs_ctx *ctx, int get_string(char *val, int len, int echo); int get_string_stdin(char **val, char *prompt, int echo); int stack_pop_val(struct val_node **head, void **val); +int ecryptfs_generate_mount_flags(char *options, unsigned long *flags); int ecryptfs_mount(char *source, char *target, unsigned long flags, char *opts); int ecryptfs_get_current_kernel_ciphers( struct ecryptfs_cipher_elem *cipher_list_head); diff --git a/src/libecryptfs/main.c b/src/libecryptfs/main.c index fc2de7c..cc0fc9f 100644 --- a/src/libecryptfs/main.c +++ b/src/libecryptfs/main.c @@ -303,6 +303,64 @@ out: return rc; } +int ecryptfs_generate_mount_flags(char *options, unsigned long *flags) +{ + char *opt; + char *next_opt; + char *end; + int num_options = 0; + + end = strchr(options, '\0'); + opt = options; + while (opt) { + if ((next_opt = strchr(opt, ','))) + next_opt++; + /* the following mount options should be + * stripped out from what is passed into the + * kernel since these eight options are best + * passed as the mount flags rather than + * redundantly to the kernel and could + * generate spurious warnings depending on the + * level of the corresponding cifs vfs kernel + * code */ + if (!strncmp(opt, "nosuid", 6)) + *flags |= MS_NOSUID; + else if (!strncmp(opt, "suid", 4)) + *flags &= ~MS_NOSUID; + else if (!strncmp(opt, "nodev", 5)) + *flags |= MS_NODEV; + else if (!strncmp(opt, "dev", 3)) + *flags &= ~MS_NODEV; + else if (!strncmp(opt, "noexec", 6)) + *flags |= MS_NOEXEC; + else if (!strncmp(opt, "exec", 4)) + *flags &= ~MS_NOEXEC; + else if (!strncmp(opt, "ro", 2)) + *flags |= MS_RDONLY; + else if (!strncmp(opt, "rw", 2)) + *flags &= ~MS_RDONLY; + else if (!strncmp(opt, "remount", 7)) + *flags |= MS_REMOUNT; + else { + opt = next_opt; + num_options++; + continue; + } + if (!next_opt) { + if (opt != options) + end = --opt; + else + end = options; + *end = '\0'; + break; + } + memcpy(opt, next_opt, end - next_opt); + end = end - (next_opt - opt); + *end = '\0'; + } + return num_options; +} + int ecryptfs_mount(char *source, char *target, unsigned long flags, char *opts) { FILE *mtab_fd = NULL; diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index ebc480e..82c77fe 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -47,7 +47,7 @@ ecryptfs_generate_tpm_key_CFLAGS = $(AM_CFLAGS) $(TSPI_CFLAGS) ecryptfs_generate_tpm_key_LDADD = $(TSPI_LIBS) mount_ecryptfs_private_SOURCES = mount.ecryptfs_private.c -mount_ecryptfs_private_LDADD = $(KEYUTILS_LIBS) +mount_ecryptfs_private_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) ecryptfs_stat_SOURCES = ecryptfs-stat.c ecryptfs_stat_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la diff --git a/src/utils/mount.ecryptfs.c b/src/utils/mount.ecryptfs.c index b881d47..0e80666 100644 --- a/src/utils/mount.ecryptfs.c +++ b/src/utils/mount.ecryptfs.c @@ -139,64 +139,6 @@ out: return rc; } -static int ecryptfs_generate_mount_flags(char *options, int *flags) -{ - char *opt; - char *next_opt; - char *end; - int num_options = 0; - - end = strchr(options, '\0'); - opt = options; - while (opt) { - if ((next_opt = strchr(opt, ','))) - next_opt++; - /* the following mount options should be - * stripped out from what is passed into the - * kernel since these eight options are best - * passed as the mount flags rather than - * redundantly to the kernel and could - * generate spurious warnings depending on the - * level of the corresponding cifs vfs kernel - * code */ - if (!strncmp(opt, "nosuid", 6)) - *flags |= MS_NOSUID; - else if (!strncmp(opt, "suid", 4)) - *flags &= ~MS_NOSUID; - else if (!strncmp(opt, "nodev", 5)) - *flags |= MS_NODEV; - else if (!strncmp(opt, "dev", 3)) - *flags &= ~MS_NODEV; - else if (!strncmp(opt, "noexec", 6)) - *flags |= MS_NOEXEC; - else if (!strncmp(opt, "exec", 4)) - *flags &= ~MS_NOEXEC; - else if (!strncmp(opt, "ro", 2)) - *flags |= MS_RDONLY; - else if (!strncmp(opt, "rw", 2)) - *flags &= ~MS_RDONLY; - else if (!strncmp(opt, "remount", 7)) - *flags |= MS_REMOUNT; - else { - opt = next_opt; - num_options++; - continue; - } - if (!next_opt) { - if (opt != options) - end = --opt; - else - end = options; - *end = '\0'; - break; - } - memcpy(opt, next_opt, end - next_opt); - end = end - (next_opt - opt); - *end = '\0'; - } - return num_options; -} - char *parameters_to_scrub[] = { "key=", "cipher=", @@ -445,8 +387,8 @@ static int ecryptfs_do_mount(int argc, char **argv, struct val_node *mnt_params, int sig_cache) { int rc; - int flags = 0; int num_opts = 0; + unsigned long flags = 0; char *src = NULL, *targ = NULL, *opts = NULL, *new_opts = NULL, *temp; char *val; diff --git a/src/utils/mount.ecryptfs_private.c b/src/utils/mount.ecryptfs_private.c index 99ff57d..f4e91a4 100644 --- a/src/utils/mount.ecryptfs_private.c +++ b/src/utils/mount.ecryptfs_private.c @@ -40,6 +40,7 @@ #include #include #include +#include "ecryptfs.h" /* Perhaps a future version of this program will allow these to be configurable * by the system administrator (or user?) at run time. For now, these are set @@ -398,9 +399,10 @@ int main(int argc, char *argv[]) { int uid, mounting; int force = 0; struct passwd *pwd; - char *dev, *mnt, *opt; + char *dev, *mnt, *full_opt, *mnt_opt; char *sig; FILE *fh_counter = NULL; + unsigned long flags; uid = getuid(); /* Non-privileged effective uid is sufficient for all but the code @@ -460,11 +462,11 @@ int main(int argc, char *argv[]) { perror("asprintf (mnt)"); goto fail; } - if ((asprintf(&opt, + if ((asprintf(&full_opt, "rw,ecryptfs_sig=%s,ecryptfs_cipher=%s,ecryptfs_key_bytes=%d,user=%s", sig, KEY_CIPHER, KEY_BYTES, pwd->pw_name) < 0) || - opt == NULL) { - perror("asprintf (opt)"); + full_opt == NULL) { + perror("asprintf (full_opt)"); goto fail; } @@ -488,6 +490,12 @@ int main(int argc, char *argv[]) { if (check_ownerships(uid, dev) != 0) { goto fail; } + if ((asprintf(&mnt_opt, "%s", full_opt) < 0) + || mnt_opt == NULL) { + perror("asprintf (mnt_opt)"); + goto fail; + } + ecryptfs_generate_mount_flags(mnt_opt, &flags); /* We must maintain our real uid as the user who called this * program in order to have access to their kernel keyring. * Even though root has the power to mount, only a user with @@ -499,8 +507,8 @@ int main(int argc, char *argv[]) { */ setreuid(-1, 0); /* Perform mount */ - if (mount(dev, mnt, FSTYPE, 0, opt) == 0) { - if (update_mtab(dev, mnt, opt) != 0) { + if (mount(dev, mnt, FSTYPE, flags, mnt_opt) == 0) { + if (update_mtab(dev, mnt, full_opt) != 0) { goto fail; } } else { -- 1.5.3.7