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

Pull lsm updates from Paul Moore:

 - Move the management of the LSM BPF security blobs into the framework

   In order to enable multiple LSMs we need to allocate and free the
   various security blobs in the LSM framework and not the individual
   LSMs as they would end up stepping all over each other.

 - Leverage the lsm_bdev_alloc() helper in lsm_bdev_alloc()

   Make better use of our existing helper functions to reduce some code
   duplication.

 - Update the Rust cred code to use 'sync::aref'

   Part of a larger effort to move the Rust code over to the 'sync'
   module.

 - Make CONFIG_LSM dependent on CONFIG_SECURITY

   As the CONFIG_LSM Kconfig setting is an ordered list of the LSMs to
   enable a boot, it obviously doesn't make much sense to enable this
   when CONFIG_SECURITY is disabled.

 - Update the LSM and CREDENTIALS sections in MAINTAINERS with Rusty
   bits

   Add the Rust helper files to the associated LSM and CREDENTIALS
   entries int the MAINTAINERS file. We're trying to improve the
   communication between the two groups and making sure we're all aware
   of what is going on via cross-posting to the relevant lists is a good
   way to start.

* tag 'lsm-pr-20250926' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm:
  lsm: CONFIG_LSM can depend on CONFIG_SECURITY
  MAINTAINERS: add the associated Rust helper to the CREDENTIALS section
  MAINTAINERS: add the associated Rust helper to the LSM section
  rust,cred: update AlwaysRefCounted import to sync::aref
  security: use umax() to improve code
  lsm,selinux: Add LSM blob support for BPF objects
  lsm: use lsm_blob_alloc() in lsm_bdev_alloc()
This commit is contained in:
Linus Torvalds
2025-09-30 08:48:29 -07:00
8 changed files with 124 additions and 68 deletions

View File

@@ -7066,14 +7066,14 @@ static int bpf_fd_pass(const struct file *file, u32 sid)
if (file->f_op == &bpf_map_fops) {
map = file->private_data;
bpfsec = map->security;
bpfsec = selinux_bpf_map_security(map);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(file->f_mode), NULL);
if (ret)
return ret;
} else if (file->f_op == &bpf_prog_fops) {
prog = file->private_data;
bpfsec = prog->aux->security;
bpfsec = selinux_bpf_prog_security(prog);
ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
if (ret)
@@ -7087,7 +7087,7 @@ static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
bpfsec = map->security;
bpfsec = selinux_bpf_map_security(map);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
bpf_map_fmode_to_av(fmode), NULL);
}
@@ -7097,7 +7097,7 @@ static int selinux_bpf_prog(struct bpf_prog *prog)
u32 sid = current_sid();
struct bpf_security_struct *bpfsec;
bpfsec = prog->aux->security;
bpfsec = selinux_bpf_prog_security(prog);
return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF,
BPF__PROG_RUN, NULL);
}
@@ -7107,69 +7107,33 @@ static int selinux_bpf_map_create(struct bpf_map *map, union bpf_attr *attr,
{
struct bpf_security_struct *bpfsec;
bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
if (!bpfsec)
return -ENOMEM;
bpfsec = selinux_bpf_map_security(map);
bpfsec->sid = current_sid();
map->security = bpfsec;
return 0;
}
static void selinux_bpf_map_free(struct bpf_map *map)
{
struct bpf_security_struct *bpfsec = map->security;
map->security = NULL;
kfree(bpfsec);
}
static int selinux_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr,
struct bpf_token *token, bool kernel)
{
struct bpf_security_struct *bpfsec;
bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
if (!bpfsec)
return -ENOMEM;
bpfsec = selinux_bpf_prog_security(prog);
bpfsec->sid = current_sid();
prog->aux->security = bpfsec;
return 0;
}
static void selinux_bpf_prog_free(struct bpf_prog *prog)
{
struct bpf_security_struct *bpfsec = prog->aux->security;
prog->aux->security = NULL;
kfree(bpfsec);
}
static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr,
const struct path *path)
{
struct bpf_security_struct *bpfsec;
bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL);
if (!bpfsec)
return -ENOMEM;
bpfsec = selinux_bpf_token_security(token);
bpfsec->sid = current_sid();
token->security = bpfsec;
return 0;
}
static void selinux_bpf_token_free(struct bpf_token *token)
{
struct bpf_security_struct *bpfsec = token->security;
token->security = NULL;
kfree(bpfsec);
}
#endif
struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
@@ -7187,6 +7151,9 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
.lbs_tun_dev = sizeof(struct tun_security_struct),
.lbs_ib = sizeof(struct ib_security_struct),
.lbs_bpf_map = sizeof(struct bpf_security_struct),
.lbs_bpf_prog = sizeof(struct bpf_security_struct),
.lbs_bpf_token = sizeof(struct bpf_security_struct),
};
#ifdef CONFIG_PERF_EVENTS
@@ -7540,9 +7507,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bpf, selinux_bpf),
LSM_HOOK_INIT(bpf_map, selinux_bpf_map),
LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog),
LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free),
LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free),
LSM_HOOK_INIT(bpf_token_free, selinux_bpf_token_free),
#endif
#ifdef CONFIG_PERF_EVENTS

View File

@@ -26,6 +26,7 @@
#include <linux/lsm_hooks.h>
#include <linux/msg.h>
#include <net/net_namespace.h>
#include <linux/bpf.h>
#include "flask.h"
#include "avc.h"
@@ -245,4 +246,23 @@ selinux_perf_event(void *perf_event)
return perf_event + selinux_blob_sizes.lbs_perf_event;
}
#ifdef CONFIG_BPF_SYSCALL
static inline struct bpf_security_struct *
selinux_bpf_map_security(struct bpf_map *map)
{
return map->security + selinux_blob_sizes.lbs_bpf_map;
}
static inline struct bpf_security_struct *
selinux_bpf_prog_security(struct bpf_prog *prog)
{
return prog->aux->security + selinux_blob_sizes.lbs_bpf_prog;
}
static inline struct bpf_security_struct *
selinux_bpf_token_security(struct bpf_token *token)
{
return token->security + selinux_blob_sizes.lbs_bpf_token;
}
#endif /* CONFIG_BPF_SYSCALL */
#endif /* _SELINUX_OBJSEC_H_ */