lsm: use 32-bit compatible data types in LSM syscalls

Change the size parameters in lsm_list_modules(), lsm_set_self_attr()
and lsm_get_self_attr() from size_t to u32. This avoids the need to
have different interfaces for 32 and 64 bit systems.

Cc: stable@vger.kernel.org
Fixes: a04a119808 ("LSM: syscalls for current process attributes")
Fixes: ad4aff9ec2 ("LSM: Create lsm_list_modules system call")
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reported-and-reviewed-by: Dmitry V. Levin <ldv@strace.io>
[PM: subject and metadata tweaks, syscall.h fixes]
Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
Casey Schaufler 2024-03-14 11:31:26 -04:00 committed by Paul Moore
parent b0546776ad
commit a5a858f622
12 changed files with 41 additions and 41 deletions

View File

@ -280,9 +280,9 @@ LSM_HOOK(int, 0, netlink_send, struct sock *sk, struct sk_buff *skb)
LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry, LSM_HOOK(void, LSM_RET_VOID, d_instantiate, struct dentry *dentry,
struct inode *inode) struct inode *inode)
LSM_HOOK(int, -EOPNOTSUPP, getselfattr, unsigned int attr, LSM_HOOK(int, -EOPNOTSUPP, getselfattr, unsigned int attr,
struct lsm_ctx __user *ctx, size_t *size, u32 flags) struct lsm_ctx __user *ctx, u32 *size, u32 flags)
LSM_HOOK(int, -EOPNOTSUPP, setselfattr, unsigned int attr, LSM_HOOK(int, -EOPNOTSUPP, setselfattr, unsigned int attr,
struct lsm_ctx *ctx, size_t size, u32 flags) struct lsm_ctx *ctx, u32 size, u32 flags)
LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name, LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name,
char **value) char **value)
LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size) LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)

View File

@ -491,9 +491,9 @@ int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
unsigned nsops, int alter); unsigned nsops, int alter);
void security_d_instantiate(struct dentry *dentry, struct inode *inode); void security_d_instantiate(struct dentry *dentry, struct inode *inode);
int security_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, int security_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t __user *size, u32 flags); u32 __user *size, u32 flags);
int security_setselfattr(unsigned int attr, struct lsm_ctx __user *ctx, int security_setselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t size, u32 flags); u32 size, u32 flags);
int security_getprocattr(struct task_struct *p, int lsmid, const char *name, int security_getprocattr(struct task_struct *p, int lsmid, const char *name,
char **value); char **value);
int security_setprocattr(int lsmid, const char *name, void *value, size_t size); int security_setprocattr(int lsmid, const char *name, void *value, size_t size);
@ -507,7 +507,7 @@ 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_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
int security_locked_down(enum lockdown_reason what); int security_locked_down(enum lockdown_reason what);
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
void *val, size_t val_len, u64 id, u64 flags); void *val, size_t val_len, u64 id, u64 flags);
#else /* CONFIG_SECURITY */ #else /* CONFIG_SECURITY */
@ -1478,7 +1478,7 @@ static inline int security_locked_down(enum lockdown_reason what)
return 0; return 0;
} }
static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx,
size_t *uctx_len, void *val, size_t val_len, u32 *uctx_len, void *val, size_t val_len,
u64 id, u64 flags) u64 id, u64 flags)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;

View File

