diff mbox series

[v10,07/11] LSM: Helpers for attribute names and filling lsm_ctx

Message ID 20230428203417.159874-8-casey@schaufler-ca.com (mailing list archive)
State Superseded
Delegated to: Paul Moore
Headers show
Series [v10,01/11] LSM: Identify modules by more than name | expand

Commit Message

Casey Schaufler April 28, 2023, 8:34 p.m. UTC
Add lsm_name_to_attr(), which translates a text string to a
LSM_ATTR value if one is available.

Add lsm_fill_user_ctx(), which fills a struct lsm_ctx, including
the trailing attribute value. The .len value is padded to a multiple
of 64 bits for alignment.

All are used in module specific components of LSM system calls.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/security.h | 13 ++++++++++++
 security/lsm_syscalls.c  | 24 ++++++++++++++++++++++
 security/security.c      | 44 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+)

Comments

kernel test robot April 29, 2023, 1:06 a.m. UTC | #1
Hi Casey,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/perf/core]
[also build test ERROR on acme/perf/core shuah-kselftest/next shuah-kselftest/fixes v6.3]
[cannot apply to linus/master next-20230428]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/LSM-Maintain-a-table-of-LSM-attribute-data/20230429-053458
base:   tip/perf/core
patch link:    https://lore.kernel.org/r/20230428203417.159874-8-casey%40schaufler-ca.com
patch subject: [PATCH v10 07/11] LSM: Helpers for attribute names and filling lsm_ctx
config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20230429/202304290847.WxviiKLP-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/9830f4776196e33bee604b8ce3339177f8fd37f8
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Casey-Schaufler/LSM-Maintain-a-table-of-LSM-attribute-data/20230429-053458
        git checkout 9830f4776196e33bee604b8ce3339177f8fd37f8
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=um SUBARCH=i386 olddefconfig
        make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304290847.WxviiKLP-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:89,
                    from init/main.c:21:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   init/main.c: At top level:
   init/main.c:775:20: warning: no previous prototype for 'arch_post_acpi_subsys_init' [-Wmissing-prototypes]
     775 | void __init __weak arch_post_acpi_subsys_init(void) { }
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~
   init/main.c:787:20: warning: no previous prototype for 'mem_encrypt_init' [-Wmissing-prototypes]
     787 | void __init __weak mem_encrypt_init(void) { }
         |                    ^~~~~~~~~~~~~~~~
   init/main.c:789:20: warning: no previous prototype for 'poking_init' [-Wmissing-prototypes]
     789 | void __init __weak poking_init(void) { }
         |                    ^~~~~~~~~~~
--
   In file included from init/do_mounts.c:9:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from include/net/scm.h:8,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:46,
                    from include/uapi/linux/if_arp.h:27,
                    from include/linux/if_arp.h:23,
                    from arch/um/drivers/slirp_kern.c:6:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   arch/um/drivers/slirp_kern.c: At top level:
   arch/um/drivers/slirp_kern.c:18:6: warning: no previous prototype for 'slirp_init' [-Wmissing-prototypes]
      18 | void slirp_init(struct net_device *dev, void *data)
         |      ^~~~~~~~~~
--
   In file included from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:89,
                    from arch/x86/um/tls_32.c:8:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   arch/x86/um/tls_32.c: At top level:
   arch/x86/um/tls_32.c:23:5: warning: no previous prototype for 'do_set_thread_area' [-Wmissing-prototypes]
      23 | int do_set_thread_area(struct user_desc *info)
         |     ^~~~~~~~~~~~~~~~~~
   arch/x86/um/tls_32.c:39:5: warning: no previous prototype for 'do_get_thread_area' [-Wmissing-prototypes]
      39 | int do_get_thread_area(struct user_desc *info)
         |     ^~~~~~~~~~~~~~~~~~
   arch/x86/um/tls_32.c:184:5: warning: no previous prototype for 'arch_switch_tls' [-Wmissing-prototypes]
     184 | int arch_switch_tls(struct task_struct *to)
         |     ^~~~~~~~~~~~~~~
