Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'lsm-pr-20240314' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm

Pull lsm fixes from Paul Moore:
"Two fixes to address issues with the LSM syscalls that we shipped in
Linux v6.8. The first patch might be a bit controversial, but the
second is a rather straightforward fix; more on both below.

The first fix from Casey addresses a problem that should have been
caught during the ~16 month (?) review cycle, but sadly was not. The
good news is that Dmitry caught it very quickly once Linux v6.8 was
released. The core issue is the use of size_t parameters to pass
buffer sizes back and forth in the syscall; while we could have solved
this with a compat syscall definition, given the newness of the
syscalls I wanted to attempt to just redefine the size_t parameters as
u32 types and avoid the work associated with a set of compat syscalls.

However, this is technically a change in the syscall's signature/API
so I can understand if you're opposed to this, even if the syscalls
are less than a week old.

[ Fingers crossed nobody even notices - Linus ]

The second fix is a rather trivial fix to allow userspace to call into
the lsm_get_self_attr() syscall with a NULL buffer to quickly
determine a minimum required size for the buffer. We do have
kselftests for this very case, I'm not sure why I didn't notice the
failure; I'm going to guess stupidity, tired eyes, I dunno. My
apologies we didn't catch this earlier"

* tag 'lsm-pr-20240314' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm:
lsm: handle the NULL buffer case in lsm_fill_user_ctx()
lsm: use 32-bit compatible data types in LSM syscalls