@ -960,10 +960,10 @@ asmlinkage long sys_cachestat(unsigned int fd,
struct cachestat __user *cstat, unsigned int flags); struct cachestat __user *cstat, unsigned int flags);
asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags); asmlinkage long sys_map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags);
asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
size_t *size, __u32 flags); u32 *size, u32 flags);
asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, __u32 flags); u32 size, u32 flags);
asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags); asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags);
/* /*
* Architecture-specific system calls * Architecture-specific system calls

View File

@ -779,7 +779,7 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
} }
static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx, static int apparmor_getselfattr(unsigned int attr, struct lsm_ctx __user *lx,
size_t *size, u32 flags) u32 *size, u32 flags)
{ {
int error = -ENOENT; int error = -ENOENT;
struct aa_task_ctx *ctx = task_ctx(current); struct aa_task_ctx *ctx = task_ctx(current);
@ -924,7 +924,7 @@ fail:
} }
static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx, static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, u32 flags) u32 size, u32 flags)
{ {
int rc; int rc;

View File

@ -53,7 +53,7 @@ u64 lsm_name_to_attr(const char *name)
* value indicating the reason for the error is returned. * value indicating the reason for the error is returned.
*/ */
SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *, SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *,
ctx, size_t, size, u32, flags) ctx, u32, size, u32, flags)
{ {
return security_setselfattr(attr, ctx, size, flags); return security_setselfattr(attr, ctx, size, flags);
} }
@ -75,7 +75,7 @@ SYSCALL_DEFINE4(lsm_set_self_attr, unsigned int, attr, struct lsm_ctx __user *,
* a negative value indicating the error is returned. * a negative value indicating the error is returned.
*/ */
SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *, SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *,
ctx, size_t __user *, size, u32, flags) ctx, u32 __user *, size, u32, flags)
{ {
return security_getselfattr(attr, ctx, size, flags); return security_getselfattr(attr, ctx, size, flags);
} }
@ -93,11 +93,11 @@ SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *,
* required size. In all other cases a negative value indicating the * required size. In all other cases a negative value indicating the
* error is returned. * error is returned.
*/ */
SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, size_t __user *, size, SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, u32 __user *, size,
u32, flags) u32, flags)
{ {
size_t total_size = lsm_active_cnt * sizeof(*ids); u32 total_size = lsm_active_cnt * sizeof(*ids);
size_t usize; u32 usize;
int i; int i;
if (flags) if (flags)

View File

@ -785,7 +785,7 @@ static int lsm_superblock_alloc(struct super_block *sb)
* Returns 0 on success, -E2BIG if userspace buffer is not large enough, * Returns 0 on success, -E2BIG if userspace buffer is not large enough,
* -EFAULT on a copyout error, -ENOMEM if memory can't be allocated. * -EFAULT on a copyout error, -ENOMEM if memory can't be allocated.
*/ */
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len, int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
void *val, size_t val_len, void *val, size_t val_len,
u64 id, u64 flags) u64 id, u64 flags)
{ {
@ -3931,14 +3931,14 @@ EXPORT_SYMBOL(security_d_instantiate);
* If @size is insufficient to contain the data -E2BIG is returned. * If @size is insufficient to contain the data -E2BIG is returned.
*/ */
int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx, int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
size_t __user *size, u32 flags) u32 __user *size, u32 flags)
{ {
struct security_hook_list *hp; struct security_hook_list *hp;
struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, }; struct lsm_ctx lctx = { .id = LSM_ID_UNDEF, };
u8 __user *base = (u8 __user *)uctx; u8 __user *base = (u8 __user *)uctx;
size_t total = 0; u32 entrysize;
size_t entrysize; u32 total = 0;
size_t left; u32 left;
bool toobig = false; bool toobig = false;
bool single = false; bool single = false;
int count = 0; int count = 0;
@ -4024,7 +4024,7 @@ int security_getselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
* LSM specific failure. * LSM specific failure.
*/ */
int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx, int security_setselfattr(unsigned int attr, struct lsm_ctx __user *uctx,
size_t size, u32 flags) u32 size, u32 flags)
{ {
struct security_hook_list *hp; struct security_hook_list *hp;
struct lsm_ctx *lctx; struct lsm_ctx *lctx;

View File

@ -6559,7 +6559,7 @@ abort_change:
* There will only ever be one attribute. * There will only ever be one attribute.
*/ */
static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t *size, u32 flags) u32 *size, u32 flags)
{ {
int rc; int rc;
char *val = NULL; char *val = NULL;
@ -6574,7 +6574,7 @@ static int selinux_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
} }
static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx, static int selinux_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, u32 flags) u32 size, u32 flags)
{ {
int rc; int rc;

View File

@ -3653,7 +3653,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
* There will only ever be one attribute. * There will only ever be one attribute.
*/ */
static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx, static int smack_getselfattr(unsigned int attr, struct lsm_ctx __user *ctx,
size_t *size, u32 flags) u32 *size, u32 flags)
{ {
int rc; int rc;
struct smack_known *skp; struct smack_known *skp;
@ -3774,7 +3774,7 @@ static int do_setattr(u64 attr, void *value, size_t size)
* Returns 0 on success, an error code otherwise. * Returns 0 on success, an error code otherwise.
*/ */
static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, u32 flags) u32 size, u32 flags)
{ {
int rc; int rc;

View File

@ -7,7 +7,7 @@
#ifndef lsm_get_self_attr #ifndef lsm_get_self_attr
static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx, static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
size_t *size, __u32 flags) __u32 *size, __u32 flags)
{ {
return syscall(__NR_lsm_get_self_attr, attr, ctx, size, flags); return syscall(__NR_lsm_get_self_attr, attr, ctx, size, flags);
} }
@ -15,14 +15,14 @@ static inline int lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
#ifndef lsm_set_self_attr #ifndef lsm_set_self_attr
static inline int lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx, static inline int lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
size_t size, __u32 flags) __u32 size, __u32 flags)
{ {
return syscall(__NR_lsm_set_self_attr, attr, ctx, size, flags); return syscall(__NR_lsm_set_self_attr, attr, ctx, size, flags);
} }
#endif #endif
#ifndef lsm_list_modules #ifndef lsm_list_modules
static inline int lsm_list_modules(__u64 *ids, size_t *size, __u32 flags) static inline int lsm_list_modules(__u64 *ids, __u32 *size, __u32 flags)
{ {
return syscall(__NR_lsm_list_modules, ids, size, flags); return syscall(__NR_lsm_list_modules, ids, size, flags);
} }

