@@ -737,6 +737,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
737737 goto out ;
738738 }
739739
740+ sbsec -> creator_sid = current_sid ();
741+
740742 if (strcmp (sb -> s_type -> name , "proc" ) == 0 )
741743 sbsec -> flags |= SE_SBPROC | SE_SBGENFS ;
742744
@@ -908,6 +910,8 @@ static int selinux_cmp_sb_context(const struct super_block *oldsb,
908910 if (oldroot -> sid != newroot -> sid )
909911 goto mismatch ;
910912 }
913+ if (old -> creator_sid != new -> creator_sid )
914+ goto mismatch ;
911915 return 0 ;
912916mismatch :
913917 pr_warn ("SELinux: mount invalid. Same superblock, "
@@ -967,6 +971,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
967971 newsbsec -> sid = oldsbsec -> sid ;
968972 newsbsec -> def_sid = oldsbsec -> def_sid ;
969973 newsbsec -> behavior = oldsbsec -> behavior ;
974+ newsbsec -> creator_sid = oldsbsec -> creator_sid ;
970975
971976 if (newsbsec -> behavior == SECURITY_FS_USE_NATIVE &&
972977 !(kern_flags & SECURITY_LSM_NATIVE_LABELS ) && !set_context ) {
@@ -1654,7 +1659,6 @@ static int cred_has_capability(const struct cred *cred,
16541659 break ;
16551660 default :
16561661 pr_err ("SELinux: out of range capability %d\n" , cap );
1657- BUG ();
16581662 return - EINVAL ;
16591663 }
16601664
@@ -2586,6 +2590,7 @@ static int selinux_sb_alloc_security(struct super_block *sb)
25862590 sbsec -> sid = SECINITSID_UNLABELED ;
25872591 sbsec -> def_sid = SECINITSID_FILE ;
25882592 sbsec -> mntpoint_sid = SECINITSID_UNLABELED ;
2593+ sbsec -> creator_sid = SECINITSID_UNLABELED ;
25892594
25902595 return 0 ;
25912596}
@@ -7043,6 +7048,9 @@ static int selinux_bpf(int cmd, union bpf_attr *attr,
70437048 u32 sid = current_sid ();
70447049 int ret ;
70457050
7051+ if (selinux_policycap_bpf_token_perms ())
7052+ return 0 ;
7053+
70467054 switch (cmd ) {
70477055 case BPF_MAP_CREATE :
70487056 ret = avc_has_perm (sid , sid , SECCLASS_BPF , BPF__MAP_CREATE ,
@@ -7124,60 +7132,144 @@ static int selinux_bpf_prog(struct bpf_prog *prog)
71247132 BPF__PROG_RUN , NULL );
71257133}
71267134
7135+ static u32 selinux_bpffs_creator_sid (u32 fd )
7136+ {
7137+ struct path path ;
7138+ struct super_block * sb ;
7139+ struct superblock_security_struct * sbsec ;
7140+
7141+ CLASS (fd , f )(fd );
7142+
7143+ if (fd_empty (f ))
7144+ return SECSID_NULL ;
7145+
7146+ path = fd_file (f )-> f_path ;
7147+ sb = path .dentry -> d_sb ;
7148+ sbsec = selinux_superblock (sb );
7149+
7150+ return sbsec -> creator_sid ;
7151+ }
7152+
71277153static int selinux_bpf_map_create (struct bpf_map * map , union bpf_attr * attr ,
71287154 struct bpf_token * token , bool kernel )
71297155{
71307156 struct bpf_security_struct * bpfsec ;
7157+ u32 ssid ;
71317158
71327159 bpfsec = selinux_bpf_map_security (map );
71337160 bpfsec -> sid = current_sid ();
71347161
7135- return 0 ;
7162+ if (!token )
7163+ ssid = bpfsec -> sid ;
7164+ else
7165+ ssid = selinux_bpffs_creator_sid (attr -> map_token_fd );
7166+
7167+ return avc_has_perm (ssid , bpfsec -> sid , SECCLASS_BPF , BPF__MAP_CREATE ,
7168+ NULL );
71367169}
71377170
71387171static int selinux_bpf_prog_load (struct bpf_prog * prog , union bpf_attr * attr ,
71397172 struct bpf_token * token , bool kernel )
71407173{
71417174 struct bpf_security_struct * bpfsec ;
7175+ u32 ssid ;
71427176
71437177 bpfsec = selinux_bpf_prog_security (prog );
71447178 bpfsec -> sid = current_sid ();
71457179
7146- return 0 ;
7180+ if (!token )
7181+ ssid = bpfsec -> sid ;
7182+ else
7183+ ssid = selinux_bpffs_creator_sid (attr -> prog_token_fd );
7184+
7185+ return avc_has_perm (ssid , bpfsec -> sid , SECCLASS_BPF , BPF__PROG_LOAD ,
7186+ NULL );
71477187}
71487188
7149- static int selinux_bpf_token_create (struct bpf_token * token , union bpf_attr * attr ,
7189+ #define bpf_token_cmd (T , C ) \
7190+ ((T)->allowed_cmds & (1ULL << (C)))
7191+
7192+ static int selinux_bpf_token_create (struct bpf_token * token ,
7193+ union bpf_attr * attr ,
71507194 const struct path * path )
71517195{
71527196 struct bpf_security_struct * bpfsec ;
7197+ u32 sid = selinux_bpffs_creator_sid (attr -> token_create .bpffs_fd );
7198+ int err ;
71537199
71547200 bpfsec = selinux_bpf_token_security (token );
71557201 bpfsec -> sid = current_sid ();
7202+ bpfsec -> grantor_sid = sid ;
7203+
7204+ bpfsec -> perms = 0 ;
7205+ /**
7206+ * 'token->allowed_cmds' is a bit mask of allowed commands
7207+ * Convert the BPF command enum to a bitmask representing its position
7208+ * in the allowed_cmds bitmap.
7209+ */
7210+ if (bpf_token_cmd (token , BPF_MAP_CREATE )) {
7211+ err = avc_has_perm (bpfsec -> sid , sid , SECCLASS_BPF ,
7212+ BPF__MAP_CREATE_AS , NULL );
7213+ if (err )
7214+ return err ;
7215+ bpfsec -> perms |= BPF__MAP_CREATE ;
7216+ }
7217+ if (bpf_token_cmd (token , BPF_PROG_LOAD )) {
7218+ err = avc_has_perm (bpfsec -> sid , sid , SECCLASS_BPF ,
7219+ BPF__PROG_LOAD_AS , NULL );
7220+ if (err )
7221+ return err ;
7222+ bpfsec -> perms |= BPF__PROG_LOAD ;
7223+ }
71567224
71577225 return 0 ;
71587226}
7159- #endif
71607227
7161- struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
7162- .lbs_cred = sizeof (struct cred_security_struct ),
7163- .lbs_task = sizeof (struct task_security_struct ),
7164- .lbs_file = sizeof (struct file_security_struct ),
7165- .lbs_inode = sizeof (struct inode_security_struct ),
7166- .lbs_ipc = sizeof (struct ipc_security_struct ),
7167- .lbs_key = sizeof (struct key_security_struct ),
7168- .lbs_msg_msg = sizeof (struct msg_security_struct ),
7169- #ifdef CONFIG_PERF_EVENTS
7170- .lbs_perf_event = sizeof (struct perf_event_security_struct ),
7228+ static int selinux_bpf_token_cmd (const struct bpf_token * token ,
7229+ enum bpf_cmd cmd )
7230+ {
7231+ struct bpf_security_struct * bpfsec ;
7232+
7233+ bpfsec = token -> security ;
7234+ switch (cmd ) {
7235+ case BPF_MAP_CREATE :
7236+ if (!(bpfsec -> perms & BPF__MAP_CREATE ))
7237+ return - EACCES ;
7238+ break ;
7239+ case BPF_PROG_LOAD :
7240+ if (!(bpfsec -> perms & BPF__PROG_LOAD ))
7241+ return - EACCES ;
7242+ break ;
7243+ default :
7244+ break ;
7245+ }
7246+
7247+ return 0 ;
7248+ }
7249+
7250+ static int selinux_bpf_token_capable (const struct bpf_token * token , int cap )
7251+ {
7252+ u16 sclass ;
7253+ struct bpf_security_struct * bpfsec = token -> security ;
7254+ bool initns = (token -> userns == & init_user_ns );
7255+ u32 av = CAP_TO_MASK (cap );
7256+
7257+ switch (CAP_TO_INDEX (cap )) {
7258+ case 0 :
7259+ sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS ;
7260+ break ;
7261+ case 1 :
7262+ sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS ;
7263+ break ;
7264+ default :
7265+ pr_err ("SELinux: out of range capability %d\n" , cap );
7266+ return - EINVAL ;
7267+ }
7268+
7269+ return avc_has_perm (current_sid (), bpfsec -> grantor_sid , sclass , av ,
7270+ NULL );
7271+ }
71717272#endif
7172- .lbs_sock = sizeof (struct sk_security_struct ),
7173- .lbs_superblock = sizeof (struct superblock_security_struct ),
7174- .lbs_xattr_count = SELINUX_INODE_INIT_XATTRS ,
7175- .lbs_tun_dev = sizeof (struct tun_security_struct ),
7176- .lbs_ib = sizeof (struct ib_security_struct ),
7177- .lbs_bpf_map = sizeof (struct bpf_security_struct ),
7178- .lbs_bpf_prog = sizeof (struct bpf_security_struct ),
7179- .lbs_bpf_token = sizeof (struct bpf_security_struct ),
7180- };
71817273
71827274#ifdef CONFIG_PERF_EVENTS
71837275static int selinux_perf_event_open (int type )
@@ -7297,6 +7389,27 @@ static const struct lsm_id selinux_lsmid = {
72977389 .id = LSM_ID_SELINUX ,
72987390};
72997391
7392+ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
7393+ .lbs_cred = sizeof (struct cred_security_struct ),
7394+ .lbs_task = sizeof (struct task_security_struct ),
7395+ .lbs_file = sizeof (struct file_security_struct ),
7396+ .lbs_inode = sizeof (struct inode_security_struct ),
7397+ .lbs_ipc = sizeof (struct ipc_security_struct ),
7398+ .lbs_key = sizeof (struct key_security_struct ),
7399+ .lbs_msg_msg = sizeof (struct msg_security_struct ),
7400+ #ifdef CONFIG_PERF_EVENTS
7401+ .lbs_perf_event = sizeof (struct perf_event_security_struct ),
7402+ #endif
7403+ .lbs_sock = sizeof (struct sk_security_struct ),
7404+ .lbs_superblock = sizeof (struct superblock_security_struct ),
7405+ .lbs_xattr_count = SELINUX_INODE_INIT_XATTRS ,
7406+ .lbs_tun_dev = sizeof (struct tun_security_struct ),
7407+ .lbs_ib = sizeof (struct ib_security_struct ),
7408+ .lbs_bpf_map = sizeof (struct bpf_security_struct ),
7409+ .lbs_bpf_prog = sizeof (struct bpf_security_struct ),
7410+ .lbs_bpf_token = sizeof (struct bpf_security_struct ),
7411+ };
7412+
73007413/*
73017414 * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order:
73027415 * 1. any hooks that don't belong to (2.) or (3.) below,
@@ -7590,6 +7703,8 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
75907703 LSM_HOOK_INIT (bpf_map_create , selinux_bpf_map_create ),
75917704 LSM_HOOK_INIT (bpf_prog_load , selinux_bpf_prog_load ),
75927705 LSM_HOOK_INIT (bpf_token_create , selinux_bpf_token_create ),
7706+ LSM_HOOK_INIT (bpf_token_cmd , selinux_bpf_token_cmd ),
7707+ LSM_HOOK_INIT (bpf_token_capable , selinux_bpf_token_capable ),
75937708#endif
75947709#ifdef CONFIG_PERF_EVENTS
75957710 LSM_HOOK_INIT (perf_event_alloc , selinux_perf_event_alloc ),
0 commit comments