+48 -42
+2 -2
include/linux/lsm_hook_defs.h
··· 280 280 LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry, 281 281 struct inode *inode) 282 282 LSM_HOOK(int, -EOPNOTSUPP, getselfattr, unsigned int attr, 283 - struct lsm_ctx __user *ctx, size_t *size, u32 flags) 283 + struct lsm_ctx __user *ctx, u32 *size, u32 flags) 284 284 LSM_HOOK(int, -EOPNOTSUPP, setselfattr, unsigned int attr, 285 - struct lsm_ctx *ctx, size_t size, u32 flags) 285 + struct lsm_ctx *ctx, u32 size, u32 flags) 286 286 LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, 287 287 char **value) 288 288 LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
+4 -4
include/linux/security.h
··· 491 491 unsigned nsops, int alter); 492 492 void security_d_instantiate(struct dentry *dentry, struct inode *inode); 493 493 int security_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, 494 - size_t __user *size, u32 flags); 494 + u32 __user *size, u32 flags); 495 495 int security_setselfattr(unsigned int attr, struct lsm_ctx __user *ctx, 496 - size_t size, u32 flags); 496 + u32 size, u32 flags); 497 497 int security_getprocattr(struct task_struct *p, int lsmid, const char *name, 498 498 char **value); 499 499 int security_setprocattr(int lsmid, const char *name, void *value, size_t size); ··· 507 507 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); 508 508 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); 509 509 int security_locked_down(enum lockdown_reason what); 510 - int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, 510 + int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, 511 511 void *val, size_t val_len, u64 id, u64 flags); 512 512 #else /* CONFIG_SECURITY */ 513 513 ··· 1478 1478 return 0; 1479 1479 } 1480 1480 static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, 1481 - size_t *uctx_len, void *val, size_t val_len, 1481 + u32 *uctx_len, void *val, size_t val_len, 1482 1482 u64 id, u64 flags) 1483 1483 { 1484 1484 return -EOPNOTSUPP;
+3 -3
include/linux/syscalls.h
··· 960 960 struct cachestat __user *cstat, unsigned int flags); 961 961 asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags); 962 962 asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, 963 - size_t *size, __u32 flags); 963 + u32 *size, u32 flags); 964 964 asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, 965 - size_t size, __u32 flags); 966 - asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags); 965 + u32 size, u32 flags); 966 + asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags); 967 967 968 968 /* 969 969 * Architecture-specific system calls
+2 -2
security/apparmor/lsm.c
··· 779 779 } 780 780 781 781 static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx, 782 - size_t *size, u32 flags) 782 + u32 *size, u32 flags) 783 783 { 784 784 int error = -ENOENT; 785 785 struct aa_task_ctx *ctx = task_ctx(current); ··· 924 924 } 925 925 926 926 static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx, 927 - size_t size, u32 flags) 927 + u32 size, u32 flags) 928 928 { 929 929 int rc; 930 930
+5 -5
security/lsm_syscalls.c
··· 53 53 * value indicating the reason for the error is returned. 54 54 */ 55 55 SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, 56 - ctx, size_t, size, u32, flags) 56 + ctx, u32, size, u32, flags) 57 57 { 58 58 return security_setselfattr(attr, ctx, size, flags); 59 59 } ··· 75 75 * a negative value indicating the error is returned. 76 76 */ 77 77 SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *, 78 - ctx, size_t __user *, size, u32, flags) 78 + ctx, u32 __user *, size, u32, flags) 79 79 { 80 80 return security_getselfattr(attr, ctx, size, flags); 81 81 } ··· 93 93 * required size. In all other cases a negative value indicating the 94 94 * error is returned. 95 95 */ 96 - SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, size_t __user *, size, 96 + SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, u32 __user *, size, 97 97 u32, flags) 98 98 { 99 - size_t total_size = lsm_active_cnt * sizeof(*ids); 100 - size_t usize; 99 + u32 total_size = lsm_active_cnt * sizeof(*ids); 100 + u32 usize; 101 101 int i; 102 102 103 103 if (flags)
+13 -7
security/security.c
··· 780 780 * @id: LSM id 781 781 * @flags: LSM defined flags 782 782 * 783 - * Fill all of the fields in a userspace lsm_ctx structure. 783 + * Fill all of the fields in a userspace lsm_ctx structure. If @uctx is NULL 784 + * simply calculate the required size to output via @utc_len and return 785 + * success. 784 786 * 785 787 * Returns 0 on success, -E2BIG if userspace buffer is not large enough, 786 788 * -EFAULT on a copyout error, -ENOMEM if memory can't be allocated. 787 789 */ 788 - int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, 790 + int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, 789 791 void *val, size_t val_len, 790 792 u64 id, u64 flags) 791 793 { ··· 800 798 rc = -E2BIG; 801 799 goto out; 802 800 } 801 + 802 + /* no buffer - return success/0 and set @uctx_len to the req size */ 803 + if (!uctx) 804 + goto out; 803 805 804 806 nctx = kzalloc(nctx_len, GFP_KERNEL); 805 807 if (nctx == NULL) { ··· 3937 3931 * If @size is insufficient to contain the data -E2BIG is returned. 3938 3932 */ 3939 3933 int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx, 3940 - size_t __user *size, u32 flags) 3934 + u32 __user *size, u32 flags) 3941 3935 { 3942 3936 struct security_hook_list *hp; 3943 3937 struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, }; 3944 3938 u8 __user *base = (u8 __user *)uctx; 3945 - size_t total = 0; 3946 - size_t entrysize; 3947 - size_t left; 3939 + u32 entrysize; 3940 + u32 total = 0; 3941 + u32 left; 3948 3942 bool toobig = false; 3949 3943 bool single = false; 3950 3944 int count = 0; ··· 4030 4024 * LSM specific failure. 4031 4025 */ 4032 4026 int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx, 4033 - size_t size, u32 flags) 4027 + u32 size, u32 flags) 4034 4028 { 4035 4029 struct security_hook_list *hp; 4036 4030 struct lsm_ctx *lctx;
+2 -2
security/selinux/hooks.c
··· 6559 6559 * There will only ever be one attribute. 6560 6560 */ 6561 6561 static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, 6562 - size_t *size, u32 flags) 6562 + u32 *size, u32 flags) 6563 6563 { 6564 6564 int rc; 6565 6565 char *val = NULL; ··· 6574 6574 } 6575 6575 6576 6576 static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx, 6577 - size_t size, u32 flags) 6577 + u32 size, u32 flags) 6578 6578 { 6579 6579 int rc; 6580 6580
+2 -2
security/smack/smack_lsm.c
··· 3653 3653 * There will only ever be one attribute. 3654 3654 */ 3655 3655 static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, 3656 - size_t *size, u32 flags) 3656 + u32 *size, u32 flags) 3657 3657 { 3658 3658 int rc; 3659 3659 struct smack_known *skp; ··· 3774 3774 * Returns 0 on success, an error code otherwise. 3775 3775 */ 3776 3776 static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, 3777 - size_t size, u32 flags) 3777 + u32 size, u32 flags) 3778 3778 { 3779 3779 int rc; 3780 3780
+3 -3
tools/testing/selftests/lsm/common.h
··· 7 7 8 8 #ifndef lsm_get_self_attr 9 9 static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, 10 - size_t *size, __u32 flags) 10 + __u32 *size, __u32 flags) 11 11 { 12 12 return syscall(__NR_lsm_get_self_attr, attr, ctx, size, flags); 13 13 } ··· 15 15 16 16 #ifndef lsm_set_self_attr 17 17 static inline int lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, 18 - size_t size, __u32 flags) 18 + __u32 size, __u32 flags) 19 19 { 20 20 return syscall(__NR_lsm_set_self_attr, attr, ctx, size, flags); 21 21 } 22 22 #endif 23 23 24 24 #ifndef lsm_list_modules 25 - static inline int lsm_list_modules(__u64 *ids, size_t *size, __u32 flags) 25 + static inline int lsm_list_modules(__u64 *ids, __u32 *size, __u32 flags) 26 26 { 27 27 return syscall(__NR_lsm_list_modules, ids, size, flags); 28 28 }
+5 -5
tools/testing/selftests/lsm/lsm_get_self_attr_test.c
··· 40 40 TEST(ctx_null_lsm_get_self_attr) 41 41 { 42 42 const long page_size = sysconf(_SC_PAGESIZE); 43 - size_t size = page_size; 43 + __u32 size = page_size; 44 44 int rc; 45 45 46 46 rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0); ··· 57 57 { 58 58 const long page_size = sysconf(_SC_PAGESIZE); 59 59 struct lsm_ctx *ctx = calloc(page_size, 1); 60 - size_t size = 1; 60 + __u32 size = 1; 61 61 62 62 ASSERT_NE(NULL, ctx); 63 63 errno = 0; ··· 77 77 const long page_size = sysconf(_SC_PAGESIZE); 78 78 struct lsm_ctx *ctx = calloc(page_size, 1); 79 79 __u64 *syscall_lsms = calloc(page_size, 1); 80 - size_t size; 80 + __u32 size; 81 81 int lsmcount; 82 82 int i; 83 83 ··· 117 117 { 118 118 const long page_size = sysconf(_SC_PAGESIZE); 119 119 struct lsm_ctx *ctx = calloc(page_size, 1); 120 - size_t size; 120 + __u32 size; 121 121 122 122 ASSERT_NE(NULL, ctx); 123 123 ··· 140 140 TEST(basic_lsm_get_self_attr) 141 141 { 142 142 const long page_size = sysconf(_SC_PAGESIZE); 143 - size_t size = page_size; 143 + __u32 size = page_size; 144 144 struct lsm_ctx *ctx = calloc(page_size, 1); 145 145 struct lsm_ctx *tctx = NULL; 146 146 __u64 *syscall_lsms = calloc(page_size, 1);
+4 -4
tools/testing/selftests/lsm/lsm_list_modules_test.c
··· 31 31 TEST(ids_null_lsm_list_modules) 32 32 { 33 33 const long page_size = sysconf(_SC_PAGESIZE); 34 - size_t size = page_size; 34 + __u32 size = page_size; 35 35 36 36 errno = 0; 37 37 ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0)); ··· 43 43 { 44 44 const long page_size = sysconf(_SC_PAGESIZE); 45 45 __u64 *syscall_lsms = calloc(page_size, 1); 46 - size_t size = 1; 46 + __u32 size = 1; 47 47 48 48 ASSERT_NE(NULL, syscall_lsms); 49 49 errno = 0; ··· 58 58 { 59 59 const long page_size = sysconf(_SC_PAGESIZE); 60 60 __u64 *syscall_lsms = calloc(page_size, 1); 61 - size_t size = page_size; 61 + __u32 size = page_size; 62 62 63 63 ASSERT_NE(NULL, syscall_lsms); 64 64 errno = 0; ··· 72 72 TEST(correct_lsm_list_modules) 73 73 { 74 74 const long page_size = sysconf(_SC_PAGESIZE); 75 - size_t size = page_size; 75 + __u32 size = page_size; 76 76 __u64 *syscall_lsms = calloc(page_size, 1); 77 77 char *sysfs_lsms = calloc(page_size, 1); 78 78 char *name;
+3 -3
tools/testing/selftests/lsm/lsm_set_self_attr_test.c
··· 25 25 { 26 26 const long page_size = sysconf(_SC_PAGESIZE); 27 27 struct lsm_ctx *ctx = calloc(page_size, 1); 28 - size_t size = page_size; 28 + __u32 size = page_size; 29 29 30 30 ASSERT_NE(NULL, ctx); 31 31 if (attr_lsm_count()) { ··· 41 41 { 42 42 const long page_size = sysconf(_SC_PAGESIZE); 43 43 struct lsm_ctx *ctx = calloc(page_size, 1); 44 - size_t size = page_size; 44 + __u32 size = page_size; 45 45 46 46 ASSERT_NE(NULL, ctx); 47 47 if (attr_lsm_count()) { ··· 57 57 { 58 58 const long page_size = sysconf(_SC_PAGESIZE); 59 59 char *ctx = calloc(page_size, 1); 60 - size_t size = page_size; 60 + __u32 size = page_size; 61 61 struct lsm_ctx *tctx = (struct lsm_ctx *)ctx; 62 62 63 63 ASSERT_NE(NULL, ctx);