View File

@ -40,7 +40,7 @@ TEST(size_null_lsm_get_self_attr)
TEST(ctx_null_lsm_get_self_attr) TEST(ctx_null_lsm_get_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
size_t size = page_size; __u32 size = page_size;
int rc; int rc;
rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0); rc = lsm_get_self_attr(LSM_ATTR_CURRENT, NULL, &size, 0);
@ -57,7 +57,7 @@ TEST(size_too_small_lsm_get_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
size_t size = 1; __u32 size = 1;
ASSERT_NE(NULL, ctx); ASSERT_NE(NULL, ctx);
errno = 0; errno = 0;
@ -77,7 +77,7 @@ TEST(flags_zero_lsm_get_self_attr)
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
__u64 *syscall_lsms = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1);
size_t size; __u32 size;
int lsmcount; int lsmcount;
int i; int i;
@ -117,7 +117,7 @@ TEST(flags_overset_lsm_get_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
size_t size; __u32 size;
ASSERT_NE(NULL, ctx); ASSERT_NE(NULL, ctx);
@ -140,7 +140,7 @@ TEST(flags_overset_lsm_get_self_attr)
TEST(basic_lsm_get_self_attr) TEST(basic_lsm_get_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
size_t size = page_size; __u32 size = page_size;
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
struct lsm_ctx *tctx = NULL; struct lsm_ctx *tctx = NULL;
__u64 *syscall_lsms = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1);

View File

@ -31,7 +31,7 @@ TEST(size_null_lsm_list_modules)
TEST(ids_null_lsm_list_modules) TEST(ids_null_lsm_list_modules)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
size_t size = page_size; __u32 size = page_size;
errno = 0; errno = 0;
ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0)); ASSERT_EQ(-1, lsm_list_modules(NULL, &size, 0));
@ -43,7 +43,7 @@ TEST(size_too_small_lsm_list_modules)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
__u64 *syscall_lsms = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1);
size_t size = 1; __u32 size = 1;
ASSERT_NE(NULL, syscall_lsms); ASSERT_NE(NULL, syscall_lsms);
errno = 0; errno = 0;
@ -58,7 +58,7 @@ TEST(flags_set_lsm_list_modules)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
__u64 *syscall_lsms = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1);
size_t size = page_size; __u32 size = page_size;
ASSERT_NE(NULL, syscall_lsms); ASSERT_NE(NULL, syscall_lsms);
errno = 0; errno = 0;
@ -72,7 +72,7 @@ TEST(flags_set_lsm_list_modules)
TEST(correct_lsm_list_modules) TEST(correct_lsm_list_modules)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
size_t size = page_size; __u32 size = page_size;
__u64 *syscall_lsms = calloc(page_size, 1); __u64 *syscall_lsms = calloc(page_size, 1);
char *sysfs_lsms = calloc(page_size, 1); char *sysfs_lsms = calloc(page_size, 1);
char *name; char *name;

View File

@ -25,7 +25,7 @@ TEST(size_too_small_lsm_set_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
size_t size = page_size; __u32 size = page_size;
ASSERT_NE(NULL, ctx); ASSERT_NE(NULL, ctx);
if (attr_lsm_count()) { if (attr_lsm_count()) {
@ -41,7 +41,7 @@ TEST(flags_zero_lsm_set_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
struct lsm_ctx *ctx = calloc(page_size, 1); struct lsm_ctx *ctx = calloc(page_size, 1);
size_t size = page_size; __u32 size = page_size;
ASSERT_NE(NULL, ctx); ASSERT_NE(NULL, ctx);
if (attr_lsm_count()) { if (attr_lsm_count()) {
@ -57,7 +57,7 @@ TEST(flags_overset_lsm_set_self_attr)
{ {
const long page_size = sysconf(_SC_PAGESIZE); const long page_size = sysconf(_SC_PAGESIZE);
char *ctx = calloc(page_size, 1); char *ctx = calloc(page_size, 1);
size_t size = page_size; __u32 size = page_size;
struct lsm_ctx *tctx = (struct lsm_ctx *)ctx; struct lsm_ctx *tctx = (struct lsm_ctx *)ctx;
ASSERT_NE(NULL, ctx); ASSERT_NE(NULL, ctx);