diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f5d304736852..12cf7de8cbed 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/export.h> | 85 | #include <linux/export.h> |
86 | #include <linux/msg.h> | 86 | #include <linux/msg.h> |
87 | #include <linux/shm.h> | 87 | #include <linux/shm.h> |
88 | #include <linux/bpf.h> | ||
88 | 89 | ||
89 | #include "avc.h" | 90 | #include "avc.h" |
90 | #include "objsec.h" | 91 | #include "objsec.h" |
@@ -6252,6 +6253,106 @@ static void selinux_ib_free_security(void *ib_sec) | |||
6252 | } | 6253 | } |
6253 | #endif | 6254 | #endif |
6254 | 6255 | ||
6256 | #ifdef CONFIG_BPF_SYSCALL | ||
6257 | static int selinux_bpf(int cmd, union bpf_attr *attr, | ||
6258 | unsigned int size) | ||
6259 | { | ||
6260 | u32 sid = current_sid(); | ||
6261 | int ret; | ||
6262 | |||
6263 | switch (cmd) { | ||
6264 | case BPF_MAP_CREATE: | ||
6265 | ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__MAP_CREATE, | ||
6266 | NULL); | ||
6267 | break; | ||
6268 | case BPF_PROG_LOAD: | ||
6269 | ret = avc_has_perm(sid, sid, SECCLASS_BPF, BPF__PROG_LOAD, | ||
6270 | NULL); | ||
6271 | break; | ||
6272 | default: | ||
6273 | ret = 0; | ||
6274 | break; | ||
6275 | } | ||
6276 | |||
6277 | return ret; | ||
6278 | } | ||
6279 | |||
6280 | static u32 bpf_map_fmode_to_av(fmode_t fmode) | ||
6281 | { | ||
6282 | u32 av = 0; | ||
6283 | |||
6284 | if (fmode & FMODE_READ) | ||
6285 | av |= BPF__MAP_READ; | ||
6286 | if (fmode & FMODE_WRITE) | ||
6287 | av |= BPF__MAP_WRITE; | ||
6288 | return av; | ||
6289 | } | ||
6290 | |||
6291 | static int selinux_bpf_map(struct bpf_map *map, fmode_t fmode) | ||
6292 | { | ||
6293 | u32 sid = current_sid(); | ||
6294 | struct bpf_security_struct *bpfsec; | ||
6295 | |||
6296 | bpfsec = map->security; | ||
6297 | return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, | ||
6298 | bpf_map_fmode_to_av(fmode), NULL); | ||
6299 | } | ||
6300 | |||
6301 | static int selinux_bpf_prog(struct bpf_prog *prog) | ||
6302 | { | ||
6303 | u32 sid = current_sid(); | ||
6304 | struct bpf_security_struct *bpfsec; | ||
6305 | |||
6306 | bpfsec = prog->aux->security; | ||
6307 | return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, | ||
6308 | BPF__PROG_RUN, NULL); | ||
6309 | } | ||
6310 | |||
6311 | static int selinux_bpf_map_alloc(struct bpf_map *map) | ||
6312 | { | ||
6313 | struct bpf_security_struct *bpfsec; | ||
6314 | |||
6315 | bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); | ||
6316 | if (!bpfsec) | ||
6317 | return -ENOMEM; | ||
6318 | |||
6319 | bpfsec->sid = current_sid(); | ||
6320 | map->security = bpfsec; | ||
6321 | |||
6322 | return 0; | ||
6323 | } | ||
6324 | |||
6325 | static void selinux_bpf_map_free(struct bpf_map *map) | ||
6326 | { | ||
6327 | struct bpf_security_struct *bpfsec = map->security; | ||
6328 | |||
6329 | map->security = NULL; | ||
6330 | kfree(bpfsec); | ||
6331 | } | ||
6332 | |||
6333 | static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux) | ||
6334 | { | ||
6335 | struct bpf_security_struct *bpfsec; | ||
6336 | |||
6337 | bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); | ||
6338 | if (!bpfsec) | ||
6339 | return -ENOMEM; | ||
6340 | |||
6341 | bpfsec->sid = current_sid(); | ||
6342 | aux->security = bpfsec; | ||
6343 | |||
6344 | return 0; | ||
6345 | } | ||
6346 | |||
6347 | static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) | ||
6348 | { | ||
6349 | struct bpf_security_struct *bpfsec = aux->security; | ||
6350 | |||
6351 | aux->security = NULL; | ||
6352 | kfree(bpfsec); | ||
6353 | } | ||
6354 | #endif | ||
6355 | |||
6255 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | 6356 | static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { |
6256 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), | 6357 | LSM_HOOK_INIT(binder_set_context_mgr, selinux_binder_set_context_mgr), |
6257 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), | 6358 | LSM_HOOK_INIT(binder_transaction, selinux_binder_transaction), |
@@ -6471,6 +6572,16 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6471 | LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match), | 6572 | LSM_HOOK_INIT(audit_rule_match, selinux_audit_rule_match), |
6472 | LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free), | 6573 | LSM_HOOK_INIT(audit_rule_free, selinux_audit_rule_free), |
6473 | #endif | 6574 | #endif |
6575 | |||
6576 | #ifdef CONFIG_BPF_SYSCALL | ||
6577 | LSM_HOOK_INIT(bpf, selinux_bpf), | ||
6578 | LSM_HOOK_INIT(bpf_map, selinux_bpf_map), | ||
6579 | LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog), | ||
6580 | LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc), | ||
6581 | LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc), | ||
6582 | LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free), | ||
6583 | LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free), | ||
6584 | #endif | ||
6474 | }; | 6585 | }; |
6475 | 6586 | ||
6476 | static __init int selinux_init(void) | 6587 | static __init int selinux_init(void) |