--
   In file included from kernel/fork.c:51:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   kernel/fork.c: At top level:
   kernel/fork.c:162:13: warning: no previous prototype for 'arch_release_task_struct' [-Wmissing-prototypes]
     162 | void __weak arch_release_task_struct(struct task_struct *tsk)
         |             ^~~~~~~~~~~~~~~~~~~~~~~~
   kernel/fork.c:859:20: warning: no previous prototype for 'arch_task_cache_init' [-Wmissing-prototypes]
     859 | void __init __weak arch_task_cache_init(void) { }
         |                    ^~~~~~~~~~~~~~~~~~~~
   kernel/fork.c:954:12: warning: no previous prototype for 'arch_dup_task_struct' [-Wmissing-prototypes]
     954 | int __weak arch_dup_task_struct(struct task_struct *dst,
         |            ^~~~~~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:89,
                    from kernel/exit.c:42:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   kernel/exit.c: At top level:
   kernel/exit.c:1915:32: warning: no previous prototype for 'abort' [-Wmissing-prototypes]
    1915 | __weak __function_aligned void abort(void)
         |                                ^~~~~
--
   In file included from include/net/scm.h:8,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:46,
                    from include/linux/if_vlan.h:10,
                    from include/linux/filter.h:21,
                    from kernel/kallsyms.c:25:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   kernel/kallsyms.c: At top level:
   kernel/kallsyms.c:663:12: warning: no previous prototype for 'arch_get_kallsym' [-Wmissing-prototypes]
     663 | int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
         |            ^~~~~~~~~~~~~~~~
--
   In file included from include/linux/fs_context.h:14,
                    from include/linux/pseudo_fs.h:4,
                    from fs/pipe.c:17:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   fs/pipe.c: At top level:
   fs/pipe.c:757:15: warning: no previous prototype for 'account_pipe_buffers' [-Wmissing-prototypes]
     757 | unsigned long account_pipe_buffers(struct user_struct *user,
         |               ^~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:763:6: warning: no previous prototype for 'too_many_pipe_buffers_soft' [-Wmissing-prototypes]
     763 | bool too_many_pipe_buffers_soft(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:770:6: warning: no previous prototype for 'too_many_pipe_buffers_hard' [-Wmissing-prototypes]
     770 | bool too_many_pipe_buffers_hard(unsigned long user_bufs)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:777:6: warning: no previous prototype for 'pipe_is_unprivileged_user' [-Wmissing-prototypes]
     777 | bool pipe_is_unprivileged_user(void)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~
   fs/pipe.c:1253:5: warning: no previous prototype for 'pipe_resize_ring' [-Wmissing-prototypes]
    1253 | int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots)
         |     ^~~~~~~~~~~~~~~~
--
   In file included from include/linux/perf_event.h:62,
                    from include/linux/trace_events.h:10,
                    from include/trace/syscall.h:7,
                    from include/linux/syscalls.h:89,
                    from fs/d_path.c:2:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   fs/d_path.c: At top level:
   fs/d_path.c:317:7: warning: no previous prototype for 'simple_dname' [-Wmissing-prototypes]
     317 | char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
         |       ^~~~~~~~~~~~
--
   In file included from include/net/scm.h:8,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:46,
                    from include/net/sock.h:46,
                    from include/linux/tcp.h:19,
                    from include/linux/ipv6.h:93,
                    from include/net/addrconf.h:52,
                    from lib/vsprintf.c:40:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   lib/vsprintf.c: In function 'va_format':
   lib/vsprintf.c:1681:9: warning: function 'va_format' might be a candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
    1681 |         buf += vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va);
         |         ^~~
--
   In file included from include/net/scm.h:8,
                    from include/linux/netlink.h:9,
                    from include/uapi/linux/neighbour.h:6,
                    from include/linux/netdevice.h:46,
                    from include/net/sock.h:46,
                    from include/linux/bpf-cgroup.h:11,
                    from net/socket.c:55:
   include/linux/security.h: In function 'lsm_name_to_attr':
>> include/linux/security.h:516:16: error: 'LSM_ATTR_UNDEF' undeclared (first use in this function)
     516 |         return LSM_ATTR_UNDEF;
         |                ^~~~~~~~~~~~~~
   include/linux/security.h:516:16: note: each undeclared identifier is reported only once for each function it appears in
   net/socket.c: In function '__sys_getsockopt':
   net/socket.c:2297:13: warning: variable 'max_optlen' set but not used [-Wunused-but-set-variable]
    2297 |         int max_optlen;
         |             ^~~~~~~~~~
..


vim +/LSM_ATTR_UNDEF +516 include/linux/security.h

   513	
   514	static inline u64 lsm_name_to_attr(const char *name)
   515	{
 > 516		return LSM_ATTR_UNDEF;
   517	}
   518
kernel test robot April 29, 2023, 2:37 a.m. UTC | #2
Hi Casey,

kernel test robot noticed the following build errors:

[auto build test ERROR on tip/perf/core]
[also build test ERROR on acme/perf/core shuah-kselftest/next shuah-kselftest/fixes v6.3]
[cannot apply to linus/master next-20230428]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Casey-Schaufler/LSM-Maintain-a-table-of-LSM-attribute-data/20230429-053458
base:   tip/perf/core
patch link:    https://lore.kernel.org/r/20230428203417.159874-8-casey%40schaufler-ca.com
patch subject: [PATCH v10 07/11] LSM: Helpers for attribute names and filling lsm_ctx
config: riscv-randconfig-r003-20230428 (https://download.01.org/0day-ci/archive/20230429/202304291044.WjF3wC86-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project 437b7602e4a998220871de78afcb020b9c14a661)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/9830f4776196e33bee604b8ce3339177f8fd37f8
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Casey-Schaufler/LSM-Maintain-a-table-of-LSM-attribute-data/20230429-053458
        git checkout 9830f4776196e33bee604b8ce3339177f8fd37f8
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv prepare

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304291044.WjF3wC86-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from arch/riscv/kernel/asm-offsets.c:12:
   In file included from arch/riscv/include/asm/kvm_host.h:21:
   In file included from arch/riscv/include/asm/kvm_vcpu_pmu.h:12:
   In file included from include/linux/perf/riscv_pmu.h:12:
   In file included from include/linux/perf_event.h:62:
>> include/linux/security.h:516:9: error: use of undeclared identifier 'LSM_ATTR_UNDEF'
           return LSM_ATTR_UNDEF;
                  ^
   1 error generated.
   make[2]: *** [scripts/Makefile.build:114: arch/riscv/kernel/asm-offsets.s] Error 1
   make[2]: Target 'prepare' not remade because of errors.
   make[1]: *** [Makefile:1286: prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [Makefile:226: __sub-make] Error 2
   make: Target 'prepare' not remade because of errors.


vim +/LSM_ATTR_UNDEF +516 include/linux/security.h

   513	
   514	static inline u64 lsm_name_to_attr(const char *name)
   515	{
 > 516		return LSM_ATTR_UNDEF;
   517	}
   518
Paul Moore June 7, 2023, 10:32 p.m. UTC | #3
On Apr 28, 2023 kernel test robot <lkp@intel.com> wrote:
> 
> Add lsm_name_to_attr(), which translates a text string to a
> LSM_ATTR value if one is available.
> 
> Add lsm_fill_user_ctx(), which fills a struct lsm_ctx, including
> the trailing attribute value. The .len value is padded to a multiple
> of 64 bits for alignment.
> 
> All are used in module specific components of LSM system calls.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/security.h | 13 ++++++++++++
>  security/lsm_syscalls.c  | 24 ++++++++++++++++++++++
>  security/security.c      | 44 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+)

...

> diff --git a/security/security.c b/security/security.c
> index 94b78bfd06b9..8c877d639cae 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -761,6 +761,50 @@ static int lsm_superblock_alloc(struct super_block *sb)
>  	return 0;
>  }
>  
> +/**
> + * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
> + * @ctx: an LSM context to be filled
> + * @context: the new context value
> + * @context_size: the size of the new context value
> + * @id: LSM id
> + * @flags: LSM defined flags
> + *
> + * Fill all of the fields in a user space lsm_ctx structure.
> + * Caller is assumed to have verified that @ctx has enough space
> + * for @context.
> + *
> + * The total length is padded to a multiple of 64 bits to
> + * accomodate possible alignment issues.
> + *
> + * Returns 0 on success, -EFAULT on a copyout error, -ENOMEM
> + * if memory can't be allocated.
> + */
> +int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
> +		      size_t context_size, u64 id, u64 flags)
> +{
> +	struct lsm_ctx *lctx;
> +	size_t locallen = ALIGN(struct_size(lctx, ctx, context_size), 8);

See my comment in 7/11 regarding the alignment calculation here.

> +	int rc = 0;
> +
> +	lctx = kzalloc(locallen, GFP_KERNEL);
> +	if (lctx == NULL)
> +		return -ENOMEM;
> +
> +	lctx->id = id;
> +	lctx->flags = flags;
> +	lctx->ctx_len = context_size;
> +	lctx->len = locallen;
> +
> +	memcpy(lctx->ctx, context, context_size);
> +
> +	if (copy_to_user(ctx, lctx, locallen))
> +		rc = -EFAULT;
> +
> +	kfree(lctx);
> +
> +	return rc;
> +}
> +
>  /*
>   * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
>   * can be accessed with:
> -- 
> 2.39.2

--
paul-moore.com
Serge E. Hallyn June 15, 2023, 1:19 p.m. UTC | #4
On Fri, Apr 28, 2023 at 01:34:13PM -0700, Casey Schaufler wrote:
> Add lsm_name_to_attr(), which translates a text string to a
> LSM_ATTR value if one is available.
> 
> Add lsm_fill_user_ctx(), which fills a struct lsm_ctx, including
> the trailing attribute value. The .len value is padded to a multiple
> of 64 bits for alignment.
> 
> All are used in module specific components of LSM system calls.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>

Reviewed-by: Serge E. Hallyn <serge@hallyn.com>

> ---
>  include/linux/security.h | 13 ++++++++++++
>  security/lsm_syscalls.c  | 24 ++++++++++++++++++++++
>  security/security.c      | 44 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 81 insertions(+)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 806bff425af9..36ace59f9171 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -263,6 +263,7 @@ int unregister_blocking_lsm_notifier(struct notifier_block *nb);
>  /* prototypes */
>  extern int security_init(void);
>  extern int early_security_init(void);
> +extern u64 lsm_name_to_attr(const char *name);
>  
>  /* Security operations */
>  int security_binder_set_context_mgr(const struct cred *mgr);
> @@ -491,6 +492,8 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
>  int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
>  int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
>  int security_locked_down(enum lockdown_reason what);
> +int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
> +		      size_t context_size, u64 id, u64 flags);
>  #else /* CONFIG_SECURITY */
>  
>  static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
> @@ -508,6 +511,11 @@ static inline  int unregister_blocking_lsm_notifier(struct notifier_block *nb)
>  	return 0;
>  }
>  
> +static inline u64 lsm_name_to_attr(const char *name)
> +{
> +	return LSM_ATTR_UNDEF;
> +}
> +
>  static inline void security_free_mnt_opts(void **mnt_opts)
>  {
>  }
> @@ -1420,6 +1428,11 @@ static inline int security_locked_down(enum lockdown_reason what)
>  {
>  	return 0;
>  }
> +static inline int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
> +				    size_t context_size, u64 id, u64 flags)
> +{
> +	return -EOPNOTSUPP;
> +}
>  #endif	/* CONFIG_SECURITY */
>  
>  #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
> diff --git a/security/lsm_syscalls.c b/security/lsm_syscalls.c
> index b89cccb2f123..0b225adfe5f7 100644
> --- a/security/lsm_syscalls.c
> +++ b/security/lsm_syscalls.c
> @@ -17,6 +17,30 @@
>  #include <linux/lsm_hooks.h>
>  #include <uapi/linux/lsm.h>
>  
> +/**
> + * lsm_name_to_attr - map an LSM attribute name to its ID
> + * @name: name of the attribute
> + *
> + * Returns the LSM attribute value associated with @name, or 0 if
> + * there is no mapping.
> + */
> +u64 lsm_name_to_attr(const char *name)
> +{
> +	if (!strcmp(name, "current"))
> +		return LSM_ATTR_CURRENT;
> +	if (!strcmp(name, "exec"))
> +		return LSM_ATTR_EXEC;
> +	if (!strcmp(name, "fscreate"))
> +		return LSM_ATTR_FSCREATE;
> +	if (!strcmp(name, "keycreate"))
> +		return LSM_ATTR_KEYCREATE;
> +	if (!strcmp(name, "prev"))
> +		return LSM_ATTR_PREV;
> +	if (!strcmp(name, "sockcreate"))
> +		return LSM_ATTR_SOCKCREATE;
> +	return LSM_ATTR_UNDEF;
> +}
> +
>  /**
>   * sys_lsm_set_self_attr - Set current task's security module attribute
>   * @attr: which attribute to set
> diff --git a/security/security.c b/security/security.c
> index 94b78bfd06b9..8c877d639cae 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -761,6 +761,50 @@ static int lsm_superblock_alloc(struct super_block *sb)
>  	return 0;
>  }
>  
> +/**
> + * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
> + * @ctx: an LSM context to be filled
> + * @context: the new context value
> + * @context_size: the size of the new context value
> + * @id: LSM id
> + * @flags: LSM defined flags
> + *
> + * Fill all of the fields in a user space lsm_ctx structure.
> + * Caller is assumed to have verified that @ctx has enough space
> + * for @context.
> + *
> + * The total length is padded to a multiple of 64 bits to
> + * accomodate possible alignment issues.
> + *
> + * Returns 0 on success, -EFAULT on a copyout error, -ENOMEM
> + * if memory can't be allocated.
> + */
> +int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
> +		      size_t context_size, u64 id, u64 flags)
> +{
> +	struct lsm_ctx *lctx;
> +	size_t locallen = ALIGN(struct_size(lctx, ctx, context_size), 8);
> +	int rc = 0;
> +
> +	lctx = kzalloc(locallen, GFP_KERNEL);
> +	if (lctx == NULL)
> +		return -ENOMEM;
> +
> +	lctx->id = id;
> +	lctx->flags = flags;
> +	lctx->ctx_len = context_size;
> +	lctx->len = locallen;
> +
> +	memcpy(lctx->ctx, context, context_size);
> +
> +	if (copy_to_user(ctx, lctx, locallen))
> +		rc = -EFAULT;
> +
> +	kfree(lctx);
> +
> +	return rc;
> +}
> +
>  /*
>   * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
>   * can be accessed with:
> -- 
> 2.39.2
>
Serge E. Hallyn June 15, 2023, 1:27 p.m. UTC | #5
On Fri, Apr 28, 2023 at 01:34:13PM -0700, Casey Schaufler wrote:
> Add lsm_name_to_attr(), which translates a text string to a
> LSM_ATTR value if one is available.
> 
> Add lsm_fill_user_ctx(), which fills a struct lsm_ctx, including
> the trailing attribute value. The .len value is padded to a multiple
> of 64 bits for alignment.
> 
> All are used in module specific components of LSM system calls.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>

(I assume you have a patch queued up for the undefined errors?)
diff mbox series

Patch

diff --git a/include/linux/security.h b/include/linux/security.h
index 806bff425af9..36ace59f9171 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -263,6 +263,7 @@  int unregister_blocking_lsm_notifier(struct notifier_block *nb);
 /* prototypes */
 extern int security_init(void);
 extern int early_security_init(void);
