aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2017-10-18 16:00:25 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-20 08:32:59 -0400
commitec27c3568a34c7fe5fcf4ac0a354eda77687f7eb (patch)
treee37f2897f3c6228d26a9a15892e61ae63aa2e4fc /security/selinux/hooks.c
parentafdb09c720b62b8090584c11151d856df330e57d (diff)
selinux: bpf: Add selinux check for eBPF syscall operations
Implement the actual checks introduced to eBPF related syscalls. This implementation use the security field inside bpf object to store a sid that identify the bpf object. And when processes try to access the object, selinux will check if processes have the right privileges. The creation of eBPF object are also checked at the general bpf check hook and new cmd introduced to eBPF domain can also be checked there. Signed-off-by: Chenbo Feng <fengc@google.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: James Morris <james.l.morris@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c111
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
6257static 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
6280static 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
6291static 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
6301static 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
6311static 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
6325static 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
6333static 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
6347static 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
6255static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { 6356static 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
6476static __init int selinux_init(void) 6587static __init int selinux_init(void)