diff options
| -rw-r--r-- | include/linux/lsm_audit.h | 8 | ||||
| -rw-r--r-- | security/lsm_audit.c | 5 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 25 | ||||
| -rw-r--r-- | security/selinux/include/classmap.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 2 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 41 |
6 files changed, 83 insertions, 0 deletions
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index 0df5639a4ff4..22b5d4e687ce 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/path.h> | 21 | #include <linux/path.h> |
| 22 | #include <linux/key.h> | 22 | #include <linux/key.h> |
| 23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
| 24 | #include <rdma/ib_verbs.h> | ||
| 24 | 25 | ||
| 25 | struct lsm_network_audit { | 26 | struct lsm_network_audit { |
| 26 | int netif; | 27 | int netif; |
| @@ -50,6 +51,11 @@ struct lsm_ibpkey_audit { | |||
| 50 | u16 pkey; | 51 | u16 pkey; |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 54 | struct lsm_ibendport_audit { | ||
| 55 | char dev_name[IB_DEVICE_NAME_MAX]; | ||
| 56 | u8 port; | ||
| 57 | }; | ||
| 58 | |||
| 53 | /* Auxiliary data to use in generating the audit record. */ | 59 | /* Auxiliary data to use in generating the audit record. */ |
| 54 | struct common_audit_data { | 60 | struct common_audit_data { |
| 55 | char type; | 61 | char type; |
| @@ -66,6 +72,7 @@ struct common_audit_data { | |||
| 66 | #define LSM_AUDIT_DATA_IOCTL_OP 11 | 72 | #define LSM_AUDIT_DATA_IOCTL_OP 11 |
| 67 | #define LSM_AUDIT_DATA_FILE 12 | 73 | #define LSM_AUDIT_DATA_FILE 12 |
| 68 | #define LSM_AUDIT_DATA_IBPKEY 13 | 74 | #define LSM_AUDIT_DATA_IBPKEY 13 |
| 75 | #define LSM_AUDIT_DATA_IBENDPORT 14 | ||
| 69 | union { | 76 | union { |
| 70 | struct path path; | 77 | struct path path; |
| 71 | struct dentry *dentry; | 78 | struct dentry *dentry; |
| @@ -84,6 +91,7 @@ struct common_audit_data { | |||
| 84 | struct lsm_ioctlop_audit *op; | 91 | struct lsm_ioctlop_audit *op; |
| 85 | struct file *file; | 92 | struct file *file; |
| 86 | struct lsm_ibpkey_audit *ibpkey; | 93 | struct lsm_ibpkey_audit *ibpkey; |
| 94 | struct lsm_ibendport_audit *ibendport; | ||
| 87 | } u; | 95 | } u; |
| 88 | /* this union contains LSM specific data */ | 96 | /* this union contains LSM specific data */ |
| 89 | union { | 97 | union { |
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index c22c99fae06a..28d4c3a528ab 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
| @@ -421,6 +421,11 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
| 421 | a->u.ibpkey->pkey, &sbn_pfx); | 421 | a->u.ibpkey->pkey, &sbn_pfx); |
| 422 | break; | 422 | break; |
| 423 | } | 423 | } |
| 424 | case LSM_AUDIT_DATA_IBENDPORT: | ||
| 425 | audit_log_format(ab, " device=%s port_num=%u", | ||
| 426 | a->u.ibendport->dev_name, | ||
| 427 | a->u.ibendport->port); | ||
| 428 | break; | ||
| 424 | } /* switch (a->type) */ | 429 | } /* switch (a->type) */ |
| 425 | } | 430 | } |
| 426 | 431 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b59255f86274..91ec46dd34d9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -6169,6 +6169,29 @@ static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val) | |||
| 6169 | INFINIBAND_PKEY__ACCESS, &ad); | 6169 | INFINIBAND_PKEY__ACCESS, &ad); |
| 6170 | } | 6170 | } |
| 6171 | 6171 | ||
| 6172 | static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name, | ||
| 6173 | u8 port_num) | ||
| 6174 | { | ||
| 6175 | struct common_audit_data ad; | ||
| 6176 | int err; | ||
| 6177 | u32 sid = 0; | ||
| 6178 | struct ib_security_struct *sec = ib_sec; | ||
| 6179 | struct lsm_ibendport_audit ibendport; | ||
| 6180 | |||
| 6181 | err = security_ib_endport_sid(dev_name, port_num, &sid); | ||
| 6182 | |||
| 6183 | if (err) | ||
| 6184 | return err; | ||
| 6185 | |||
| 6186 | ad.type = LSM_AUDIT_DATA_IBENDPORT; | ||
| 6187 | strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name)); | ||
| 6188 | ibendport.port = port_num; | ||
| 6189 | ad.u.ibendport = &ibendport; | ||
| 6190 | return avc_has_perm(sec->sid, sid, | ||
| 6191 | SECCLASS_INFINIBAND_ENDPORT, | ||
| 6192 | INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad); | ||
| 6193 | } | ||
| 6194 | |||
| 6172 | static int selinux_ib_alloc_security(void **ib_sec) | 6195 | static int selinux_ib_alloc_security(void **ib_sec) |
| 6173 | { | 6196 | { |
| 6174 | struct ib_security_struct *sec; | 6197 | struct ib_security_struct *sec; |
| @@ -6374,6 +6397,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
| 6374 | LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), | 6397 | LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), |
| 6375 | #ifdef CONFIG_SECURITY_INFINIBAND | 6398 | #ifdef CONFIG_SECURITY_INFINIBAND |
| 6376 | LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access), | 6399 | LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access), |
| 6400 | LSM_HOOK_INIT(ib_endport_manage_subnet, | ||
| 6401 | selinux_ib_endport_manage_subnet), | ||
| 6377 | LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security), | 6402 | LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security), |
| 6378 | LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security), | 6403 | LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security), |
| 6379 | #endif | 6404 | #endif |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index 0fec1c505f84..b9fe3434b036 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
| @@ -233,6 +233,8 @@ struct security_class_mapping secclass_map[] = { | |||
| 233 | { COMMON_SOCK_PERMS, NULL } }, | 233 | { COMMON_SOCK_PERMS, NULL } }, |
| 234 | { "infiniband_pkey", | 234 | { "infiniband_pkey", |
| 235 | { "access", NULL } }, | 235 | { "access", NULL } }, |
| 236 | { "infiniband_endport", | ||
| 237 | { "manage_subnet", NULL } }, | ||
| 236 | { NULL } | 238 | { NULL } |
| 237 | }; | 239 | }; |
| 238 | 240 | ||
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 592c014e369c..e91f08c16c0b 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -183,6 +183,8 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid); | |||
| 183 | 183 | ||
| 184 | int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid); | 184 | int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid); |
| 185 | 185 | ||
| 186 | int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid); | ||
| 187 | |||
| 186 | int security_netif_sid(char *name, u32 *if_sid); | 188 | int security_netif_sid(char *name, u32 *if_sid); |
| 187 | 189 | ||
| 188 | int security_node_sid(u16 domain, void *addr, u32 addrlen, | 190 | int security_node_sid(u16 domain, void *addr, u32 addrlen, |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 02257d90adc9..202166612b80 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -2273,6 +2273,47 @@ out: | |||
| 2273 | } | 2273 | } |
| 2274 | 2274 | ||
| 2275 | /** | 2275 | /** |
| 2276 | * security_ib_endport_sid - Obtain the SID for a subnet management interface. | ||
| 2277 | * @dev_name: device name | ||
| 2278 | * @port: port number | ||
| 2279 | * @out_sid: security identifier | ||
| 2280 | */ | ||
| 2281 | int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid) | ||
| 2282 | { | ||
| 2283 | struct ocontext *c; | ||
| 2284 | int rc = 0; | ||
| 2285 | |||
| 2286 | read_lock(&policy_rwlock); | ||
| 2287 | |||
| 2288 | c = policydb.ocontexts[OCON_IBENDPORT]; | ||
| 2289 | while (c) { | ||
| 2290 | if (c->u.ibendport.port == port_num && | ||
| 2291 | !strncmp(c->u.ibendport.dev_name, | ||
| 2292 | dev_name, | ||
| 2293 | IB_DEVICE_NAME_MAX)) | ||
| 2294 | break; | ||
| 2295 | |||
| 2296 | c = c->next; | ||
| 2297 | } | ||
| 2298 | |||
| 2299 | if (c) { | ||
| 2300 | if (!c->sid[0]) { | ||
| 2301 | rc = sidtab_context_to_sid(&sidtab, | ||
| 2302 | &c->context[0], | ||
| 2303 | &c->sid[0]); | ||
| 2304 | if (rc) | ||
| 2305 | goto out; | ||
| 2306 | } | ||
| 2307 | *out_sid = c->sid[0]; | ||
| 2308 | } else | ||
| 2309 | *out_sid = SECINITSID_UNLABELED; | ||
| 2310 | |||
| 2311 | out: | ||
| 2312 | read_unlock(&policy_rwlock); | ||
| 2313 | return rc; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | /** | ||
| 2276 | * security_netif_sid - Obtain the SID for a network interface. | 2317 | * security_netif_sid - Obtain the SID for a network interface. |
| 2277 | * @name: interface name | 2318 | * @name: interface name |
| 2278 | * @if_sid: interface SID | 2319 | * @if_sid: interface SID |
