Message ID | 20230222200838.8149-5-casey@schaufler-ca.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Paul Moore |
Headers | show |
Series | LSM: Three basic syscalls | expand |
Hi Casey, I love your patch! Yet something to improve: [auto build test ERROR on tip/perf/core] [also build test ERROR on acme/perf/core shuah-kselftest/next shuah-kselftest/fixes v6.2] [cannot apply to linus/master next-20230222] [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/20230223-050902 patch link: https://lore.kernel.org/r/20230222200838.8149-5-casey%40schaufler-ca.com patch subject: [PATCH v6 04/11] LSM: syscalls for current process attributes config: um-x86_64_defconfig (https://download.01.org/0day-ci/archive/20230223/202302231247.4CJvLv71-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-8) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/04ba82c1bd629c2114ad851b4723d6e8b0f9d08f 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/20230223-050902 git checkout 04ba82c1bd629c2114ad851b4723d6e8b0f9d08f # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=um SUBARCH=x86_64 olddefconfig make W=1 O=build_dir ARCH=um SUBARCH=x86_64 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/202302231247.4CJvLv71-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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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 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:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- In file included from init/do_mounts.c:9: >> include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ In file included from init/do_mounts.c:9: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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/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:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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/syscalls_64.c:10: >> include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ arch/x86/um/syscalls_64.c:84:6: warning: no previous prototype for 'arch_switch_to' [-Wmissing-prototypes] 84 | void arch_switch_to(struct task_struct *to) | ^~~~~~~~~~~~~~ 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/syscalls_64.c:10: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- In file included from kernel/fork.c:51: >> include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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:862:20: warning: no previous prototype for 'arch_task_cache_init' [-Wmissing-prototypes] 862 | void __init __weak arch_task_cache_init(void) { } | ^~~~~~~~~~~~~~~~~~~~ kernel/fork.c:957:12: warning: no previous prototype for 'arch_dup_task_struct' [-Wmissing-prototypes] 957 | int __weak arch_dup_task_struct(struct task_struct *dst, | ^~~~~~~~~~~~~~~~~~~~ In file included from kernel/fork.c:51: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ kernel/exit.c:1901:13: warning: no previous prototype for 'abort' [-Wmissing-prototypes] 1901 | __weak void abort(void) | ^~~~~ 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:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:20, from kernel/kallsyms.c:25: >> include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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/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:20, from kernel/kallsyms.c:25: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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/fs_context.h:14, from include/linux/pseudo_fs.h:4, from fs/pipe.c:17: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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/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:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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 io_uring/io_uring.c:45: >> include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ io_uring/io_uring.c: In function '__io_submit_flush_completions': io_uring/io_uring.c:1448:40: warning: variable 'prev' set but not used [-Wunused-but-set-variable] 1448 | struct io_wq_work_node *node, *prev; | ^~~~ 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 io_uring/io_uring.c:45: io_uring/io_uring.c: At top level: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ -- 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:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ 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/tcp.h:19, from include/linux/ipv6.h:93, from include/net/addrconf.h:52, from lib/vsprintf.c:40: lib/vsprintf.c: At top level: include/linux/security.h:1353:19: warning: 'security_getselfattr' declared 'static' but never defined [-Wunused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ include/linux/security.h:1360:19: warning: 'security_setselfattr' declared 'static' but never defined [-Wunused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ .. vim +1356 include/linux/security.h 1352 1353 static inline int security_getselfattr(u64 __user attr, 1354 struct lsm_ctx __user *ctx, 1355 size_t __user *size); > 1356 { 1357 return -EINVAL; 1358 } 1359
Hi Casey, I love your patch! Yet something to improve: [auto build test ERROR on tip/perf/core] [also build test ERROR on acme/perf/core shuah-kselftest/next shuah-kselftest/fixes v6.2] [cannot apply to linus/master next-20230223] [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/20230223-050902 patch link: https://lore.kernel.org/r/20230222200838.8149-5-casey%40schaufler-ca.com patch subject: [PATCH v6 04/11] LSM: syscalls for current process attributes config: powerpc-allnoconfig (https://download.01.org/0day-ci/archive/20230223/202302231639.YHlfovm7-lkp@intel.com/config) compiler: powerpc-linux-gcc (GCC) 12.1.0 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 # https://github.com/intel-lab-lkp/linux/commit/04ba82c1bd629c2114ad851b4723d6e8b0f9d08f 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/20230223-050902 git checkout 04ba82c1bd629c2114ad851b4723d6e8b0f9d08f # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash arch/powerpc/kernel/ 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/202302231639.YHlfovm7-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 arch/powerpc/kernel/syscalls.c:19: include/linux/security.h:1356:1: error: expected identifier or '(' before '{' token 1356 | { | ^ include/linux/security.h:1363:1: error: expected identifier or '(' before '{' token 1363 | { | ^ >> include/linux/security.h:1353:19: error: 'security_getselfattr' declared 'static' but never defined [-Werror=unused-function] 1353 | static inline int security_getselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ >> include/linux/security.h:1360:19: error: 'security_setselfattr' declared 'static' but never defined [-Werror=unused-function] 1360 | static inline int security_setselfattr(u64 __user attr, | ^~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors vim +1353 include/linux/security.h 1352 > 1353 static inline int security_getselfattr(u64 __user attr, 1354 struct lsm_ctx __user *ctx, 1355 size_t __user *size); 1356 { 1357 return -EINVAL; 1358 } 1359 > 1360 static inline int security_setselfattr(u64 __user attr, 1361 struct lsm_ctx __user *ctx, 1362 size_t __user size); 1363 { 1364 return -EINVAL; 1365 } 1366
Hi Casey, I love your patch! Perhaps something to improve: [auto build test WARNING on tip/perf/core] [also build test WARNING on acme/perf/core shuah-kselftest/next shuah-kselftest/fixes v6.2] [cannot apply to linus/master next-20230223] [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/20230223-050902 patch link: https://lore.kernel.org/r/20230222200838.8149-5-casey%40schaufler-ca.com patch subject: [PATCH v6 04/11] LSM: syscalls for current process attributes config: x86_64-rhel-8.3 (https://download.01.org/0day-ci/archive/20230223/202302232007.dcqfhRnw-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-8) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/04ba82c1bd629c2114ad851b4723d6e8b0f9d08f 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/20230223-050902 git checkout 04ba82c1bd629c2114ad851b4723d6e8b0f9d08f # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=x86_64 olddefconfig make W=1 O=build_dir ARCH=x86_64 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/202302232007.dcqfhRnw-lkp@intel.com/ All warnings (new ones prefixed by >>): >> security/lsm_syscalls.c:61:5: warning: no previous prototype for 'lsm_name_to_attr' [-Wmissing-prototypes] 61 | u64 lsm_name_to_attr(const char *name) | ^~~~~~~~~~~~~~~~ vim +/lsm_name_to_attr +61 security/lsm_syscalls.c 51 52 /** 53 * lsm_name_to_attr - map an LSM attribute name to its ID 54 * @name: name of the attribute 55 * 56 * Look the given @name up in the table of know attribute names. 57 * 58 * Returns the LSM attribute value associated with @name, or 0 if 59 * there is no mapping. 60 */ > 61 u64 lsm_name_to_attr(const char *name) 62 { 63 int i; 64 65 for (i = 0; i < ARRAY_SIZE(lsm_attr_names); i++) 66 if (!strcmp(name, lsm_attr_names[i].name)) 67 return lsm_attr_names[i].attrs; 68 return 0; 69 } 70
On Wed, Feb 22, 2023, at 21:08, Casey Schaufler wrote: > +/** > + * sys_lsm_set_self_attr - Set current task's security module attribute > + * @ctx: the LSM contexts > + * @size: size of @ctx > + * @flags: which attribute to set > + * > + * Sets the calling task's LSM context. On success this function > + * returns 0. If the attribute specified cannot be set a negative > + * value indicating the reason for the error is returned. > + */ > +SYSCALL_DEFINE3(lsm_set_self_attr, struct lsm_ctx __user *, ctx, > size_t __user, > + size, u64, flags) > +{ > + return security_setselfattr(flags, ctx, size); > +} > + > +SYSCALL_DEFINE3(lsm_get_self_attr, struct lsm_ctx __user *, ctx, > + size_t __user *, size, u64, flags) > +{ > + return security_getselfattr(flags, ctx, size); > +} As with the other patch I commented on, I think it's better to use a 32-bit 'flags' argument here, to make this work for compat tasks. Arnd
On 22/02/2023 21:08, Casey Schaufler wrote: > Create a system call lsm_get_self_attr() to provide the security > module maintained attributes of the current process. > Create a system call lsm_set_self_attr() to set a security > module maintained attribute of the current process. > Historically these attributes have been exposed to user space via > entries in procfs under /proc/self/attr. > > The attribute value is provided in a lsm_ctx structure. The structure > identifys the size of the attribute, and the attribute value. The format > of the attribute value is defined by the security module. A flags field > is included for LSM specific information. It is currently unused and must > be 0. The total size of the data, including the lsm_ctx structure and any > padding, is maintained as well. > > struct lsm_ctx { > __u64 id; > __u64 flags; > __u64 len; > __u64 ctx_len; > __u8 ctx[]; > }; > > Two new LSM hooks are used to interface with the LSMs. > security_getselfattr() collects the lsm_ctx values from the > LSMs that support the hook, accounting for space requirements. > security_setselfattr() identifies which LSM the attribute is > intended for and passes it along. > > Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> > --- > Documentation/userspace-api/lsm.rst | 15 ++++ > include/linux/lsm_hook_defs.h | 4 ++ > include/linux/lsm_hooks.h | 9 +++ > include/linux/security.h | 19 +++++ > include/linux/syscalls.h | 4 ++ > include/uapi/linux/lsm.h | 33 +++++++++ > kernel/sys_ni.c | 4 ++ > security/Makefile | 1 + > security/lsm_syscalls.c | 104 ++++++++++++++++++++++++++++ > security/security.c | 82 ++++++++++++++++++++++ > 10 files changed, 275 insertions(+) > create mode 100644 security/lsm_syscalls.c > [...] > +/** > + * security_setselfattr - Set an LSM attribute on the current process. > + * @attr: which attribute to return > + * @ctx: the user-space source for the information > + * @size: the size of the data > + * > + * Set an LSM attribute for the current process. The LSM, attribute > + * and new value are included in @ctx. > + * > + * Returns 0 on seccess, an LSM specific value on failure. > + */ > +int security_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx, > + size_t __user size) > +{ > + struct security_hook_list *hp; > + struct lsm_ctx lctx; > + > + if (size < sizeof(*ctx)) If the lsm_ctx struct could grow in the future, we should check the size of the struct to the last field for compatibility reasons, see Landlock's copy_min_struct_from_user(). > + return -EINVAL; > + if (copy_from_user(&lctx, ctx, sizeof(*ctx))) > + return -EFAULT; > + > + hlist_for_each_entry(hp, &security_hook_heads.setselfattr, list) > + if ((hp->lsmid->id) == lctx.id) > + return hp->hook.setselfattr(attr, ctx, size); > + > + return LSM_RET_DEFAULT(setselfattr); > +} > + > int security_getprocattr(struct task_struct *p, int lsmid, const char *name, > char **value) > {
Let's say an LSM need to pass a file descriptor instead of a text value. Would that be possible or would it need to use another interface? On 22/02/2023 21:08, Casey Schaufler wrote: > Create a system call lsm_get_self_attr() to provide the security > module maintained attributes of the current process. > Create a system call lsm_set_self_attr() to set a security > module maintained attribute of the current process. > Historically these attributes have been exposed to user space via > entries in procfs under /proc/self/attr. > > The attribute value is provided in a lsm_ctx structure. The structure > identifys the size of the attribute, and the attribute value. The format > of the attribute value is defined by the security module. A flags field > is included for LSM specific information. It is currently unused and must > be 0. The total size of the data, including the lsm_ctx structure and any > padding, is maintained as well. > > struct lsm_ctx { > __u64 id; > __u64 flags; > __u64 len; > __u64 ctx_len; > __u8 ctx[]; > }; > > Two new LSM hooks are used to interface with the LSMs. > security_getselfattr() collects the lsm_ctx values from the > LSMs that support the hook, accounting for space requirements. > security_setselfattr() identifies which LSM the attribute is > intended for and passes it along.
* Casey Schaufler: > Create a system call lsm_get_self_attr() to provide the security > module maintained attributes of the current process. Is it really the current process, or the current thread? > diff --git a/include/uapi/linux/lsm.h b/include/uapi/linux/lsm.h > index 523748cae615..7850fed28998 100644 > --- a/include/uapi/linux/lsm.h > +++ b/include/uapi/linux/lsm.h > @@ -9,6 +9,39 @@ > #ifndef _UAPI_LINUX_LSM_H > #define _UAPI_LINUX_LSM_H > > +#include <linux/types.h> > +#include <linux/unistd.h> > + > +/** > + * struct lsm_ctx - LSM context information > + * @id: the LSM id number, see LSM_ID_XXX > + * @flags: LSM specific flags > + * @len: length of the lsm_ctx struct, @ctx and any other data or padding > + * @ctx_len: the size of @ctx > + * @ctx: the LSM context value > + * > + * The @len field MUST be equal to the size of the lsm_ctx struct > + * plus any additional padding and/or data placed after @ctx. > + * > + * In all cases @ctx_len MUST be equal to the length of @ctx. > + * If @ctx is a string value it should be nul terminated with > + * @ctx_len equal to `strlen(@ctx) + 1`. Binary values are > + * supported. > + * > + * The @flags and @ctx fields SHOULD only be interpreted by the > + * LSM specified by @id; they MUST be set to zero/0 when not used. > + */ > +struct lsm_ctx { > + __u64 id; > + __u64 flags; > + __u64 len; > + __u64 ctx_len; > + __u8 ctx[]; > +}; The documentation seems to be written from the LSM point of view, not the application point of view. As far as I understand it, the LSM writes to the ctx member, not the application. Thanks, Florian
On 3/7/2023 3:56 AM, Mickaël Salaün wrote: > Let's say an LSM need to pass a file descriptor instead of a text > value. Would that be possible or would it need to use another interface? > > > On 22/02/2023 21:08, Casey Schaufler wrote: >> Create a system call lsm_get_self_attr() to provide the security >> module maintained attributes of the current process. >> Create a system call lsm_set_self_attr() to set a security >> module maintained attribute of the current process. >> Historically these attributes have been exposed to user space via >> entries in procfs under /proc/self/attr. >> >> The attribute value is provided in a lsm_ctx structure. The structure >> identifys the size of the attribute, and the attribute value. The format >> of the attribute value is defined by the security module. A flags field >> is included for LSM specific information. It is currently unused and >> must >> be 0. The total size of the data, including the lsm_ctx structure and >> any >> padding, is maintained as well. >> >> struct lsm_ctx { >> __u64 id; >> __u64 flags; >> __u64 len; >> __u64 ctx_len; >> __u8 ctx[]; >> }; >> >> Two new LSM hooks are used to interface with the LSMs. >> security_getselfattr() collects the lsm_ctx values from the >> LSMs that support the hook, accounting for space requirements. >> security_setselfattr() identifies which LSM the attribute is >> intended for and passes it along.
On 3/7/2023 3:56 AM, Mickaël Salaün wrote: > Let's say an LSM need to pass a file descriptor instead of a text > value. Would that be possible or would it need to use another interface? You could use this interface. LSM_ATTR_MAGICFD would have a ctx_len = sizeof(fd) and the value in ctx. The underlying plumbing is another matter entirely. It's likely you'd need to provide more information in the ctx than the fd, but I couldn't say what it would be, and I won't speculate. I would not advocate such a use, as I am not now nor have ever been a fan of passed file descriptors. > > > On 22/02/2023 21:08, Casey Schaufler wrote: >> Create a system call lsm_get_self_attr() to provide the security >> module maintained attributes of the current process. >> Create a system call lsm_set_self_attr() to set a security >> module maintained attribute of the current process. >> Historically these attributes have been exposed to user space via >> entries in procfs under /proc/self/attr. >> >> The attribute value is provided in a lsm_ctx structure. The structure >> identifys the size of the attribute, and the attribute value. The format >> of the attribute value is defined by the security module. A flags field >> is included for LSM specific information. It is currently unused and >> must >> be 0. The total size of the data, including the lsm_ctx structure and >> any >> padding, is maintained as well. >> >> struct lsm_ctx { >> __u64 id; >> __u64 flags; >> __u64 len; >> __u64 ctx_len; >> __u8 ctx[]; >> }; >> >> Two new LSM hooks are used to interface with the LSMs. >> security_getselfattr() collects the lsm_ctx values from the >> LSMs that support the hook, accounting for space requirements. >> security_setselfattr() identifies which LSM the attribute is >> intended for and passes it along.
On 3/7/2023 3:51 AM, Mickaël Salaün wrote: > > On 22/02/2023 21:08, Casey Schaufler wrote: >> Create a system call lsm_get_self_attr() to provide the security >> module maintained attributes of the current process. >> Create a system call lsm_set_self_attr() to set a security >> module maintained attribute of the current process. >> Historically these attributes have been exposed to user space via >> entries in procfs under /proc/self/attr. >> >> The attribute value is provided in a lsm_ctx structure. The structure >> identifys the size of the attribute, and the attribute value. The format >> of the attribute value is defined by the security module. A flags field >> is included for LSM specific information. It is currently unused and >> must >> be 0. The total size of the data, including the lsm_ctx structure and >> any >> padding, is maintained as well. >> >> struct lsm_ctx { >> __u64 id; >> __u64 flags; >> __u64 len; >> __u64 ctx_len; >> __u8 ctx[]; >> }; >> >> Two new LSM hooks are used to interface with the LSMs. >> security_getselfattr() collects the lsm_ctx values from the >> LSMs that support the hook, accounting for space requirements. >> security_setselfattr() identifies which LSM the attribute is >> intended for and passes it along. >> >> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> >> --- >> Documentation/userspace-api/lsm.rst | 15 ++++ >> include/linux/lsm_hook_defs.h | 4 ++ >> include/linux/lsm_hooks.h | 9 +++ >> include/linux/security.h | 19 +++++ >> include/linux/syscalls.h | 4 ++ >> include/uapi/linux/lsm.h | 33 +++++++++ >> kernel/sys_ni.c | 4 ++ >> security/Makefile | 1 + >> security/lsm_syscalls.c | 104 ++++++++++++++++++++++++++++ >> security/security.c | 82 ++++++++++++++++++++++ >> 10 files changed, 275 insertions(+) >> create mode 100644 security/lsm_syscalls.c >> > > [...] > >> +/** >> + * security_setselfattr - Set an LSM attribute on the current process. >> + * @attr: which attribute to return >> + * @ctx: the user-space source for the information >> + * @size: the size of the data >> + * >> + * Set an LSM attribute for the current process. The LSM, attribute >> + * and new value are included in @ctx. >> + * >> + * Returns 0 on seccess, an LSM specific value on failure. >> + */ >> +int security_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx, >> + size_t __user size) >> +{ >> + struct security_hook_list *hp; >> + struct lsm_ctx lctx; >> + >> + if (size < sizeof(*ctx)) > > If the lsm_ctx struct could grow in the future, we should check the > size of the struct to the last field for compatibility reasons, see > Landlock's copy_min_struct_from_user(). Because the lsm_ctx structure ends with the variable length context there's no way to append new fields to it. The structure can't grow. > > >> + return -EINVAL; >> + if (copy_from_user(&lctx, ctx, sizeof(*ctx))) >> + return -EFAULT; >> + >> + hlist_for_each_entry(hp, &security_hook_heads.setselfattr, list) >> + if ((hp->lsmid->id) == lctx.id) >> + return hp->hook.setselfattr(attr, ctx, size); >> + >> + return LSM_RET_DEFAULT(setselfattr); >> +} >> + >> int security_getprocattr(struct task_struct *p, int lsmid, const >> char *name, >> char **value) >> {
On Wed, Mar 8, 2023 at 9:30 PM Casey Schaufler <casey@schaufler-ca.com> wrote: > On 3/7/2023 3:51 AM, Mickaël Salaün wrote: > > > > On 22/02/2023 21:08, Casey Schaufler wrote: > >> Create a system call lsm_get_self_attr() to provide the security > >> module maintained attributes of the current process. > >> Create a system call lsm_set_self_attr() to set a security > >> module maintained attribute of the current process. > >> Historically these attributes have been exposed to user space via > >> entries in procfs under /proc/self/attr. > >> > >> The attribute value is provided in a lsm_ctx structure. The structure > >> identifys the size of the attribute, and the attribute value. The format > >> of the attribute value is defined by the security module. A flags field > >> is included for LSM specific information. It is currently unused and > >> must > >> be 0. The total size of the data, including the lsm_ctx structure and > >> any > >> padding, is maintained as well. > >> > >> struct lsm_ctx { > >> __u64 id; > >> __u64 flags; > >> __u64 len; > >> __u64 ctx_len; > >> __u8 ctx[]; > >> }; > >> > >> Two new LSM hooks are used to interface with the LSMs. > >> security_getselfattr() collects the lsm_ctx values from the > >> LSMs that support the hook, accounting for space requirements. > >> security_setselfattr() identifies which LSM the attribute is > >> intended for and passes it along. > >> > >> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> > >> --- > >> Documentation/userspace-api/lsm.rst | 15 ++++ > >> include/linux/lsm_hook_defs.h | 4 ++ > >> include/linux/lsm_hooks.h | 9 +++ > >> include/linux/security.h | 19 +++++ > >> include/linux/syscalls.h | 4 ++ > >> include/uapi/linux/lsm.h | 33 +++++++++ > >> kernel/sys_ni.c | 4 ++ > >> security/Makefile | 1 + > >> security/lsm_syscalls.c | 104 ++++++++++++++++++++++++++++ > >> security/security.c | 82 ++++++++++++++++++++++ > >> 10 files changed, 275 insertions(+) > >> create mode 100644 security/lsm_syscalls.c > >> > > > > [...] > > > >> +/** > >> + * security_setselfattr - Set an LSM attribute on the current process. > >> + * @attr: which attribute to return > >> + * @ctx: the user-space source for the information > >> + * @size: the size of the data > >> + * > >> + * Set an LSM attribute for the current process. The LSM, attribute > >> + * and new value are included in @ctx. > >> + * > >> + * Returns 0 on seccess, an LSM specific value on failure. > >> + */ > >> +int security_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx, > >> + size_t __user size) > >> +{ > >> + struct security_hook_list *hp; > >> + struct lsm_ctx lctx; > >> + > >> + if (size < sizeof(*ctx)) > > > > If the lsm_ctx struct could grow in the future, we should check the > > size of the struct to the last field for compatibility reasons, see > > Landlock's copy_min_struct_from_user(). > > Because the lsm_ctx structure ends with the variable length context there's > no way to append new fields to it. The structure can't grow. The lsm_ctx can grow; that was one of the reasons for having both a @len and @ctx_len field in the struct, the other being padding. Of course any LSM wanting to place information beyond the end of @ctx will need to indicate that with a bit in the @flags field. Having said that, there are probably other ways to pass other data via a lsm_ctx struct, e.g. binary @ctx values, but I don't think we want to rule anything out at this point. Also, as a reminder, just because we *can* do something, doesn't mean we will do something. Any LSM that wants to pass something other than a string @ctx value will face a *lot* of scrutiny.
diff --git a/Documentation/userspace-api/lsm.rst b/Documentation/userspace-api/lsm.rst index 6ddf5506110b..b45e402302b3 100644 --- a/Documentation/userspace-api/lsm.rst +++ b/Documentation/userspace-api/lsm.rst @@ -48,6 +48,21 @@ creating socket objects. The proc filesystem provides this value in ``/proc/self/attr/sockcreate``. This is supported by the SELinux security module. +Kernel interface +================ + +Set a security attribute of the current process +-------------------------------------------------- + +.. kernel-doc:: security/lsm_syscalls.c + :identifiers: sys_lsm_set_self_attr + +Get the specified security attributes of the current process +-------------------------------------------------- + +.. kernel-doc:: security/lsm_syscalls.c + :identifiers: sys_lsm_get_self_attr + Additional documentation ======================== diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index ed6cb2ac55fa..a834bc2311bf 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -261,6 +261,10 @@ LSM_HOOK(int, 0, sem_semop, struct kern_ipc_perm *perm, struct sembuf *sops, LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb) LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry, struct inode *inode) +LSM_HOOK(int, -EOPNOTSUPP, getselfattr, u64 __user attr, + struct lsm_ctx __user *ctx, size_t *size) +LSM_HOOK(int, -EOPNOTSUPP, setselfattr, u64 __user attr, + struct lsm_ctx __user *ctx, size_t size) LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, char **value) LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 98acafc60f47..36cd1692b82b 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -25,6 +25,7 @@ #ifndef __LINUX_LSM_HOOKS_H #define __LINUX_LSM_HOOKS_H +#include <uapi/linux/lsm.h> #include <linux/security.h> #include <linux/init.h> #include <linux/rculist.h> @@ -503,6 +504,14 @@ * and writing the xattrs as this hook is merely a filter. * @d_instantiate: * Fill in @inode security information for a @dentry if allowed. + * @getselfattr: + * Read attribute @attr for the current process and store it into @ctx. + * Return 0 on success, -EOPNOTSUPP if the attribute is not supported, + * or another negative value otherwise. + * @setselfattr: + * Set attribute @attr for the current process. + * Return 0 on success, -EOPNOTSUPP if the attribute is not supported, + * or another negative value otherwise. * @getprocattr: * Read attribute @name for process @p and store it into @value if allowed. * Return the length of @value on success, a negative value otherwise. diff --git a/include/linux/security.h b/include/linux/security.h index 2d09e818a7d1..21971a635b6a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -60,6 +60,7 @@ struct fs_parameter; enum fs_value_type; struct watch; struct watch_notification; +struct lsm_ctx; /* Default (no) options for the capable function */ #define CAP_OPT_NONE 0x0 @@ -475,6 +476,10 @@ int security_sem_semctl(struct kern_ipc_perm *sma, int cmd); int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, unsigned nsops, int alter); void security_d_instantiate(struct dentry *dentry, struct inode *inode); +int security_getselfattr(u64 __user attr, struct lsm_ctx __user *ctx, + size_t __user *size); +int security_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx, + size_t __user size); int security_getprocattr(struct task_struct *p, int lsmid, const char *name, char **value); int security_setprocattr(int lsmid, const char *name, void *value, size_t size); @@ -1345,6 +1350,20 @@ static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) { } +static inline int security_getselfattr(u64 __user attr, + struct lsm_ctx __user *ctx, + size_t __user *size); +{ + return -EINVAL; +} + +static inline int security_setselfattr(u64 __user attr, + struct lsm_ctx __user *ctx, + size_t __user size); +{ + return -EINVAL; +} + static inline int security_getprocattr(struct task_struct *p, int lsmid, const char *name, char **value) { diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 33a0ee3bcb2e..1ef2a3de8ae0 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -71,6 +71,7 @@ struct clone_args; struct open_how; struct mount_attr; struct landlock_ruleset_attr; +struct lsm_ctx; enum landlock_rule_type; #include <linux/types.h> @@ -1058,6 +1059,9 @@ asmlinkage long sys_memfd_secret(unsigned int flags); asmlinkage long sys_set_mempolicy_home_node(unsigned long start, unsigned long len, unsigned long home_node, unsigned long flags); +asmlinkage long sys_lsm_get_self_attr(struct lsm_ctx *ctx, size_t *size, + __u64 flags); +asmlinkage long sys_lsm_set_self_attr(struct lsm_ctx *ctx, __u64 flags); /* * Architecture-specific system calls diff --git a/include/uapi/linux/lsm.h b/include/uapi/linux/lsm.h index 523748cae615..7850fed28998 100644 --- a/include/uapi/linux/lsm.h +++ b/include/uapi/linux/lsm.h @@ -9,6 +9,39 @@ #ifndef _UAPI_LINUX_LSM_H #define _UAPI_LINUX_LSM_H +#include <linux/types.h> +#include <linux/unistd.h> + +/** + * struct lsm_ctx - LSM context information + * @id: the LSM id number, see LSM_ID_XXX + * @flags: LSM specific flags + * @len: length of the lsm_ctx struct, @ctx and any other data or padding + * @ctx_len: the size of @ctx + * @ctx: the LSM context value + * + * The @len field MUST be equal to the size of the lsm_ctx struct + * plus any additional padding and/or data placed after @ctx. + * + * In all cases @ctx_len MUST be equal to the length of @ctx. + * If @ctx is a string value it should be nul terminated with + * @ctx_len equal to `strlen(@ctx) + 1`. Binary values are + * supported. + * + * The @flags and @ctx fields SHOULD only be interpreted by the + * LSM specified by @id; they MUST be set to zero/0 when not used. + */ +struct lsm_ctx { + __u64 id; + __u64 flags; + __u64 len; + __u64 ctx_len; + __u8 ctx[]; +}; + +#include <linux/types.h> +#include <linux/unistd.h> + /* * ID tokens to identify Linux Security Modules (LSMs) * diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 860b2dcf3ac4..d03c78ef1562 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -262,6 +262,10 @@ COND_SYSCALL_COMPAT(recvmsg); /* mm/nommu.c, also with MMU */ COND_SYSCALL(mremap); +/* security/lsm_syscalls.c */ +COND_SYSCALL(lsm_get_self_attr); +COND_SYSCALL(lsm_set_self_attr); + /* security/keys/keyctl.c */ COND_SYSCALL(add_key); COND_SYSCALL(request_key); diff --git a/security/Makefile b/security/Makefile index 18121f8f85cd..59f238490665 100644 --- a/security/Makefile +++ b/security/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_KEYS) += keys/ # always enable default capabilities obj-y += commoncap.o +obj-$(CONFIG_SECURITY) += lsm_syscalls.o obj-$(CONFIG_MMU) += min_addr.o # Object file lists diff --git a/security/lsm_syscalls.c b/security/lsm_syscalls.c new file mode 100644 index 000000000000..b89c4e7d009e --- /dev/null +++ b/security/lsm_syscalls.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * System calls implementing the Linux Security Module API. + * + * Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com> + * Copyright (C) 2022 Intel Corporation + */ + +#include <asm/current.h> +#include <linux/compiler_types.h> +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/security.h> +#include <linux/stddef.h> +#include <linux/syscalls.h> +#include <linux/types.h> +#include <linux/lsm_hooks.h> +#include <uapi/linux/lsm.h> + +struct attrs_map { + char *name; + int attrs; +}; + +static const struct attrs_map lsm_attr_names[] = { + { + .name = "current", + .attrs = LSM_ATTR_CURRENT, + }, + { + .name = "exec", + .attrs = LSM_ATTR_EXEC, + }, + { + .name = "fscreate", + .attrs = LSM_ATTR_FSCREATE, + }, + { + .name = "keycreate", + .attrs = LSM_ATTR_KEYCREATE, + }, + { + .name = "prev", + .attrs = LSM_ATTR_PREV, + }, + { + .name = "sockcreate", + .attrs = LSM_ATTR_SOCKCREATE, + }, +}; + +/** + * lsm_name_to_attr - map an LSM attribute name to its ID + * @name: name of the attribute + * + * Look the given @name up in the table of know attribute names. + * + * Returns the LSM attribute value associated with @name, or 0 if + * there is no mapping. + */ +u64 lsm_name_to_attr(const char *name) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(lsm_attr_names); i++) + if (!strcmp(name, lsm_attr_names[i].name)) + return lsm_attr_names[i].attrs; + return 0; +} + +/** + * sys_lsm_set_self_attr - Set current task's security module attribute + * @ctx: the LSM contexts + * @size: size of @ctx + * @flags: which attribute to set + * + * Sets the calling task's LSM context. On success this function + * returns 0. If the attribute specified cannot be set a negative + * value indicating the reason for the error is returned. + */ +SYSCALL_DEFINE3(lsm_set_self_attr, struct lsm_ctx __user *, ctx, size_t __user, + size, u64, flags) +{ + return security_setselfattr(flags, ctx, size); +} + +/** + * sys_lsm_get_self_attr - Return current task's security module attributes + * @ctx: the LSM contexts + * @size: size of @ctx, updated on return + * @flags: which attribute to return + * + * Returns the calling task's LSM contexts. On success this + * function returns the number of @ctx array elements. This value + * may be zero if there are no LSM contexts assigned. If @size is + * insufficient to contain the return data -E2BIG is returned and + * @size is set to the minimum required size. In all other cases + * a negative value indicating the error is returned. + */ +SYSCALL_DEFINE3(lsm_get_self_attr, struct lsm_ctx __user *, ctx, + size_t __user *, size, u64, flags) +{ + return security_getselfattr(flags, ctx, size); +} diff --git a/security/security.c b/security/security.c index 3308d7c8a20b..6823a6cb32a9 100644 --- a/security/security.c +++ b/security/security.c @@ -2167,6 +2167,88 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode) } EXPORT_SYMBOL(security_d_instantiate); +/** + * security_getselfattr - Read an LSM attribute of the current process. + * @attr: which attribute to return + * @ctx: the user-space destination for the information, or NULL + * @size: the size of space available to receive the data + * + * Returns the number of attributes found on success, negative value + * on error. @size is reset to the total size of the data. + * If @size is insufficient to contain the data -E2BIG is returned. + */ +int security_getselfattr(u64 __user attr, struct lsm_ctx __user *ctx, + size_t __user *size) +{ + struct security_hook_list *hp; + void __user *base = (void *)ctx; + size_t total = 0; + size_t this; + size_t left; + int count = 0; + int rc; + + if (attr == 0) + return -EINVAL; + if (size == NULL) + return -EINVAL; + if (get_user(left, size)) + return -EFAULT; + + hlist_for_each_entry(hp, &security_hook_heads.getselfattr, list) { + if ((hp->lsmid->attrs & attr) != attr) + continue; + this = left; + if (base) + ctx = (struct lsm_ctx __user *)(base + total); + rc = hp->hook.getselfattr(attr, ctx, &this); + if (rc == -E2BIG) + left = 0; + else if (rc == 0) + left -= this; + else + return rc; + total += this; + count++; + } + if (count == 0) + return LSM_RET_DEFAULT(getselfattr); + if (put_user(total, size)) + return -EFAULT; + if (rc) + return rc; + return count; +} + +/** + * security_setselfattr - Set an LSM attribute on the current process. + * @attr: which attribute to return + * @ctx: the user-space source for the information + * @size: the size of the data + * + * Set an LSM attribute for the current process. The LSM, attribute + * and new value are included in @ctx. + * + * Returns 0 on seccess, an LSM specific value on failure. + */ +int security_setselfattr(u64 __user attr, struct lsm_ctx __user *ctx, + size_t __user size) +{ + struct security_hook_list *hp; + struct lsm_ctx lctx; + + if (size < sizeof(*ctx)) + return -EINVAL; + if (copy_from_user(&lctx, ctx, sizeof(*ctx))) + return -EFAULT; + + hlist_for_each_entry(hp, &security_hook_heads.setselfattr, list) + if ((hp->lsmid->id) == lctx.id) + return hp->hook.setselfattr(attr, ctx, size); + + return LSM_RET_DEFAULT(setselfattr); +} + int security_getprocattr(struct task_struct *p, int lsmid, const char *name, char **value) {
Create a system call lsm_get_self_attr() to provide the security module maintained attributes of the current process. Create a system call lsm_set_self_attr() to set a security module maintained attribute of the current process. Historically these attributes have been exposed to user space via entries in procfs under /proc/self/attr. The attribute value is provided in a lsm_ctx structure. The structure identifys the size of the attribute, and the attribute value. The format of the attribute value is defined by the security module. A flags field is included for LSM specific information. It is currently unused and must be 0. The total size of the data, including the lsm_ctx structure and any padding, is maintained as well. struct lsm_ctx { __u64 id; __u64 flags; __u64 len; __u64 ctx_len; __u8 ctx[]; }; Two new LSM hooks are used to interface with the LSMs. security_getselfattr() collects the lsm_ctx values from the LSMs that support the hook, accounting for space requirements. security_setselfattr() identifies which LSM the attribute is intended for and passes it along. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- Documentation/userspace-api/lsm.rst | 15 ++++ include/linux/lsm_hook_defs.h | 4 ++ include/linux/lsm_hooks.h | 9 +++ include/linux/security.h | 19 +++++ include/linux/syscalls.h | 4 ++ include/uapi/linux/lsm.h | 33 +++++++++ kernel/sys_ni.c | 4 ++ security/Makefile | 1 + security/lsm_syscalls.c | 104 ++++++++++++++++++++++++++++ security/security.c | 82 ++++++++++++++++++++++ 10 files changed, 275 insertions(+) create mode 100644 security/lsm_syscalls.c