From 442155c1bd84f82bff2d05d0ec4d0090df17ecfa Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 1 Nov 2018 23:07:24 +0000 Subject: selinux: Implement the new mount API LSM hooks Implement the new mount API LSM hooks for SELinux. At some point the old hooks will need to be removed. Signed-off-by: David Howells cc: Paul Moore cc: Stephen Smalley cc: selinux@tycho.nsa.gov cc: linux-security-module@vger.kernel.org Signed-off-by: Al Viro --- security/selinux/hooks.c | 49 +++++++++++++++++++++++++++++++++---- security/selinux/include/security.h | 10 ++++---- 2 files changed, 49 insertions(+), 10 deletions(-) (limited to 'security/selinux') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f0e36c3492ba..f99381e97d73 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -48,6 +48,8 @@ #include #include #include +#include +#include #include #include #include @@ -454,11 +456,11 @@ static inline int inode_doinit(struct inode *inode) enum { Opt_error = -1, - Opt_context = 1, + Opt_context = 0, + Opt_defcontext = 1, Opt_fscontext = 2, - Opt_defcontext = 3, - Opt_rootcontext = 4, - Opt_seclabel = 5, + Opt_rootcontext = 3, + Opt_seclabel = 4, }; #define A(s, has_arg) {#s, sizeof(#s) - 1, Opt_##s, has_arg} @@ -1089,6 +1091,7 @@ static int show_sid(struct seq_file *m, u32 sid) if (!rc) { bool has_comma = context && strchr(context, ','); + seq_putc(m, '='); if (has_comma) seq_putc(m, '\"'); seq_escape(m, context, "\"\n\\"); @@ -1142,7 +1145,7 @@ static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) } if (sbsec->flags & SBLABEL_MNT) { seq_putc(m, ','); - seq_puts(m, LABELSUPP_STR); + seq_puts(m, SECLABEL_STR); } return 0; } @@ -2761,6 +2764,38 @@ static int selinux_umount(struct vfsmount *mnt, int flags) FILESYSTEM__UNMOUNT, NULL); } +static const struct fs_parameter_spec selinux_param_specs[] = { + fsparam_string(CONTEXT_STR, Opt_context), + fsparam_string(DEFCONTEXT_STR, Opt_defcontext), + fsparam_string(FSCONTEXT_STR, Opt_fscontext), + fsparam_string(ROOTCONTEXT_STR, Opt_rootcontext), + fsparam_flag (SECLABEL_STR, Opt_seclabel), + {} +}; + +static const struct fs_parameter_description selinux_fs_parameters = { + .name = "SELinux", + .specs = selinux_param_specs, +}; + +static int selinux_fs_context_parse_param(struct fs_context *fc, + struct fs_parameter *param) +{ + struct fs_parse_result result; + int opt, rc; + + opt = fs_parse(fc, &selinux_fs_parameters, param, &result); + if (opt < 0) + return opt; + + rc = selinux_add_opt(opt, param->string, &fc->security); + if (!rc) { + param->string = NULL; + rc = 1; + } + return rc; +} + /* inode security operations */ static int selinux_inode_alloc_security(struct inode *inode) @@ -6710,6 +6745,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), + LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), + LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), @@ -6978,6 +7015,8 @@ static __init int selinux_init(void) else pr_debug("SELinux: Starting in permissive mode\n"); + fs_validate_description(&selinux_fs_parameters); + return 0; } diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index ba8eedf42b90..529d8941c9c5 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -59,11 +59,11 @@ #define SE_SBPROC 0x0200 #define SE_SBGENFS 0x0400 -#define CONTEXT_STR "context=" -#define FSCONTEXT_STR "fscontext=" -#define ROOTCONTEXT_STR "rootcontext=" -#define DEFCONTEXT_STR "defcontext=" -#define LABELSUPP_STR "seclabel" +#define CONTEXT_STR "context" +#define FSCONTEXT_STR "fscontext" +#define ROOTCONTEXT_STR "rootcontext" +#define DEFCONTEXT_STR "defcontext" +#define SECLABEL_STR "seclabel" struct netlbl_lsm_secattr; -- cgit From 0b52075ee62301dd150c9f2c3ddd0035ed894cde Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 23 Dec 2018 16:02:47 -0500 Subject: introduce cloning of fs_context new primitive: vfs_dup_fs_context(). Comes with fs_context method (->dup()) for copying the filesystem-specific parts of fs_context, along with LSM one (->fs_context_dup()) for doing the same to LSM parts. [needs better commit message, and change of Author:, anyway] Signed-off-by: Al Viro --- security/selinux/hooks.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'security/selinux') diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f99381e97d73..4ba83de5fa80 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2764,6 +2764,44 @@ static int selinux_umount(struct vfsmount *mnt, int flags) FILESYSTEM__UNMOUNT, NULL); } +static int selinux_fs_context_dup(struct fs_context *fc, + struct fs_context *src_fc) +{ + const struct selinux_mnt_opts *src = src_fc->security; + struct selinux_mnt_opts *opts; + + if (!src) + return 0; + + fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); + if (!fc->security) + return -ENOMEM; + + opts = fc->security; + + if (src->fscontext) { + opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL); + if (!opts->fscontext) + return -ENOMEM; + } + if (src->context) { + opts->context = kstrdup(src->context, GFP_KERNEL); + if (!opts->context) + return -ENOMEM; + } + if (src->rootcontext) { + opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL); + if (!opts->rootcontext) + return -ENOMEM; + } + if (src->defcontext) { + opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL); + if (!opts->defcontext) + return -ENOMEM; + } + return 0; +} + static const struct fs_parameter_spec selinux_param_specs[] = { fsparam_string(CONTEXT_STR, Opt_context), fsparam_string(DEFCONTEXT_STR, Opt_defcontext), @@ -6745,6 +6783,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_committing_creds, selinux_bprm_committing_creds), LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), + LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), -- cgit