+extern u64 lsm_name_to_attr(const char *name);
 
 /* Security operations */
 int security_binder_set_context_mgr(const struct cred *mgr);
@@ -491,6 +492,8 @@  int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
 int security_locked_down(enum lockdown_reason what);
+int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
+		      size_t context_size, u64 id, u64 flags);
 #else /* CONFIG_SECURITY */
 
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
@@ -508,6 +511,11 @@  static inline  int unregister_blocking_lsm_notifier(struct notifier_block *nb)
 	return 0;
 }
 
+static inline u64 lsm_name_to_attr(const char *name)
+{
+	return LSM_ATTR_UNDEF;
+}
+
 static inline void security_free_mnt_opts(void **mnt_opts)
 {
 }
@@ -1420,6 +1428,11 @@  static inline int security_locked_down(enum lockdown_reason what)
 {
 	return 0;
 }
+static inline int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
+				    size_t context_size, u64 id, u64 flags)
+{
+	return -EOPNOTSUPP;
+}
 #endif	/* CONFIG_SECURITY */
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
diff --git a/security/lsm_syscalls.c b/security/lsm_syscalls.c
index b89cccb2f123..0b225adfe5f7 100644
--- a/security/lsm_syscalls.c
+++ b/security/lsm_syscalls.c
@@ -17,6 +17,30 @@ 
 #include <linux/lsm_hooks.h>
 #include <uapi/linux/lsm.h>
 
