Commit c0a614e8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 35e886e8 eaf0e7a3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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,
	 struct inode *inode)
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,
	 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,
	 char **value)
LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
+4 −4
Original line number Diff line number Diff line
@@ -491,9 +491,9 @@ 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(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,
			 size_t size, u32 flags);
			 u32 size, u32 flags);
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);
@@ -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_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 *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);
#else /* CONFIG_SECURITY */

@@ -1478,7 +1478,7 @@ static inline int security_locked_down(enum lockdown_reason what)
	return 0;
}
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)
{
	return -EOPNOTSUPP;
+3 −3
Original line number Diff line number Diff line
@@ -960,10 +960,10 @@ asmlinkage long sys_cachestat(unsigned int fd,
		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_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,
				      size_t size, __u32 flags);
asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags);
				      u32 size, u32 flags);
asmlinkage long sys_lsm_list_modules(u64 *ids, u32 *size, u32 flags);

/*
 * Architecture-specific system calls
+2 −2
Original line number Diff line number Diff line
@@ -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,
				size_t *size, u32 flags)
				u32 *size, u32 flags)
{
	int error = -ENOENT;
	struct aa_task_ctx *ctx = task_ctx(current);
@@ -924,7 +924,7 @@ static int do_setattr(u64 attr, void *value, size_t size)
}

static int apparmor_setselfattr(unsigned int attr, struct lsm_ctx *ctx,
				size_t size, u32 flags)
				u32 size, u32 flags)
{
	int rc;

+5 −5
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ u64 lsm_name_to_attr(const char *name)
 * value indicating the reason for the error is returned.
 */
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);
}
@@ -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.
 */
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);
}
@@ -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
 * 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)
{
	size_t total_size = lsm_active_cnt * sizeof(*ids);
	size_t usize;
	u32 total_size = lsm_active_cnt * sizeof(*ids);
	u32 usize;
	int i;

	if (flags)
Loading