summaryrefslogtreecommitdiff
path: root/kernel/bpf
diff options
context:
space:
mode:
authorAndrii Nakryiko <andrii@kernel.org>2023-11-30 10:52:23 -0800
committerAlexei Starovoitov <ast@kernel.org>2023-12-06 10:03:00 -0800
commitd734ca7b33dbf60eb15dcf7c44f3da7073356777 (patch)
tree094194f17a60f5e22567a26ba3ae537556a54456 /kernel/bpf
parent66d636d70a79c1d37e3eea67ab50969e6aaef983 (diff)
bpf,lsm: add BPF token LSM hooks
Wire up bpf_token_create and bpf_token_free LSM hooks, which allow to allocate LSM security blob (we add `void *security` field to struct bpf_token for that), but also control who can instantiate BPF token. This follows existing pattern for BPF map and BPF prog. Also add security_bpf_token_allow_cmd() and security_bpf_token_capable() LSM hooks that allow LSM implementation to control and negate (if necessary) BPF token's delegation of a specific bpf_cmd and capability, respectively. Acked-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20231130185229.2688956-12-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/bpf_lsm.c4
-rw-r--r--kernel/bpf/token.c18
2 files changed, 16 insertions, 6 deletions
diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
index 9e4e615f11eb..7d2f96413a57 100644
--- a/kernel/bpf/bpf_lsm.c
+++ b/kernel/bpf/bpf_lsm.c
@@ -265,6 +265,10 @@ BTF_ID(func, bpf_lsm_bpf_map_free)
BTF_ID(func, bpf_lsm_bpf_prog)
BTF_ID(func, bpf_lsm_bpf_prog_load)
BTF_ID(func, bpf_lsm_bpf_prog_free)
+BTF_ID(func, bpf_lsm_bpf_token_create)
+BTF_ID(func, bpf_lsm_bpf_token_free)
+BTF_ID(func, bpf_lsm_bpf_token_cmd)
+BTF_ID(func, bpf_lsm_bpf_token_capable)
BTF_ID(func, bpf_lsm_bprm_check_security)
BTF_ID(func, bpf_lsm_bprm_committed_creds)
BTF_ID(func, bpf_lsm_bprm_committing_creds)
diff --git a/kernel/bpf/token.c b/kernel/bpf/token.c
index 5a51e6b8f6bf..17212efcde60 100644
--- a/kernel/bpf/token.c
+++ b/kernel/bpf/token.c
@@ -7,6 +7,7 @@
#include <linux/idr.h>
#include <linux/namei.h>
#include <linux/user_namespace.h>
+#include <linux/security.h>
bool bpf_token_capable(const struct bpf_token *token, int cap)
{
@@ -14,10 +15,9 @@ bool bpf_token_capable(const struct bpf_token *token, int cap)
* token's userns is *exactly* the same as current user's userns
*/
if (token && current_user_ns() == token->userns) {
- if (ns_capable(token->userns, cap))
- return true;
- if (cap != CAP_SYS_ADMIN && ns_capable(token->userns, CAP_SYS_ADMIN))
- return true;
+ if (ns_capable(token->userns, cap) ||
+ (cap != CAP_SYS_ADMIN && ns_capable(token->userns, CAP_SYS_ADMIN)))
+ return security_bpf_token_capable(token, cap) == 0;
}
/* otherwise fallback to capable() checks */
return capable(cap) || (cap != CAP_SYS_ADMIN && capable(CAP_SYS_ADMIN));
@@ -30,6 +30,7 @@ void bpf_token_inc(struct bpf_token *token)
static void bpf_token_free(struct bpf_token *token)
{
+ security_bpf_token_free(token);
put_user_ns(token->userns);
kvfree(token);
}
@@ -186,6 +187,10 @@ int bpf_token_create(union bpf_attr *attr)
token->allowed_progs = mnt_opts->delegate_progs;
token->allowed_attachs = mnt_opts->delegate_attachs;
+ err = security_bpf_token_create(token, attr, &path);
+ if (err)
+ goto out_token;
+
fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0) {
err = fd;
@@ -233,8 +238,9 @@ bool bpf_token_allow_cmd(const struct bpf_token *token, enum bpf_cmd cmd)
*/
if (!token || current_user_ns() != token->userns)
return false;
-
- return token->allowed_cmds & (1ULL << cmd);
+ if (!(token->allowed_cmds & (1ULL << cmd)))
+ return false;
+ return security_bpf_token_cmd(token, cmd) == 0;
}
bool bpf_token_allow_map_type(const struct bpf_token *token, enum bpf_map_type type)