Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lsm,selinux: Add LSM blob support for BPF objects

This patch introduces LSM blob support for BPF maps, programs, and
tokens to enable LSM stacking and multiplexing of LSM modules that
govern BPF objects. Additionally, the existing BPF hooks used by
SELinux have been updated to utilize the new blob infrastructure,
removing the assumption of exclusive ownership of the security
pointer.

Signed-off-by: Blaise Boscaccy <bboscaccy@linux.microsoft.com>
[PM: dropped local variable init, style fixes]
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Blaise Boscaccy and committed by
Paul Moore
5816bf42 e5bc8874

+116 -49
+3
include/linux/lsm_hooks.h
··· 116 116 int lbs_xattr_count; /* number of xattr slots in new_xattrs array */ 117 117 int lbs_tun_dev; 118 118 int lbs_bdev; 119 + int lbs_bpf_map; 120 + int lbs_bpf_prog; 121 + int lbs_bpf_token; 119 122 }; 120 123 121 124 /*
+83 -3
security/security.c
··· 283 283 lsm_set_blob_size(&needed->lbs_xattr_count, 284 284 &blob_sizes.lbs_xattr_count); 285 285 lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev); 286 + lsm_set_blob_size(&needed->lbs_bpf_map, &blob_sizes.lbs_bpf_map); 287 + lsm_set_blob_size(&needed->lbs_bpf_prog, &blob_sizes.lbs_bpf_prog); 288 + lsm_set_blob_size(&needed->lbs_bpf_token, &blob_sizes.lbs_bpf_token); 286 289 } 287 290 288 291 /* Prepare LSM for initialization. */ ··· 483 480 init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev); 484 481 init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count); 485 482 init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev); 483 + init_debug("bpf map blob size = %d\n", blob_sizes.lbs_bpf_map); 484 + init_debug("bpf prog blob size = %d\n", blob_sizes.lbs_bpf_prog); 485 + init_debug("bpf token blob size = %d\n", blob_sizes.lbs_bpf_token); 486 486 487 487 /* 488 488 * Create any kmem_caches needed for blobs ··· 832 826 return lsm_blob_alloc(&bdev->bd_security, blob_sizes.lbs_bdev, 833 827 GFP_KERNEL); 834 828 } 829 + 830 + #ifdef CONFIG_BPF_SYSCALL 831 + /** 832 + * lsm_bpf_map_alloc - allocate a composite bpf_map blob 833 + * @map: the bpf_map that needs a blob 834 + * 835 + * Allocate the bpf_map blob for all the modules 836 + * 837 + * Returns 0, or -ENOMEM if memory can't be allocated. 838 + */ 839 + static int lsm_bpf_map_alloc(struct bpf_map *map) 840 + { 841 + return lsm_blob_alloc(&map->security, blob_sizes.lbs_bpf_map, GFP_KERNEL); 842 + } 843 + 844 + /** 845 + * lsm_bpf_prog_alloc - allocate a composite bpf_prog blob 846 + * @prog: the bpf_prog that needs a blob 847 + * 848 + * Allocate the bpf_prog blob for all the modules 849 + * 850 + * Returns 0, or -ENOMEM if memory can't be allocated. 851 + */ 852 + static int lsm_bpf_prog_alloc(struct bpf_prog *prog) 853 + { 854 + return lsm_blob_alloc(&prog->aux->security, blob_sizes.lbs_bpf_prog, GFP_KERNEL); 855 + } 856 + 857 + /** 858 + * lsm_bpf_token_alloc - allocate a composite bpf_token blob 859 + * @token: the bpf_token that needs a blob 860 + * 861 + * Allocate the bpf_token blob for all the modules 862 + * 863 + * Returns 0, or -ENOMEM if memory can't be allocated. 864 + */ 865 + static int lsm_bpf_token_alloc(struct bpf_token *token) 866 + { 867 + return lsm_blob_alloc(&token->security, blob_sizes.lbs_bpf_token, GFP_KERNEL); 868 + } 869 + #endif /* CONFIG_BPF_SYSCALL */ 835 870 836 871 /** 837 872 * lsm_early_task - during initialization allocate a composite task blob ··· 5753 5706 int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, 5754 5707 struct bpf_token *token, bool kernel) 5755 5708 { 5756 - return call_int_hook(bpf_map_create, map, attr, token, kernel); 5709 + int rc; 5710 + 5711 + rc = lsm_bpf_map_alloc(map); 5712 + if (unlikely(rc)) 5713 + return rc; 5714 + 5715 + rc = call_int_hook(bpf_map_create, map, attr, token, kernel); 5716 + if (unlikely(rc)) 5717 + security_bpf_map_free(map); 5718 + return rc; 5757 5719 } 5758 5720 5759 5721 /** ··· 5781 5725 int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, 5782 5726 struct bpf_token *token, bool kernel) 5783 5727 { 5784 - return call_int_hook(bpf_prog_load, prog, attr, token, kernel); 5728 + int rc; 5729 + 5730 + rc = lsm_bpf_prog_alloc(prog); 5731 + if (unlikely(rc)) 5732 + return rc; 5733 + 5734 + rc = call_int_hook(bpf_prog_load, prog, attr, token, kernel); 5735 + if (unlikely(rc)) 5736 + security_bpf_prog_free(prog); 5737 + return rc; 5785 5738 } 5786 5739 5787 5740 /** ··· 5807 5742 int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 5808 5743 const struct path *path) 5809 5744 { 5810 - return call_int_hook(bpf_token_create, token, attr, path); 5745 + int rc; 5746 + 5747 + rc = lsm_bpf_token_alloc(token); 5748 + if (unlikely(rc)) 5749 + return rc; 5750 + 5751 + rc = call_int_hook(bpf_token_create, token, attr, path); 5752 + if (unlikely(rc)) 5753 + security_bpf_token_free(token); 5754 + return rc; 5811 5755 } 5812 5756 5813 5757 /** ··· 5860 5786 void security_bpf_map_free(struct bpf_map *map) 5861 5787 { 5862 5788 call_void_hook(bpf_map_free, map); 5789 + kfree(map->security); 5790 + map->security = NULL; 5863 5791 } 5864 5792 5865 5793 /** ··· 5873 5797 void security_bpf_prog_free(struct bpf_prog *prog) 5874 5798 { 5875 5799 call_void_hook(bpf_prog_free, prog); 5800 + kfree(prog->aux->security); 5801 + prog->aux->security = NULL; 5876 5802 } 5877 5803 5878 5804 /** ··· 5886 5808 void security_bpf_token_free(struct bpf_token *token) 5887 5809 { 5888 5810 call_void_hook(bpf_token_free, token); 5811 + kfree(token->security); 5812 + token->security = NULL; 5889 5813 } 5890 5814 #endif /* CONFIG_BPF_SYSCALL */ 5891 5815
+10 -46
security/selinux/hooks.c
··· 7062 7062 7063 7063 if (file->f_op == &bpf_map_fops) { 7064 7064 map = file->private_data; 7065 - bpfsec = map->security; 7065 + bpfsec = selinux_bpf_map_security(map); 7066 7066 ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, 7067 7067 bpf_map_fmode_to_av(file->f_mode), NULL); 7068 7068 if (ret) 7069 7069 return ret; 7070 7070 } else if (file->f_op == &bpf_prog_fops) { 7071 7071 prog = file->private_data; 7072 - bpfsec = prog->aux->security; 7072 + bpfsec = selinux_bpf_prog_security(prog); 7073 7073 ret = avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, 7074 7074 BPF__PROG_RUN, NULL); 7075 7075 if (ret) ··· 7083 7083 u32 sid = current_sid(); 7084 7084 struct bpf_security_struct *bpfsec; 7085 7085 7086 - bpfsec = map->security; 7086 + bpfsec = selinux_bpf_map_security(map); 7087 7087 return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, 7088 7088 bpf_map_fmode_to_av(fmode), NULL); 7089 7089 } ··· 7093 7093 u32 sid = current_sid(); 7094 7094 struct bpf_security_struct *bpfsec; 7095 7095 7096 - bpfsec = prog->aux->security; 7096 + bpfsec = selinux_bpf_prog_security(prog); 7097 7097 return avc_has_perm(sid, bpfsec->sid, SECCLASS_BPF, 7098 7098 BPF__PROG_RUN, NULL); 7099 7099 } ··· 7103 7103 { 7104 7104 struct bpf_security_struct *bpfsec; 7105 7105 7106 - bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); 7107 - if (!bpfsec) 7108 - return -ENOMEM; 7109 - 7106 + bpfsec = selinux_bpf_map_security(map); 7110 7107 bpfsec->sid = current_sid(); 7111 - map->security = bpfsec; 7112 7108 7113 7109 return 0; 7114 - } 7115 - 7116 - static void selinux_bpf_map_free(struct bpf_map *map) 7117 - { 7118 - struct bpf_security_struct *bpfsec = map->security; 7119 - 7120 - map->security = NULL; 7121 - kfree(bpfsec); 7122 7110 } 7123 7111 7124 7112 static int selinux_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, ··· 7114 7126 { 7115 7127 struct bpf_security_struct *bpfsec; 7116 7128 7117 - bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); 7118 - if (!bpfsec) 7119 - return -ENOMEM; 7120 - 7129 + bpfsec = selinux_bpf_prog_security(prog); 7121 7130 bpfsec->sid = current_sid(); 7122 - prog->aux->security = bpfsec; 7123 7131 7124 7132 return 0; 7125 - } 7126 - 7127 - static void selinux_bpf_prog_free(struct bpf_prog *prog) 7128 - { 7129 - struct bpf_security_struct *bpfsec = prog->aux->security; 7130 - 7131 - prog->aux->security = NULL; 7132 - kfree(bpfsec); 7133 7133 } 7134 7134 7135 7135 static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, ··· 7125 7149 { 7126 7150 struct bpf_security_struct *bpfsec; 7127 7151 7128 - bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); 7129 - if (!bpfsec) 7130 - return -ENOMEM; 7131 - 7152 + bpfsec = selinux_bpf_token_security(token); 7132 7153 bpfsec->sid = current_sid(); 7133 - token->security = bpfsec; 7134 7154 7135 7155 return 0; 7136 - } 7137 - 7138 - static void selinux_bpf_token_free(struct bpf_token *token) 7139 - { 7140 - struct bpf_security_struct *bpfsec = token->security; 7141 - 7142 - token->security = NULL; 7143 - kfree(bpfsec); 7144 7156 } 7145 7157 #endif 7146 7158 ··· 7147 7183 .lbs_xattr_count = SELINUX_INODE_INIT_XATTRS, 7148 7184 .lbs_tun_dev = sizeof(struct tun_security_struct), 7149 7185 .lbs_ib = sizeof(struct ib_security_struct), 7186 + .lbs_bpf_map = sizeof(struct bpf_security_struct), 7187 + .lbs_bpf_prog = sizeof(struct bpf_security_struct), 7188 + .lbs_bpf_token = sizeof(struct bpf_security_struct), 7150 7189 }; 7151 7190 7152 7191 #ifdef CONFIG_PERF_EVENTS ··· 7503 7536 LSM_HOOK_INIT(bpf, selinux_bpf), 7504 7537 LSM_HOOK_INIT(bpf_map, selinux_bpf_map), 7505 7538 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog), 7506 - LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free), 7507 - LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free), 7508 - LSM_HOOK_INIT(bpf_token_free, selinux_bpf_token_free), 7509 7539 #endif 7510 7540 7511 7541 #ifdef CONFIG_PERF_EVENTS
+20
security/selinux/include/objsec.h
··· 26 26 #include <linux/lsm_hooks.h> 27 27 #include <linux/msg.h> 28 28 #include <net/net_namespace.h> 29 + #include <linux/bpf.h> 29 30 #include "flask.h" 30 31 #include "avc.h" 31 32 ··· 246 245 return perf_event + selinux_blob_sizes.lbs_perf_event; 247 246 } 248 247 248 + #ifdef CONFIG_BPF_SYSCALL 249 + static inline struct bpf_security_struct * 250 + selinux_bpf_map_security(struct bpf_map *map) 251 + { 252 + return map->security + selinux_blob_sizes.lbs_bpf_map; 253 + } 254 + 255 + static inline struct bpf_security_struct * 256 + selinux_bpf_prog_security(struct bpf_prog *prog) 257 + { 258 + return prog->aux->security + selinux_blob_sizes.lbs_bpf_prog; 259 + } 260 + 261 + static inline struct bpf_security_struct * 262 + selinux_bpf_token_security(struct bpf_token *token) 263 + { 264 + return token->security + selinux_blob_sizes.lbs_bpf_token; 265 + } 266 + #endif /* CONFIG_BPF_SYSCALL */ 249 267 #endif /* _SELINUX_OBJSEC_H_ */