+/**
+ * lsm_name_to_attr - map an LSM attribute name to its ID
+ * @name: name of the attribute
+ *
+ * Returns the LSM attribute value associated with @name, or 0 if
+ * there is no mapping.
+ */
+u64 lsm_name_to_attr(const char *name)
+{
+	if (!strcmp(name, "current"))
+		return LSM_ATTR_CURRENT;
+	if (!strcmp(name, "exec"))
+		return LSM_ATTR_EXEC;
+	if (!strcmp(name, "fscreate"))
+		return LSM_ATTR_FSCREATE;
+	if (!strcmp(name, "keycreate"))
+		return LSM_ATTR_KEYCREATE;
+	if (!strcmp(name, "prev"))
+		return LSM_ATTR_PREV;
+	if (!strcmp(name, "sockcreate"))
+		return LSM_ATTR_SOCKCREATE;
+	return LSM_ATTR_UNDEF;
+}
+
 /**
  * sys_lsm_set_self_attr - Set current task's security module attribute
  * @attr: which attribute to set
diff --git a/security/security.c b/security/security.c
index 94b78bfd06b9..8c877d639cae 100644
--- a/security/security.c
+++ b/security/security.c
@@ -761,6 +761,50 @@  static int lsm_superblock_alloc(struct super_block *sb)
 	return 0;
 }
 
+/**
+ * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
+ * @ctx: an LSM context to be filled
+ * @context: the new context value
+ * @context_size: the size of the new context value
+ * @id: LSM id
+ * @flags: LSM defined flags
+ *
+ * Fill all of the fields in a user space lsm_ctx structure.
+ * Caller is assumed to have verified that @ctx has enough space
+ * for @context.
+ *
+ * The total length is padded to a multiple of 64 bits to
+ * accomodate possible alignment issues.
+ *
+ * Returns 0 on success, -EFAULT on a copyout error, -ENOMEM
+ * if memory can't be allocated.
+ */
+int lsm_fill_user_ctx(struct lsm_ctx __user *ctx, void *context,
+		      size_t context_size, u64 id, u64 flags)
+{
+	struct lsm_ctx *lctx;
+	size_t locallen = ALIGN(struct_size(lctx, ctx, context_size), 8);
+	int rc = 0;
+
+	lctx = kzalloc(locallen, GFP_KERNEL);
+	if (lctx == NULL)
+		return -ENOMEM;
+
+	lctx->id = id;
+	lctx->flags = flags;
+	lctx->ctx_len = context_size;
+	lctx->len = locallen;
+
+	memcpy(lctx->ctx, context, context_size);
+
+	if (copy_to_user(ctx, lctx, locallen))
+		rc = -EFAULT;
+
+	kfree(lctx);
+
+	return rc;
+}
+
 /*
  * The default value of the LSM hook is defined in linux/lsm_hook_defs.h and
  * can be accessed with: