summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/Makefile3
-rw-r--r--drivers/infiniband/core/cache.c43
-rw-r--r--drivers/infiniband/core/core_priv.h115
-rw-r--r--drivers/infiniband/core/device.c86
-rw-r--r--drivers/infiniband/core/mad.c52
-rw-r--r--drivers/infiniband/core/security.c705
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c15
-rw-r--r--drivers/infiniband/core/verbs.c27
-rw-r--r--fs/nfs/super.c17
-rw-r--r--include/linux/lsm_audit.h15
-rw-r--r--include/linux/lsm_hooks.h39
-rw-r--r--include/linux/security.h58
-rw-r--r--include/rdma/ib_mad.h4
-rw-r--r--include/rdma/ib_verbs.h49
-rw-r--r--security/Kconfig9
-rw-r--r--security/lsm_audit.c16
-rw-r--r--security/security.c55
-rw-r--r--security/selinux/Makefile2
-rw-r--r--security/selinux/hooks.c212
-rw-r--r--security/selinux/ibpkey.c245
-rw-r--r--security/selinux/include/classmap.h6
-rw-r--r--security/selinux/include/ibpkey.h31
-rw-r--r--security/selinux/include/objsec.h11
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/selinuxfs.c15
-rw-r--r--security/selinux/ss/ebitmap.c26
-rw-r--r--security/selinux/ss/ebitmap.h3
-rw-r--r--security/selinux/ss/policydb.c127
-rw-r--r--security/selinux/ss/policydb.h27
-rw-r--r--security/selinux/ss/services.c108
-rw-r--r--security/selinux/ss/sidtab.c27
31 files changed, 2028 insertions, 129 deletions
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 6ebd9ad95010..e3cdafff8ece 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -10,7 +10,8 @@ obj-$(CONFIG_INFINIBAND_USER_ACCESS) += ib_uverbs.o ib_ucm.o \
10ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \ 10ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \
11 device.o fmr_pool.o cache.o netlink.o \ 11 device.o fmr_pool.o cache.o netlink.o \
12 roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \ 12 roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
13 multicast.o mad.o smi.o agent.o mad_rmpp.o 13 multicast.o mad.o smi.o agent.o mad_rmpp.o \
14 security.o
14ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o 15ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
15ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o 16ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o
16ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o 17ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index b1371eb9f46c..efc94304dee3 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -53,6 +53,7 @@ struct ib_update_work {
53 struct work_struct work; 53 struct work_struct work;
54 struct ib_device *device; 54 struct ib_device *device;
55 u8 port_num; 55 u8 port_num;
56 bool enforce_security;
56}; 57};
57 58
58union ib_gid zgid; 59union ib_gid zgid;
@@ -911,6 +912,26 @@ int ib_get_cached_pkey(struct ib_device *device,
911} 912}
912EXPORT_SYMBOL(ib_get_cached_pkey); 913EXPORT_SYMBOL(ib_get_cached_pkey);
913 914
915int ib_get_cached_subnet_prefix(struct ib_device *device,
916 u8 port_num,
917 u64 *sn_pfx)
918{
919 unsigned long flags;
920 int p;
921
922 if (port_num < rdma_start_port(device) ||
923 port_num > rdma_end_port(device))
924 return -EINVAL;
925
926 p = port_num - rdma_start_port(device);
927 read_lock_irqsave(&device->cache.lock, flags);
928 *sn_pfx = device->cache.ports[p].subnet_prefix;
929 read_unlock_irqrestore(&device->cache.lock, flags);
930
931 return 0;
932}
933EXPORT_SYMBOL(ib_get_cached_subnet_prefix);
934
914int ib_find_cached_pkey(struct ib_device *device, 935int ib_find_cached_pkey(struct ib_device *device,
915 u8 port_num, 936 u8 port_num,
916 u16 pkey, 937 u16 pkey,
@@ -1022,7 +1043,8 @@ int ib_get_cached_port_state(struct ib_device *device,
1022EXPORT_SYMBOL(ib_get_cached_port_state); 1043EXPORT_SYMBOL(ib_get_cached_port_state);
1023 1044
1024static void ib_cache_update(struct ib_device *device, 1045static void ib_cache_update(struct ib_device *device,
1025 u8 port) 1046 u8 port,
1047 bool enforce_security)
1026{ 1048{
1027 struct ib_port_attr *tprops = NULL; 1049 struct ib_port_attr *tprops = NULL;
1028 struct ib_pkey_cache *pkey_cache = NULL, *old_pkey_cache; 1050 struct ib_pkey_cache *pkey_cache = NULL, *old_pkey_cache;
@@ -1108,8 +1130,15 @@ static void ib_cache_update(struct ib_device *device,
1108 device->cache.ports[port - rdma_start_port(device)].port_state = 1130 device->cache.ports[port - rdma_start_port(device)].port_state =
1109 tprops->state; 1131 tprops->state;
1110 1132
1133 device->cache.ports[port - rdma_start_port(device)].subnet_prefix =
1134 tprops->subnet_prefix;
1111 write_unlock_irq(&device->cache.lock); 1135 write_unlock_irq(&device->cache.lock);
1112 1136
1137 if (enforce_security)
1138 ib_security_cache_change(device,
1139 port,
1140 tprops->subnet_prefix);
1141
1113 kfree(gid_cache); 1142 kfree(gid_cache);
1114 kfree(old_pkey_cache); 1143 kfree(old_pkey_cache);
1115 kfree(tprops); 1144 kfree(tprops);
@@ -1126,7 +1155,9 @@ static void ib_cache_task(struct work_struct *_work)
1126 struct ib_update_work *work = 1155 struct ib_update_work *work =
1127 container_of(_work, struct ib_update_work, work); 1156 container_of(_work, struct ib_update_work, work);
1128 1157
1129 ib_cache_update(work->device, work->port_num); 1158 ib_cache_update(work->device,
1159 work->port_num,
1160 work->enforce_security);
1130 kfree(work); 1161 kfree(work);
1131} 1162}
1132 1163
@@ -1147,6 +1178,12 @@ static void ib_cache_event(struct ib_event_handler *handler,
1147 INIT_WORK(&work->work, ib_cache_task); 1178 INIT_WORK(&work->work, ib_cache_task);
1148 work->device = event->device; 1179 work->device = event->device;
1149 work->port_num = event->element.port_num; 1180 work->port_num = event->element.port_num;
1181 if (event->event == IB_EVENT_PKEY_CHANGE ||
1182 event->event == IB_EVENT_GID_CHANGE)
1183 work->enforce_security = true;
1184 else
1185 work->enforce_security = false;
1186
1150 queue_work(ib_wq, &work->work); 1187 queue_work(ib_wq, &work->work);
1151 } 1188 }
1152 } 1189 }
@@ -1172,7 +1209,7 @@ int ib_cache_setup_one(struct ib_device *device)
1172 goto out; 1209 goto out;
1173 1210
1174 for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p) 1211 for (p = 0; p <= rdma_end_port(device) - rdma_start_port(device); ++p)
1175 ib_cache_update(device, p + rdma_start_port(device)); 1212 ib_cache_update(device, p + rdma_start_port(device), true);
1176 1213
1177 INIT_IB_EVENT_HANDLER(&device->cache.event_handler, 1214 INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
1178 device, ib_cache_event); 1215 device, ib_cache_event);
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index cb7d372e4bdf..06645272c784 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,6 +38,16 @@
38#include <linux/cgroup_rdma.h> 38#include <linux/cgroup_rdma.h>
39 39
40#include <rdma/ib_verbs.h> 40#include <rdma/ib_verbs.h>
41#include <rdma/ib_mad.h>
42#include "mad_priv.h"
43
44struct pkey_index_qp_list {
45 struct list_head pkey_index_list;
46 u16 pkey_index;
47 /* Lock to hold while iterating the qp_list. */
48 spinlock_t qp_list_lock;
49 struct list_head qp_list;
50};
41 51
42#if IS_ENABLED(CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS) 52#if IS_ENABLED(CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS)
43int cma_configfs_init(void); 53int cma_configfs_init(void);
@@ -176,4 +186,109 @@ int ib_nl_handle_set_timeout(struct sk_buff *skb,
176int ib_nl_handle_ip_res_resp(struct sk_buff *skb, 186int ib_nl_handle_ip_res_resp(struct sk_buff *skb,
177 struct netlink_callback *cb); 187 struct netlink_callback *cb);
178 188
189int ib_get_cached_subnet_prefix(struct ib_device *device,
190 u8 port_num,
191 u64 *sn_pfx);
192
193#ifdef CONFIG_SECURITY_INFINIBAND
194int ib_security_pkey_access(struct ib_device *dev,
195 u8 port_num,
196 u16 pkey_index,
197 void *sec);
198
199void ib_security_destroy_port_pkey_list(struct ib_device *device);
200
201void ib_security_cache_change(struct ib_device *device,
202 u8 port_num,
203 u64 subnet_prefix);
204
205int ib_security_modify_qp(struct ib_qp *qp,
206 struct ib_qp_attr *qp_attr,
207 int qp_attr_mask,
208 struct ib_udata *udata);
209
210int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev);
211void ib_destroy_qp_security_begin(struct ib_qp_security *sec);
212void ib_destroy_qp_security_abort(struct ib_qp_security *sec);
213void ib_destroy_qp_security_end(struct ib_qp_security *sec);
214int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev);
215void ib_close_shared_qp_security(struct ib_qp_security *sec);
216int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
217 enum ib_qp_type qp_type);
218void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent);
219int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index);
220#else
221static inline int ib_security_pkey_access(struct ib_device *dev,
222 u8 port_num,
223 u16 pkey_index,
224 void *sec)
225{
226 return 0;
227}
228
229static inline void ib_security_destroy_port_pkey_list(struct ib_device *device)
230{
231}
232
233static inline void ib_security_cache_change(struct ib_device *device,
234 u8 port_num,
235 u64 subnet_prefix)
236{
237}
238
239static inline int ib_security_modify_qp(struct ib_qp *qp,
240 struct ib_qp_attr *qp_attr,
241 int qp_attr_mask,
242 struct ib_udata *udata)
243{
244 return qp->device->modify_qp(qp->real_qp,
245 qp_attr,
246 qp_attr_mask,
247 udata);
248}
249
250static inline int ib_create_qp_security(struct ib_qp *qp,
251 struct ib_device *dev)
252{
253 return 0;
254}
255
256static inline void ib_destroy_qp_security_begin(struct ib_qp_security *sec)
257{
258}
259
260static inline void ib_destroy_qp_security_abort(struct ib_qp_security *sec)
261{
262}
263
264static inline void ib_destroy_qp_security_end(struct ib_qp_security *sec)
265{
266}
267
268static inline int ib_open_shared_qp_security(struct ib_qp *qp,
269 struct ib_device *dev)
270{
271 return 0;
272}
273
274static inline void ib_close_shared_qp_security(struct ib_qp_security *sec)
275{
276}
277
278static inline int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
279 enum ib_qp_type qp_type)
280{
281 return 0;
282}
283
284static inline void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent)
285{
286}
287
288static inline int ib_mad_enforce_security(struct ib_mad_agent_private *map,
289 u16 pkey_index)
290{
291 return 0;
292}
293#endif
179#endif /* _CORE_PRIV_H */ 294#endif /* _CORE_PRIV_H */
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 81d447da0048..631eaa9daf65 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -39,6 +39,8 @@
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/mutex.h> 40#include <linux/mutex.h>
41#include <linux/netdevice.h> 41#include <linux/netdevice.h>
42#include <linux/security.h>
43#include <linux/notifier.h>
42#include <rdma/rdma_netlink.h> 44#include <rdma/rdma_netlink.h>
43#include <rdma/ib_addr.h> 45#include <rdma/ib_addr.h>
44#include <rdma/ib_cache.h> 46#include <rdma/ib_cache.h>
@@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
82static DEFINE_MUTEX(device_mutex); 84static DEFINE_MUTEX(device_mutex);
83static DECLARE_RWSEM(lists_rwsem); 85static DECLARE_RWSEM(lists_rwsem);
84 86
87static int ib_security_change(struct notifier_block *nb, unsigned long event,
88 void *lsm_data);
89static void ib_policy_change_task(struct work_struct *work);
90static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
91
92static struct notifier_block ibdev_lsm_nb = {
93 .notifier_call = ib_security_change,
94};
85 95
86static int ib_device_check_mandatory(struct ib_device *device) 96static int ib_device_check_mandatory(struct ib_device *device)
87{ 97{
@@ -325,6 +335,64 @@ void ib_get_device_fw_str(struct ib_device *dev, char *str, size_t str_len)
325} 335}
326EXPORT_SYMBOL(ib_get_device_fw_str); 336EXPORT_SYMBOL(ib_get_device_fw_str);
327 337
338static int setup_port_pkey_list(struct ib_device *device)
339{
340 int i;
341
342 /**
343 * device->port_pkey_list is indexed directly by the port number,
344 * Therefore it is declared as a 1 based array with potential empty
345 * slots at the beginning.
346 */
347 device->port_pkey_list = kcalloc(rdma_end_port(device) + 1,
348 sizeof(*device->port_pkey_list),
349 GFP_KERNEL);
350
351 if (!device->port_pkey_list)
352 return -ENOMEM;
353
354 for (i = 0; i < (rdma_end_port(device) + 1); i++) {
355 spin_lock_init(&device->port_pkey_list[i].list_lock);
356 INIT_LIST_HEAD(&device->port_pkey_list[i].pkey_list);
357 }
358
359 return 0;
360}
361
362static void ib_policy_change_task(struct work_struct *work)
363{
364 struct ib_device *dev;
365
366 down_read(&lists_rwsem);
367 list_for_each_entry(dev, &device_list, core_list) {
368 int i;
369
370 for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
371 u64 sp;
372 int ret = ib_get_cached_subnet_prefix(dev,
373 i,
374 &sp);
375
376 WARN_ONCE(ret,
377 "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
378 ret);
379 ib_security_cache_change(dev, i, sp);
380 }
381 }
382 up_read(&lists_rwsem);
383}
384
385static int ib_security_change(struct notifier_block *nb, unsigned long event,
386 void *lsm_data)
387{
388 if (event != LSM_POLICY_CHANGE)
389 return NOTIFY_DONE;
390
391 schedule_work(&ib_policy_change_work);
392
393 return NOTIFY_OK;
394}
395
328/** 396/**
329 * ib_register_device - Register an IB device with IB core 397 * ib_register_device - Register an IB device with IB core
330 * @device:Device to register 398 * @device:Device to register
@@ -385,6 +453,12 @@ int ib_register_device(struct ib_device *device,
385 goto out; 453 goto out;
386 } 454 }
387 455
456 ret = setup_port_pkey_list(device);
457 if (ret) {
458 pr_warn("Couldn't create per port_pkey_list\n");
459 goto out;
460 }
461
388 ret = ib_cache_setup_one(device); 462 ret = ib_cache_setup_one(device);
389 if (ret) { 463 if (ret) {
390 pr_warn("Couldn't set up InfiniBand P_Key/GID cache\n"); 464 pr_warn("Couldn't set up InfiniBand P_Key/GID cache\n");
@@ -468,6 +542,9 @@ void ib_unregister_device(struct ib_device *device)
468 ib_device_unregister_sysfs(device); 542 ib_device_unregister_sysfs(device);
469 ib_cache_cleanup_one(device); 543 ib_cache_cleanup_one(device);
470 544
545 ib_security_destroy_port_pkey_list(device);
546 kfree(device->port_pkey_list);
547
471 down_write(&lists_rwsem); 548 down_write(&lists_rwsem);
472 spin_lock_irqsave(&device->client_data_lock, flags); 549 spin_lock_irqsave(&device->client_data_lock, flags);
473 list_for_each_entry_safe(context, tmp, &device->client_data_list, list) 550 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
@@ -1082,10 +1159,18 @@ static int __init ib_core_init(void)
1082 goto err_sa; 1159 goto err_sa;
1083 } 1160 }
1084 1161
1162 ret = register_lsm_notifier(&ibdev_lsm_nb);
1163 if (ret) {
1164 pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
1165 goto err_ibnl_clients;
1166 }
1167
1085 ib_cache_setup(); 1168 ib_cache_setup();
1086 1169
1087 return 0; 1170 return 0;
1088 1171
1172err_ibnl_clients:
1173 ib_remove_ibnl_clients();
1089err_sa: 1174err_sa:
1090 ib_sa_cleanup(); 1175 ib_sa_cleanup();
1091err_mad: 1176err_mad:
@@ -1105,6 +1190,7 @@ err:
1105 1190
1106static void __exit ib_core_cleanup(void) 1191static void __exit ib_core_cleanup(void)
1107{ 1192{
1193 unregister_lsm_notifier(&ibdev_lsm_nb);
1108 ib_cache_cleanup(); 1194 ib_cache_cleanup();
1109 ib_remove_ibnl_clients(); 1195 ib_remove_ibnl_clients();
1110 ib_sa_cleanup(); 1196 ib_sa_cleanup();
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 192ee3dafb80..f8f53bb90837 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -40,9 +40,11 @@
40#include <linux/dma-mapping.h> 40#include <linux/dma-mapping.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/security.h>
43#include <rdma/ib_cache.h> 44#include <rdma/ib_cache.h>
44 45
45#include "mad_priv.h" 46#include "mad_priv.h"
47#include "core_priv.h"
46#include "mad_rmpp.h" 48#include "mad_rmpp.h"
47#include "smi.h" 49#include "smi.h"
48#include "opa_smi.h" 50#include "opa_smi.h"
@@ -369,6 +371,12 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
369 atomic_set(&mad_agent_priv->refcount, 1); 371 atomic_set(&mad_agent_priv->refcount, 1);
370 init_completion(&mad_agent_priv->comp); 372 init_completion(&mad_agent_priv->comp);
371 373
374 ret2 = ib_mad_agent_security_setup(&mad_agent_priv->agent, qp_type);
375 if (ret2) {
376 ret = ERR_PTR(ret2);
377 goto error4;
378 }
379
372 spin_lock_irqsave(&port_priv->reg_lock, flags); 380 spin_lock_irqsave(&port_priv->reg_lock, flags);
373 mad_agent_priv->agent.hi_tid = ++ib_mad_client_id; 381 mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
374 382
@@ -386,7 +394,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
386 if (method) { 394 if (method) {
387 if (method_in_use(&method, 395 if (method_in_use(&method,
388 mad_reg_req)) 396 mad_reg_req))
389 goto error4; 397 goto error5;
390 } 398 }
391 } 399 }
392 ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv, 400 ret2 = add_nonoui_reg_req(mad_reg_req, mad_agent_priv,
@@ -402,14 +410,14 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
402 if (is_vendor_method_in_use( 410 if (is_vendor_method_in_use(
403 vendor_class, 411 vendor_class,
404 mad_reg_req)) 412 mad_reg_req))
405 goto error4; 413 goto error5;
406 } 414 }
407 } 415 }
408 ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv); 416 ret2 = add_oui_reg_req(mad_reg_req, mad_agent_priv);
409 } 417 }
410 if (ret2) { 418 if (ret2) {
411 ret = ERR_PTR(ret2); 419 ret = ERR_PTR(ret2);
412 goto error4; 420 goto error5;
413 } 421 }
414 } 422 }
415 423
@@ -418,9 +426,10 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
418 spin_unlock_irqrestore(&port_priv->reg_lock, flags); 426 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
419 427
420 return &mad_agent_priv->agent; 428 return &mad_agent_priv->agent;
421 429error5:
422error4:
423 spin_unlock_irqrestore(&port_priv->reg_lock, flags); 430 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
431 ib_mad_agent_security_cleanup(&mad_agent_priv->agent);
432error4:
424 kfree(reg_req); 433 kfree(reg_req);
425error3: 434error3:
426 kfree(mad_agent_priv); 435 kfree(mad_agent_priv);
@@ -491,6 +500,7 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
491 struct ib_mad_agent *ret; 500 struct ib_mad_agent *ret;
492 struct ib_mad_snoop_private *mad_snoop_priv; 501 struct ib_mad_snoop_private *mad_snoop_priv;
493 int qpn; 502 int qpn;
503 int err;
494 504
495 /* Validate parameters */ 505 /* Validate parameters */
496 if ((is_snooping_sends(mad_snoop_flags) && !snoop_handler) || 506 if ((is_snooping_sends(mad_snoop_flags) && !snoop_handler) ||
@@ -525,17 +535,25 @@ struct ib_mad_agent *ib_register_mad_snoop(struct ib_device *device,
525 mad_snoop_priv->agent.port_num = port_num; 535 mad_snoop_priv->agent.port_num = port_num;
526 mad_snoop_priv->mad_snoop_flags = mad_snoop_flags; 536 mad_snoop_priv->mad_snoop_flags = mad_snoop_flags;
527 init_completion(&mad_snoop_priv->comp); 537 init_completion(&mad_snoop_priv->comp);
538
539 err = ib_mad_agent_security_setup(&mad_snoop_priv->agent, qp_type);
540 if (err) {
541 ret = ERR_PTR(err);
542 goto error2;
543 }
544
528 mad_snoop_priv->snoop_index = register_snoop_agent( 545 mad_snoop_priv->snoop_index = register_snoop_agent(
529 &port_priv->qp_info[qpn], 546 &port_priv->qp_info[qpn],
530 mad_snoop_priv); 547 mad_snoop_priv);
531 if (mad_snoop_priv->snoop_index < 0) { 548 if (mad_snoop_priv->snoop_index < 0) {
532 ret = ERR_PTR(mad_snoop_priv->snoop_index); 549 ret = ERR_PTR(mad_snoop_priv->snoop_index);
533 goto error2; 550 goto error3;
534 } 551 }
535 552
536 atomic_set(&mad_snoop_priv->refcount, 1); 553 atomic_set(&mad_snoop_priv->refcount, 1);
537 return &mad_snoop_priv->agent; 554 return &mad_snoop_priv->agent;
538 555error3:
556 ib_mad_agent_security_cleanup(&mad_snoop_priv->agent);
539error2: 557error2:
540 kfree(mad_snoop_priv); 558 kfree(mad_snoop_priv);
541error1: 559error1:
@@ -581,6 +599,8 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
581 deref_mad_agent(mad_agent_priv); 599 deref_mad_agent(mad_agent_priv);
582 wait_for_completion(&mad_agent_priv->comp); 600 wait_for_completion(&mad_agent_priv->comp);
583 601
602 ib_mad_agent_security_cleanup(&mad_agent_priv->agent);
603
584 kfree(mad_agent_priv->reg_req); 604 kfree(mad_agent_priv->reg_req);
585 kfree(mad_agent_priv); 605 kfree(mad_agent_priv);
586} 606}
@@ -599,6 +619,8 @@ static void unregister_mad_snoop(struct ib_mad_snoop_private *mad_snoop_priv)
599 deref_snoop_agent(mad_snoop_priv); 619 deref_snoop_agent(mad_snoop_priv);
600 wait_for_completion(&mad_snoop_priv->comp); 620 wait_for_completion(&mad_snoop_priv->comp);
601 621
622 ib_mad_agent_security_cleanup(&mad_snoop_priv->agent);
623
602 kfree(mad_snoop_priv); 624 kfree(mad_snoop_priv);
603} 625}
604 626
@@ -1215,12 +1237,16 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf,
1215 1237
1216 /* Walk list of send WRs and post each on send list */ 1238 /* Walk list of send WRs and post each on send list */
1217 for (; send_buf; send_buf = next_send_buf) { 1239 for (; send_buf; send_buf = next_send_buf) {
1218
1219 mad_send_wr = container_of(send_buf, 1240 mad_send_wr = container_of(send_buf,
1220 struct ib_mad_send_wr_private, 1241 struct ib_mad_send_wr_private,
1221 send_buf); 1242 send_buf);
1222 mad_agent_priv = mad_send_wr->mad_agent_priv; 1243 mad_agent_priv = mad_send_wr->mad_agent_priv;
1223 1244
1245 ret = ib_mad_enforce_security(mad_agent_priv,
1246 mad_send_wr->send_wr.pkey_index);
1247 if (ret)
1248 goto error;
1249
1224 if (!send_buf->mad_agent->send_handler || 1250 if (!send_buf->mad_agent->send_handler ||
1225 (send_buf->timeout_ms && 1251 (send_buf->timeout_ms &&
1226 !send_buf->mad_agent->recv_handler)) { 1252 !send_buf->mad_agent->recv_handler)) {
@@ -1946,6 +1972,14 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
1946 struct ib_mad_send_wr_private *mad_send_wr; 1972 struct ib_mad_send_wr_private *mad_send_wr;
1947 struct ib_mad_send_wc mad_send_wc; 1973 struct ib_mad_send_wc mad_send_wc;
1948 unsigned long flags; 1974 unsigned long flags;
1975 int ret;
1976
1977 ret = ib_mad_enforce_security(mad_agent_priv,
1978 mad_recv_wc->wc->pkey_index);
1979 if (ret) {
1980 ib_free_recv_mad(mad_recv_wc);
1981 deref_mad_agent(mad_agent_priv);
1982 }
1949 1983
1950 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); 1984 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
1951 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); 1985 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
@@ -2003,6 +2037,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
2003 mad_recv_wc); 2037 mad_recv_wc);
2004 deref_mad_agent(mad_agent_priv); 2038 deref_mad_agent(mad_agent_priv);
2005 } 2039 }
2040
2041 return;
2006} 2042}
2007 2043
2008static enum smi_action handle_ib_smi(const struct ib_mad_port_private *port_priv, 2044static enum smi_action handle_ib_smi(const struct ib_mad_port_private *port_priv,
diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c
new file mode 100644
index 000000000000..3e8c38953912
--- /dev/null
+++ b/drivers/infiniband/core/security.c
@@ -0,0 +1,705 @@
1/*
2 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#ifdef CONFIG_SECURITY_INFINIBAND
34
35#include <linux/security.h>
36#include <linux/completion.h>
37#include <linux/list.h>
38
39#include <rdma/ib_verbs.h>
40#include <rdma/ib_cache.h>
41#include "core_priv.h"
42#include "mad_priv.h"
43
44static struct pkey_index_qp_list *get_pkey_idx_qp_list(struct ib_port_pkey *pp)
45{
46 struct pkey_index_qp_list *pkey = NULL;
47 struct pkey_index_qp_list *tmp_pkey;
48 struct ib_device *dev = pp->sec->dev;
49
50 spin_lock(&dev->port_pkey_list[pp->port_num].list_lock);
51 list_for_each_entry(tmp_pkey,
52 &dev->port_pkey_list[pp->port_num].pkey_list,
53 pkey_index_list) {
54 if (tmp_pkey->pkey_index == pp->pkey_index) {
55 pkey = tmp_pkey;
56 break;
57 }
58 }
59 spin_unlock(&dev->port_pkey_list[pp->port_num].list_lock);
60 return pkey;
61}
62
63static int get_pkey_and_subnet_prefix(struct ib_port_pkey *pp,
64 u16 *pkey,
65 u64 *subnet_prefix)
66{
67 struct ib_device *dev = pp->sec->dev;
68 int ret;
69
70 ret = ib_get_cached_pkey(dev, pp->port_num, pp->pkey_index, pkey);
71 if (ret)
72 return ret;
73
74 ret = ib_get_cached_subnet_prefix(dev, pp->port_num, subnet_prefix);
75
76 return ret;
77}
78
79static int enforce_qp_pkey_security(u16 pkey,
80 u64 subnet_prefix,
81 struct ib_qp_security *qp_sec)
82{
83 struct ib_qp_security *shared_qp_sec;
84 int ret;
85
86 ret = security_ib_pkey_access(qp_sec->security, subnet_prefix, pkey);
87 if (ret)
88 return ret;
89
90 if (qp_sec->qp == qp_sec->qp->real_qp) {
91 list_for_each_entry(shared_qp_sec,
92 &qp_sec->shared_qp_list,
93 shared_qp_list) {
94 ret = security_ib_pkey_access(shared_qp_sec->security,
95 subnet_prefix,
96 pkey);
97 if (ret)
98 return ret;
99 }
100 }
101 return 0;
102}
103
104/* The caller of this function must hold the QP security
105 * mutex of the QP of the security structure in *pps.
106 *
107 * It takes separate ports_pkeys and security structure
108 * because in some cases the pps will be for a new settings
109 * or the pps will be for the real QP and security structure
110 * will be for a shared QP.
111 */
112static int check_qp_port_pkey_settings(struct ib_ports_pkeys *pps,
113 struct ib_qp_security *sec)
114{
115 u64 subnet_prefix;
116 u16 pkey;
117 int ret = 0;
118
119 if (!pps)
120 return 0;
121
122 if (pps->main.state != IB_PORT_PKEY_NOT_VALID) {
123 get_pkey_and_subnet_prefix(&pps->main,
124 &pkey,
125 &subnet_prefix);
126
127 ret = enforce_qp_pkey_security(pkey,
128 subnet_prefix,
129 sec);
130 }
131 if (ret)
132 return ret;
133
134 if (pps->alt.state != IB_PORT_PKEY_NOT_VALID) {
135 get_pkey_and_subnet_prefix(&pps->alt,
136 &pkey,
137 &subnet_prefix);
138
139 ret = enforce_qp_pkey_security(pkey,
140 subnet_prefix,
141 sec);
142 }
143
144 return ret;
145}
146
147/* The caller of this function must hold the QP security
148 * mutex.
149 */
150static void qp_to_error(struct ib_qp_security *sec)
151{
152 struct ib_qp_security *shared_qp_sec;
153 struct ib_qp_attr attr = {
154 .qp_state = IB_QPS_ERR
155 };
156 struct ib_event event = {
157 .event = IB_EVENT_QP_FATAL
158 };
159
160 /* If the QP is in the process of being destroyed
161 * the qp pointer in the security structure is
162 * undefined. It cannot be modified now.
163 */
164 if (sec->destroying)
165 return;
166
167 ib_modify_qp(sec->qp,
168 &attr,
169 IB_QP_STATE);
170
171 if (sec->qp->event_handler && sec->qp->qp_context) {
172 event.element.qp = sec->qp;
173 sec->qp->event_handler(&event,
174 sec->qp->qp_context);
175 }
176
177 list_for_each_entry(shared_qp_sec,
178 &sec->shared_qp_list,
179 shared_qp_list) {
180 struct ib_qp *qp = shared_qp_sec->qp;
181
182 if (qp->event_handler && qp->qp_context) {
183 event.element.qp = qp;
184 event.device = qp->device;
185 qp->event_handler(&event,
186 qp->qp_context);
187 }
188 }
189}
190
191static inline void check_pkey_qps(struct pkey_index_qp_list *pkey,
192 struct ib_device *device,
193 u8 port_num,
194 u64 subnet_prefix)
195{
196 struct ib_port_pkey *pp, *tmp_pp;
197 bool comp;
198 LIST_HEAD(to_error_list);
199 u16 pkey_val;
200
201 if (!ib_get_cached_pkey(device,
202 port_num,
203 pkey->pkey_index,
204 &pkey_val)) {
205 spin_lock(&pkey->qp_list_lock);
206 list_for_each_entry(pp, &pkey->qp_list, qp_list) {
207 if (atomic_read(&pp->sec->error_list_count))
208 continue;
209
210 if (enforce_qp_pkey_security(pkey_val,
211 subnet_prefix,
212 pp->sec)) {
213 atomic_inc(&pp->sec->error_list_count);
214 list_add(&pp->to_error_list,
215 &to_error_list);
216 }
217 }
218 spin_unlock(&pkey->qp_list_lock);
219 }
220
221 list_for_each_entry_safe(pp,
222 tmp_pp,
223 &to_error_list,
224 to_error_list) {
225 mutex_lock(&pp->sec->mutex);
226 qp_to_error(pp->sec);
227 list_del(&pp->to_error_list);
228 atomic_dec(&pp->sec->error_list_count);
229 comp = pp->sec->destroying;
230 mutex_unlock(&pp->sec->mutex);
231
232 if (comp)
233 complete(&pp->sec->error_complete);
234 }
235}
236
237/* The caller of this function must hold the QP security
238 * mutex.
239 */
240static int port_pkey_list_insert(struct ib_port_pkey *pp)
241{
242 struct pkey_index_qp_list *tmp_pkey;
243 struct pkey_index_qp_list *pkey;
244 struct ib_device *dev;
245 u8 port_num = pp->port_num;
246 int ret = 0;
247
248 if (pp->state != IB_PORT_PKEY_VALID)
249 return 0;
250
251 dev = pp->sec->dev;
252
253 pkey = get_pkey_idx_qp_list(pp);
254
255 if (!pkey) {
256 bool found = false;
257
258 pkey = kzalloc(sizeof(*pkey), GFP_KERNEL);
259 if (!pkey)
260 return -ENOMEM;
261
262 spin_lock(&dev->port_pkey_list[port_num].list_lock);
263 /* Check for the PKey again. A racing process may
264 * have created it.
265 */
266 list_for_each_entry(tmp_pkey,
267 &dev->port_pkey_list[port_num].pkey_list,
268 pkey_index_list) {
269 if (tmp_pkey->pkey_index == pp->pkey_index) {
270 kfree(pkey);
271 pkey = tmp_pkey;
272 found = true;
273 break;
274 }
275 }
276
277 if (!found) {
278 pkey->pkey_index = pp->pkey_index;
279 spin_lock_init(&pkey->qp_list_lock);
280 INIT_LIST_HEAD(&pkey->qp_list);
281 list_add(&pkey->pkey_index_list,
282 &dev->port_pkey_list[port_num].pkey_list);
283 }
284 spin_unlock(&dev->port_pkey_list[port_num].list_lock);
285 }
286
287 spin_lock(&pkey->qp_list_lock);
288 list_add(&pp->qp_list, &pkey->qp_list);
289 spin_unlock(&pkey->qp_list_lock);
290
291 pp->state = IB_PORT_PKEY_LISTED;
292
293 return ret;
294}
295
296/* The caller of this function must hold the QP security
297 * mutex.
298 */
299static void port_pkey_list_remove(struct ib_port_pkey *pp)
300{
301 struct pkey_index_qp_list *pkey;
302
303 if (pp->state != IB_PORT_PKEY_LISTED)
304 return;
305
306 pkey = get_pkey_idx_qp_list(pp);
307
308 spin_lock(&pkey->qp_list_lock);
309 list_del(&pp->qp_list);
310 spin_unlock(&pkey->qp_list_lock);
311
312 /* The setting may still be valid, i.e. after
313 * a destroy has failed for example.
314 */
315 pp->state = IB_PORT_PKEY_VALID;
316}
317
318static void destroy_qp_security(struct ib_qp_security *sec)
319{
320 security_ib_free_security(sec->security);
321 kfree(sec->ports_pkeys);
322 kfree(sec);
323}
324
325/* The caller of this function must hold the QP security
326 * mutex.
327 */
328static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp,
329 const struct ib_qp_attr *qp_attr,
330 int qp_attr_mask)
331{
332 struct ib_ports_pkeys *new_pps;
333 struct ib_ports_pkeys *qp_pps = qp->qp_sec->ports_pkeys;
334
335 new_pps = kzalloc(sizeof(*new_pps), GFP_KERNEL);
336 if (!new_pps)
337 return NULL;
338
339 if (qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) {
340 if (!qp_pps) {
341 new_pps->main.port_num = qp_attr->port_num;
342 new_pps->main.pkey_index = qp_attr->pkey_index;
343 } else {
344 new_pps->main.port_num = (qp_attr_mask & IB_QP_PORT) ?
345 qp_attr->port_num :
346 qp_pps->main.port_num;
347
348 new_pps->main.pkey_index =
349 (qp_attr_mask & IB_QP_PKEY_INDEX) ?
350 qp_attr->pkey_index :
351 qp_pps->main.pkey_index;
352 }
353 new_pps->main.state = IB_PORT_PKEY_VALID;
354 } else if (qp_pps) {
355 new_pps->main.port_num = qp_pps->main.port_num;
356 new_pps->main.pkey_index = qp_pps->main.pkey_index;
357 if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)
358 new_pps->main.state = IB_PORT_PKEY_VALID;
359 }
360
361 if (qp_attr_mask & IB_QP_ALT_PATH) {
362 new_pps->alt.port_num = qp_attr->alt_port_num;
363 new_pps->alt.pkey_index = qp_attr->alt_pkey_index;
364 new_pps->alt.state = IB_PORT_PKEY_VALID;
365 } else if (qp_pps) {
366 new_pps->alt.port_num = qp_pps->alt.port_num;
367 new_pps->alt.pkey_index = qp_pps->alt.pkey_index;
368 if (qp_pps->alt.state != IB_PORT_PKEY_NOT_VALID)
369 new_pps->alt.state = IB_PORT_PKEY_VALID;
370 }
371
372 new_pps->main.sec = qp->qp_sec;
373 new_pps->alt.sec = qp->qp_sec;
374 return new_pps;
375}
376
377int ib_open_shared_qp_security(struct ib_qp *qp, struct ib_device *dev)
378{
379 struct ib_qp *real_qp = qp->real_qp;
380 int ret;
381
382 ret = ib_create_qp_security(qp, dev);
383
384 if (ret)
385 return ret;
386
387 mutex_lock(&real_qp->qp_sec->mutex);
388 ret = check_qp_port_pkey_settings(real_qp->qp_sec->ports_pkeys,
389 qp->qp_sec);
390
391 if (ret)
392 goto ret;
393
394 if (qp != real_qp)
395 list_add(&qp->qp_sec->shared_qp_list,
396 &real_qp->qp_sec->shared_qp_list);
397ret:
398 mutex_unlock(&real_qp->qp_sec->mutex);
399 if (ret)
400 destroy_qp_security(qp->qp_sec);
401
402 return ret;
403}
404
405void ib_close_shared_qp_security(struct ib_qp_security *sec)
406{
407 struct ib_qp *real_qp = sec->qp->real_qp;
408
409 mutex_lock(&real_qp->qp_sec->mutex);
410 list_del(&sec->shared_qp_list);
411 mutex_unlock(&real_qp->qp_sec->mutex);
412
413 destroy_qp_security(sec);
414}
415
416int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev)
417{
418 int ret;
419
420 qp->qp_sec = kzalloc(sizeof(*qp->qp_sec), GFP_KERNEL);
421 if (!qp->qp_sec)
422 return -ENOMEM;
423
424 qp->qp_sec->qp = qp;
425 qp->qp_sec->dev = dev;
426 mutex_init(&qp->qp_sec->mutex);
427 INIT_LIST_HEAD(&qp->qp_sec->shared_qp_list);
428 atomic_set(&qp->qp_sec->error_list_count, 0);
429 init_completion(&qp->qp_sec->error_complete);
430 ret = security_ib_alloc_security(&qp->qp_sec->security);
431 if (ret)
432 kfree(qp->qp_sec);
433
434 return ret;
435}
436EXPORT_SYMBOL(ib_create_qp_security);
437
438void ib_destroy_qp_security_begin(struct ib_qp_security *sec)
439{
440 mutex_lock(&sec->mutex);
441
442 /* Remove the QP from the lists so it won't get added to
443 * a to_error_list during the destroy process.
444 */
445 if (sec->ports_pkeys) {
446 port_pkey_list_remove(&sec->ports_pkeys->main);
447 port_pkey_list_remove(&sec->ports_pkeys->alt);
448 }
449
450 /* If the QP is already in one or more of those lists
451 * the destroying flag will ensure the to error flow
452 * doesn't operate on an undefined QP.
453 */
454 sec->destroying = true;
455
456 /* Record the error list count to know how many completions
457 * to wait for.
458 */
459 sec->error_comps_pending = atomic_read(&sec->error_list_count);
460
461 mutex_unlock(&sec->mutex);
462}
463
464void ib_destroy_qp_security_abort(struct ib_qp_security *sec)
465{
466 int ret;
467 int i;
468
469 /* If a concurrent cache update is in progress this
470 * QP security could be marked for an error state
471 * transition. Wait for this to complete.
472 */
473 for (i = 0; i < sec->error_comps_pending; i++)
474 wait_for_completion(&sec->error_complete);
475
476 mutex_lock(&sec->mutex);
477 sec->destroying = false;
478
479 /* Restore the position in the lists and verify
480 * access is still allowed in case a cache update
481 * occurred while attempting to destroy.
482 *
483 * Because these setting were listed already
484 * and removed during ib_destroy_qp_security_begin
485 * we know the pkey_index_qp_list for the PKey
486 * already exists so port_pkey_list_insert won't fail.
487 */
488 if (sec->ports_pkeys) {
489 port_pkey_list_insert(&sec->ports_pkeys->main);
490 port_pkey_list_insert(&sec->ports_pkeys->alt);
491 }
492
493 ret = check_qp_port_pkey_settings(sec->ports_pkeys, sec);
494 if (ret)
495 qp_to_error(sec);
496
497 mutex_unlock(&sec->mutex);
498}
499
500void ib_destroy_qp_security_end(struct ib_qp_security *sec)
501{
502 int i;
503
504 /* If a concurrent cache update is occurring we must
505 * wait until this QP security structure is processed
506 * in the QP to error flow before destroying it because
507 * the to_error_list is in use.
508 */
509 for (i = 0; i < sec->error_comps_pending; i++)
510 wait_for_completion(&sec->error_complete);
511
512 destroy_qp_security(sec);
513}
514
515void ib_security_cache_change(struct ib_device *device,
516 u8 port_num,
517 u64 subnet_prefix)
518{
519 struct pkey_index_qp_list *pkey;
520
521 list_for_each_entry(pkey,
522 &device->port_pkey_list[port_num].pkey_list,
523 pkey_index_list) {
524 check_pkey_qps(pkey,
525 device,
526 port_num,
527 subnet_prefix);
528 }
529}
530
531void ib_security_destroy_port_pkey_list(struct ib_device *device)
532{
533 struct pkey_index_qp_list *pkey, *tmp_pkey;
534 int i;
535
536 for (i = rdma_start_port(device); i <= rdma_end_port(device); i++) {
537 spin_lock(&device->port_pkey_list[i].list_lock);
538 list_for_each_entry_safe(pkey,
539 tmp_pkey,
540 &device->port_pkey_list[i].pkey_list,
541 pkey_index_list) {
542 list_del(&pkey->pkey_index_list);
543 kfree(pkey);
544 }
545 spin_unlock(&device->port_pkey_list[i].list_lock);
546 }
547}
548
549int ib_security_modify_qp(struct ib_qp *qp,
550 struct ib_qp_attr *qp_attr,
551 int qp_attr_mask,
552 struct ib_udata *udata)
553{
554 int ret = 0;
555 struct ib_ports_pkeys *tmp_pps;
556 struct ib_ports_pkeys *new_pps;
557 bool special_qp = (qp->qp_type == IB_QPT_SMI ||
558 qp->qp_type == IB_QPT_GSI ||
559 qp->qp_type >= IB_QPT_RESERVED1);
560 bool pps_change = ((qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) ||
561 (qp_attr_mask & IB_QP_ALT_PATH));
562
563 if (pps_change && !special_qp) {
564 mutex_lock(&qp->qp_sec->mutex);
565 new_pps = get_new_pps(qp,
566 qp_attr,
567 qp_attr_mask);
568
569 /* Add this QP to the lists for the new port
570 * and pkey settings before checking for permission
571 * in case there is a concurrent cache update
572 * occurring. Walking the list for a cache change
573 * doesn't acquire the security mutex unless it's
574 * sending the QP to error.
575 */
576 ret = port_pkey_list_insert(&new_pps->main);
577
578 if (!ret)
579 ret = port_pkey_list_insert(&new_pps->alt);
580
581 if (!ret)
582 ret = check_qp_port_pkey_settings(new_pps,
583 qp->qp_sec);
584 }
585
586 if (!ret)
587 ret = qp->device->modify_qp(qp->real_qp,
588 qp_attr,
589 qp_attr_mask,
590 udata);
591
592 if (pps_change && !special_qp) {
593 /* Clean up the lists and free the appropriate
594 * ports_pkeys structure.
595 */
596 if (ret) {
597 tmp_pps = new_pps;
598 } else {
599 tmp_pps = qp->qp_sec->ports_pkeys;
600 qp->qp_sec->ports_pkeys = new_pps;
601 }
602
603 if (tmp_pps) {
604 port_pkey_list_remove(&tmp_pps->main);
605 port_pkey_list_remove(&tmp_pps->alt);
606 }
607 kfree(tmp_pps);
608 mutex_unlock(&qp->qp_sec->mutex);
609 }
610 return ret;
611}
612EXPORT_SYMBOL(ib_security_modify_qp);
613
614int ib_security_pkey_access(struct ib_device *dev,
615 u8 port_num,
616 u16 pkey_index,
617 void *sec)
618{
619 u64 subnet_prefix;
620 u16 pkey;
621 int ret;
622
623 ret = ib_get_cached_pkey(dev, port_num, pkey_index, &pkey);
624 if (ret)
625 return ret;
626
627 ret = ib_get_cached_subnet_prefix(dev, port_num, &subnet_prefix);
628
629 if (ret)
630 return ret;
631
632 return security_ib_pkey_access(sec, subnet_prefix, pkey);
633}
634EXPORT_SYMBOL(ib_security_pkey_access);
635
636static int ib_mad_agent_security_change(struct notifier_block *nb,
637 unsigned long event,
638 void *data)
639{
640 struct ib_mad_agent *ag = container_of(nb, struct ib_mad_agent, lsm_nb);
641
642 if (event != LSM_POLICY_CHANGE)
643 return NOTIFY_DONE;
644
645 ag->smp_allowed = !security_ib_endport_manage_subnet(ag->security,
646 ag->device->name,
647 ag->port_num);
648
649 return NOTIFY_OK;
650}
651
652int ib_mad_agent_security_setup(struct ib_mad_agent *agent,
653 enum ib_qp_type qp_type)
654{
655 int ret;
656
657 ret = security_ib_alloc_security(&agent->security);
658 if (ret)
659 return ret;
660
661 if (qp_type != IB_QPT_SMI)
662 return 0;
663
664 ret = security_ib_endport_manage_subnet(agent->security,
665 agent->device->name,
666 agent->port_num);
667 if (ret)
668 return ret;
669
670 agent->lsm_nb.notifier_call = ib_mad_agent_security_change;
671 ret = register_lsm_notifier(&agent->lsm_nb);
672 if (ret)
673 return ret;
674
675 agent->smp_allowed = true;
676 agent->lsm_nb_reg = true;
677 return 0;
678}
679
680void ib_mad_agent_security_cleanup(struct ib_mad_agent *agent)
681{
682 security_ib_free_security(agent->security);
683 if (agent->lsm_nb_reg)
684 unregister_lsm_notifier(&agent->lsm_nb);
685}
686
687int ib_mad_enforce_security(struct ib_mad_agent_private *map, u16 pkey_index)
688{
689 int ret;
690
691 if (map->agent.qp->qp_type == IB_QPT_SMI && !map->agent.smp_allowed)
692 return -EACCES;
693
694 ret = ib_security_pkey_access(map->agent.device,
695 map->agent.port_num,
696 pkey_index,
697 map->agent.security);
698
699 if (ret)
700 return ret;
701
702 return 0;
703}
704
705#endif /* CONFIG_SECURITY_INFINIBAND */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 70b7fb156414..0ad3b05405d8 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1508,6 +1508,10 @@ static int create_qp(struct ib_uverbs_file *file,
1508 } 1508 }
1509 1509
1510 if (cmd->qp_type != IB_QPT_XRC_TGT) { 1510 if (cmd->qp_type != IB_QPT_XRC_TGT) {
1511 ret = ib_create_qp_security(qp, device);
1512 if (ret)
1513 goto err_cb;
1514
1511 qp->real_qp = qp; 1515 qp->real_qp = qp;
1512 qp->device = device; 1516 qp->device = device;
1513 qp->pd = pd; 1517 qp->pd = pd;
@@ -2002,14 +2006,17 @@ static int modify_qp(struct ib_uverbs_file *file,
2002 if (ret) 2006 if (ret)
2003 goto release_qp; 2007 goto release_qp;
2004 } 2008 }
2005 ret = qp->device->modify_qp(qp, attr, 2009 ret = ib_security_modify_qp(qp,
2010 attr,
2006 modify_qp_mask(qp->qp_type, 2011 modify_qp_mask(qp->qp_type,
2007 cmd->base.attr_mask), 2012 cmd->base.attr_mask),
2008 udata); 2013 udata);
2009 } else { 2014 } else {
2010 ret = ib_modify_qp(qp, attr, 2015 ret = ib_security_modify_qp(qp,
2011 modify_qp_mask(qp->qp_type, 2016 attr,
2012 cmd->base.attr_mask)); 2017 modify_qp_mask(qp->qp_type,
2018 cmd->base.attr_mask),
2019 NULL);
2013 } 2020 }
2014 2021
2015release_qp: 2022release_qp:
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 4792f5209ac2..c973a83c898b 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -44,6 +44,7 @@
44#include <linux/in.h> 44#include <linux/in.h>
45#include <linux/in6.h> 45#include <linux/in6.h>
46#include <net/addrconf.h> 46#include <net/addrconf.h>
47#include <linux/security.h>
47 48
48#include <rdma/ib_verbs.h> 49#include <rdma/ib_verbs.h>
49#include <rdma/ib_cache.h> 50#include <rdma/ib_cache.h>
@@ -713,12 +714,20 @@ static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
713{ 714{
714 struct ib_qp *qp; 715 struct ib_qp *qp;
715 unsigned long flags; 716 unsigned long flags;
717 int err;
716 718
717 qp = kzalloc(sizeof *qp, GFP_KERNEL); 719 qp = kzalloc(sizeof *qp, GFP_KERNEL);
718 if (!qp) 720 if (!qp)
719 return ERR_PTR(-ENOMEM); 721 return ERR_PTR(-ENOMEM);
720 722
721 qp->real_qp = real_qp; 723 qp->real_qp = real_qp;
724 err = ib_open_shared_qp_security(qp, real_qp->device);
725 if (err) {
726 kfree(qp);
727 return ERR_PTR(err);
728 }
729
730 qp->real_qp = real_qp;
722 atomic_inc(&real_qp->usecnt); 731 atomic_inc(&real_qp->usecnt);
723 qp->device = real_qp->device; 732 qp->device = real_qp->device;
724 qp->event_handler = event_handler; 733 qp->event_handler = event_handler;
@@ -804,6 +813,12 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
804 if (IS_ERR(qp)) 813 if (IS_ERR(qp))
805 return qp; 814 return qp;
806 815
816 ret = ib_create_qp_security(qp, device);
817 if (ret) {
818 ib_destroy_qp(qp);
819 return ERR_PTR(ret);
820 }
821
807 qp->device = device; 822 qp->device = device;
808 qp->real_qp = qp; 823 qp->real_qp = qp;
809 qp->uobject = NULL; 824 qp->uobject = NULL;
@@ -1266,7 +1281,7 @@ int ib_modify_qp(struct ib_qp *qp,
1266 return ret; 1281 return ret;
1267 } 1282 }
1268 1283
1269 return qp->device->modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL); 1284 return ib_security_modify_qp(qp->real_qp, qp_attr, qp_attr_mask, NULL);
1270} 1285}
1271EXPORT_SYMBOL(ib_modify_qp); 1286EXPORT_SYMBOL(ib_modify_qp);
1272 1287
@@ -1295,6 +1310,7 @@ int ib_close_qp(struct ib_qp *qp)
1295 spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags); 1310 spin_unlock_irqrestore(&real_qp->device->event_handler_lock, flags);
1296 1311
1297 atomic_dec(&real_qp->usecnt); 1312 atomic_dec(&real_qp->usecnt);
1313 ib_close_shared_qp_security(qp->qp_sec);
1298 kfree(qp); 1314 kfree(qp);
1299 1315
1300 return 0; 1316 return 0;
@@ -1335,6 +1351,7 @@ int ib_destroy_qp(struct ib_qp *qp)
1335 struct ib_cq *scq, *rcq; 1351 struct ib_cq *scq, *rcq;
1336 struct ib_srq *srq; 1352 struct ib_srq *srq;
1337 struct ib_rwq_ind_table *ind_tbl; 1353 struct ib_rwq_ind_table *ind_tbl;
1354 struct ib_qp_security *sec;
1338 int ret; 1355 int ret;
1339 1356
1340 WARN_ON_ONCE(qp->mrs_used > 0); 1357 WARN_ON_ONCE(qp->mrs_used > 0);
@@ -1350,6 +1367,9 @@ int ib_destroy_qp(struct ib_qp *qp)
1350 rcq = qp->recv_cq; 1367 rcq = qp->recv_cq;
1351 srq = qp->srq; 1368 srq = qp->srq;
1352 ind_tbl = qp->rwq_ind_tbl; 1369 ind_tbl = qp->rwq_ind_tbl;
1370 sec = qp->qp_sec;
1371 if (sec)
1372 ib_destroy_qp_security_begin(sec);
1353 1373
1354 if (!qp->uobject) 1374 if (!qp->uobject)
1355 rdma_rw_cleanup_mrs(qp); 1375 rdma_rw_cleanup_mrs(qp);
@@ -1366,6 +1386,11 @@ int ib_destroy_qp(struct ib_qp *qp)
1366 atomic_dec(&srq->usecnt); 1386 atomic_dec(&srq->usecnt);
1367 if (ind_tbl) 1387 if (ind_tbl)
1368 atomic_dec(&ind_tbl->usecnt); 1388 atomic_dec(&ind_tbl->usecnt);
1389 if (sec)
1390 ib_destroy_qp_security_end(sec);
1391 } else {
1392 if (sec)
1393 ib_destroy_qp_security_abort(sec);
1369 } 1394 }
1370 1395
1371 return ret; 1396 return ret;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 2f3822a4a7d5..b8e073546507 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2544,10 +2544,25 @@ EXPORT_SYMBOL_GPL(nfs_set_sb_security);
2544int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, 2544int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2545 struct nfs_mount_info *mount_info) 2545 struct nfs_mount_info *mount_info)
2546{ 2546{
2547 int error;
2548 unsigned long kflags = 0, kflags_out = 0;
2549
2547 /* clone any lsm security options from the parent to the new sb */ 2550 /* clone any lsm security options from the parent to the new sb */
2548 if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) 2551 if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
2549 return -ESTALE; 2552 return -ESTALE;
2550 return security_sb_clone_mnt_opts(mount_info->cloned->sb, s); 2553
2554 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
2555 kflags |= SECURITY_LSM_NATIVE_LABELS;
2556
2557 error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags,
2558 &kflags_out);
2559 if (error)
2560 return error;
2561
2562 if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
2563 !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
2564 NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
2565 return 0;
2551} 2566}
2552EXPORT_SYMBOL_GPL(nfs_clone_sb_security); 2567EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
2553 2568
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index e58e577117b6..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
25struct lsm_network_audit { 26struct lsm_network_audit {
26 int netif; 27 int netif;
@@ -45,6 +46,16 @@ struct lsm_ioctlop_audit {
45 u16 cmd; 46 u16 cmd;
46}; 47};
47 48
49struct lsm_ibpkey_audit {
50 u64 subnet_prefix;
51 u16 pkey;
52};
53
54struct lsm_ibendport_audit {
55 char dev_name[IB_DEVICE_NAME_MAX];
56 u8 port;
57};
58
48/* Auxiliary data to use in generating the audit record. */ 59/* Auxiliary data to use in generating the audit record. */
49struct common_audit_data { 60struct common_audit_data {
50 char type; 61 char type;
@@ -60,6 +71,8 @@ struct common_audit_data {
60#define LSM_AUDIT_DATA_DENTRY 10 71#define LSM_AUDIT_DATA_DENTRY 10
61#define LSM_AUDIT_DATA_IOCTL_OP 11 72#define LSM_AUDIT_DATA_IOCTL_OP 11
62#define LSM_AUDIT_DATA_FILE 12 73#define LSM_AUDIT_DATA_FILE 12
74#define LSM_AUDIT_DATA_IBPKEY 13
75#define LSM_AUDIT_DATA_IBENDPORT 14
63 union { 76 union {
64 struct path path; 77 struct path path;
65 struct dentry *dentry; 78 struct dentry *dentry;
@@ -77,6 +90,8 @@ struct common_audit_data {
77 char *kmod_name; 90 char *kmod_name;
78 struct lsm_ioctlop_audit *op; 91 struct lsm_ioctlop_audit *op;
79 struct file *file; 92 struct file *file;
93 struct lsm_ibpkey_audit *ibpkey;
94 struct lsm_ibendport_audit *ibendport;
80 } u; 95 } u;
81 /* this union contains LSM specific data */ 96 /* this union contains LSM specific data */
82 union { 97 union {
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 080f34e66017..3cc9d77c7527 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -8,6 +8,7 @@
8 * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group) 8 * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group)
9 * Copyright (C) 2015 Intel Corporation. 9 * Copyright (C) 2015 Intel Corporation.
10 * Copyright (C) 2015 Casey Schaufler <casey@schaufler-ca.com> 10 * Copyright (C) 2015 Casey Schaufler <casey@schaufler-ca.com>
11 * Copyright (C) 2016 Mellanox Techonologies
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -911,6 +912,26 @@
911 * associated with the TUN device's security structure. 912 * associated with the TUN device's security structure.
912 * @security pointer to the TUN devices's security structure. 913 * @security pointer to the TUN devices's security structure.
913 * 914 *
915 * Security hooks for Infiniband
916 *
917 * @ib_pkey_access:
918 * Check permission to access a pkey when modifing a QP.
919 * @subnet_prefix the subnet prefix of the port being used.
920 * @pkey the pkey to be accessed.
921 * @sec pointer to a security structure.
922 * @ib_endport_manage_subnet:
923 * Check permissions to send and receive SMPs on a end port.
924 * @dev_name the IB device name (i.e. mlx4_0).
925 * @port_num the port number.
926 * @sec pointer to a security structure.
927 * @ib_alloc_security:
928 * Allocate a security structure for Infiniband objects.
929 * @sec pointer to a security structure pointer.
930 * Returns 0 on success, non-zero on failure
931 * @ib_free_security:
932 * Deallocate an Infiniband security structure.
933 * @sec contains the security structure to be freed.
934 *
914 * Security hooks for XFRM operations. 935 * Security hooks for XFRM operations.
915 * 936 *
916 * @xfrm_policy_alloc_security: 937 * @xfrm_policy_alloc_security:
@@ -1388,7 +1409,9 @@ union security_list_options {
1388 unsigned long kern_flags, 1409 unsigned long kern_flags,
1389 unsigned long *set_kern_flags); 1410 unsigned long *set_kern_flags);
1390 int (*sb_clone_mnt_opts)(const struct super_block *oldsb, 1411 int (*sb_clone_mnt_opts)(const struct super_block *oldsb,
1391 struct super_block *newsb); 1412 struct super_block *newsb,
1413 unsigned long kern_flags,
1414 unsigned long *set_kern_flags);
1392 int (*sb_parse_opts_str)(char *options, struct security_mnt_opts *opts); 1415 int (*sb_parse_opts_str)(char *options, struct security_mnt_opts *opts);
1393 int (*dentry_init_security)(struct dentry *dentry, int mode, 1416 int (*dentry_init_security)(struct dentry *dentry, int mode,
1394 const struct qstr *name, void **ctx, 1417 const struct qstr *name, void **ctx,
@@ -1620,6 +1643,14 @@ union security_list_options {
1620 int (*tun_dev_open)(void *security); 1643 int (*tun_dev_open)(void *security);
1621#endif /* CONFIG_SECURITY_NETWORK */ 1644#endif /* CONFIG_SECURITY_NETWORK */
1622 1645
1646#ifdef CONFIG_SECURITY_INFINIBAND
1647 int (*ib_pkey_access)(void *sec, u64 subnet_prefix, u16 pkey);
1648 int (*ib_endport_manage_subnet)(void *sec, const char *dev_name,
1649 u8 port_num);
1650 int (*ib_alloc_security)(void **sec);
1651 void (*ib_free_security)(void *sec);
1652#endif /* CONFIG_SECURITY_INFINIBAND */
1653
1623#ifdef CONFIG_SECURITY_NETWORK_XFRM 1654#ifdef CONFIG_SECURITY_NETWORK_XFRM
1624 int (*xfrm_policy_alloc_security)(struct xfrm_sec_ctx **ctxp, 1655 int (*xfrm_policy_alloc_security)(struct xfrm_sec_ctx **ctxp,
1625 struct xfrm_user_sec_ctx *sec_ctx, 1656 struct xfrm_user_sec_ctx *sec_ctx,
@@ -1851,6 +1882,12 @@ struct security_hook_heads {
1851 struct list_head tun_dev_attach; 1882 struct list_head tun_dev_attach;
1852 struct list_head tun_dev_open; 1883 struct list_head tun_dev_open;
1853#endif /* CONFIG_SECURITY_NETWORK */ 1884#endif /* CONFIG_SECURITY_NETWORK */
1885#ifdef CONFIG_SECURITY_INFINIBAND
1886 struct list_head ib_pkey_access;
1887 struct list_head ib_endport_manage_subnet;
1888 struct list_head ib_alloc_security;
1889 struct list_head ib_free_security;
1890#endif /* CONFIG_SECURITY_INFINIBAND */
1854#ifdef CONFIG_SECURITY_NETWORK_XFRM 1891#ifdef CONFIG_SECURITY_NETWORK_XFRM
1855 struct list_head xfrm_policy_alloc_security; 1892 struct list_head xfrm_policy_alloc_security;
1856 struct list_head xfrm_policy_clone_security; 1893 struct list_head xfrm_policy_clone_security;
diff --git a/include/linux/security.h b/include/linux/security.h
index caf8b64d8b5c..b6ea1dc9cc9d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -6,6 +6,7 @@
6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> 6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
7 * Copyright (C) 2001 James Morris <jmorris@intercode.com.au> 7 * Copyright (C) 2001 James Morris <jmorris@intercode.com.au>
8 * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group) 8 * Copyright (C) 2001 Silicon Graphics, Inc. (Trust Technology Group)
9 * Copyright (C) 2016 Mellanox Techonologies
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -68,6 +69,10 @@ struct audit_krule;
68struct user_namespace; 69struct user_namespace;
69struct timezone; 70struct timezone;
70 71
72enum lsm_event {
73 LSM_POLICY_CHANGE,
74};
75
71/* These functions are in security/commoncap.c */ 76/* These functions are in security/commoncap.c */
72extern int cap_capable(const struct cred *cred, struct user_namespace *ns, 77extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
73 int cap, int audit); 78 int cap, int audit);
@@ -163,6 +168,10 @@ struct security_mnt_opts {
163 int num_mnt_opts; 168 int num_mnt_opts;
164}; 169};
165 170
171int call_lsm_notifier(enum lsm_event event, void *data);
172int register_lsm_notifier(struct notifier_block *nb);
173int unregister_lsm_notifier(struct notifier_block *nb);
174
166static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 175static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
167{ 176{
168 opts->mnt_opts = NULL; 177 opts->mnt_opts = NULL;
@@ -240,7 +249,9 @@ int security_sb_set_mnt_opts(struct super_block *sb,
240 unsigned long kern_flags, 249 unsigned long kern_flags,
241 unsigned long *set_kern_flags); 250 unsigned long *set_kern_flags);
242int security_sb_clone_mnt_opts(const struct super_block *oldsb, 251int security_sb_clone_mnt_opts(const struct super_block *oldsb,
243 struct super_block *newsb); 252 struct super_block *newsb,
253 unsigned long kern_flags,
254 unsigned long *set_kern_flags);
244int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts); 255int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
245int security_dentry_init_security(struct dentry *dentry, int mode, 256int security_dentry_init_security(struct dentry *dentry, int mode,
246 const struct qstr *name, void **ctx, 257 const struct qstr *name, void **ctx,
@@ -381,6 +392,21 @@ int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
381struct security_mnt_opts { 392struct security_mnt_opts {
382}; 393};
383 394
395static inline int call_lsm_notifier(enum lsm_event event, void *data)
396{
397 return 0;
398}
399
400static inline int register_lsm_notifier(struct notifier_block *nb)
401{
402 return 0;
403}
404
405static inline int unregister_lsm_notifier(struct notifier_block *nb)
406{
407 return 0;
408}
409
384static inline void security_init_mnt_opts(struct security_mnt_opts *opts) 410static inline void security_init_mnt_opts(struct security_mnt_opts *opts)
385{ 411{
386} 412}
@@ -581,7 +607,9 @@ static inline int security_sb_set_mnt_opts(struct super_block *sb,
581} 607}
582 608
583static inline int security_sb_clone_mnt_opts(const struct super_block *oldsb, 609static inline int security_sb_clone_mnt_opts(const struct super_block *oldsb,
584 struct super_block *newsb) 610 struct super_block *newsb,
611 unsigned long kern_flags,
612 unsigned long *set_kern_flags)
585{ 613{
586 return 0; 614 return 0;
587} 615}
@@ -1406,6 +1434,32 @@ static inline int security_tun_dev_open(void *security)
1406} 1434}
1407#endif /* CONFIG_SECURITY_NETWORK */ 1435#endif /* CONFIG_SECURITY_NETWORK */
1408 1436
1437#ifdef CONFIG_SECURITY_INFINIBAND
1438int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey);
1439int security_ib_endport_manage_subnet(void *sec, const char *name, u8 port_num);
1440int security_ib_alloc_security(void **sec);
1441void security_ib_free_security(void *sec);
1442#else /* CONFIG_SECURITY_INFINIBAND */
1443static inline int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
1444{
1445 return 0;
1446}
1447
1448static inline int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
1449{
1450 return 0;
1451}
1452
1453static inline int security_ib_alloc_security(void **sec)
1454{
1455 return 0;
1456}
1457
1458static inline void security_ib_free_security(void *sec)
1459{
1460}
1461#endif /* CONFIG_SECURITY_INFINIBAND */
1462
1409#ifdef CONFIG_SECURITY_NETWORK_XFRM 1463#ifdef CONFIG_SECURITY_NETWORK_XFRM
1410 1464
1411int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 1465int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h
index d67b11b72029..2f4f1768ded4 100644
--- a/include/rdma/ib_mad.h
+++ b/include/rdma/ib_mad.h
@@ -575,6 +575,10 @@ struct ib_mad_agent {
575 u32 flags; 575 u32 flags;
576 u8 port_num; 576 u8 port_num;
577 u8 rmpp_version; 577 u8 rmpp_version;
578 void *security;
579 bool smp_allowed;
580 bool lsm_nb_reg;
581 struct notifier_block lsm_nb;
578}; 582};
579 583
580/** 584/**
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index ba8314ec5768..0e480a5630d4 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1614,6 +1614,45 @@ struct ib_rwq_ind_table_init_attr {
1614 struct ib_wq **ind_tbl; 1614 struct ib_wq **ind_tbl;
1615}; 1615};
1616 1616
1617enum port_pkey_state {
1618 IB_PORT_PKEY_NOT_VALID = 0,
1619 IB_PORT_PKEY_VALID = 1,
1620 IB_PORT_PKEY_LISTED = 2,
1621};
1622
1623struct ib_qp_security;
1624
1625struct ib_port_pkey {
1626 enum port_pkey_state state;
1627 u16 pkey_index;
1628 u8 port_num;
1629 struct list_head qp_list;
1630 struct list_head to_error_list;
1631 struct ib_qp_security *sec;
1632};
1633
1634struct ib_ports_pkeys {
1635 struct ib_port_pkey main;
1636 struct ib_port_pkey alt;
1637};
1638
1639struct ib_qp_security {
1640 struct ib_qp *qp;
1641 struct ib_device *dev;
1642 /* Hold this mutex when changing port and pkey settings. */
1643 struct mutex mutex;
1644 struct ib_ports_pkeys *ports_pkeys;
1645 /* A list of all open shared QP handles. Required to enforce security
1646 * properly for all users of a shared QP.
1647 */
1648 struct list_head shared_qp_list;
1649 void *security;
1650 bool destroying;
1651 atomic_t error_list_count;
1652 struct completion error_complete;
1653 int error_comps_pending;
1654};
1655
1617/* 1656/*
1618 * @max_write_sge: Maximum SGE elements per RDMA WRITE request. 1657 * @max_write_sge: Maximum SGE elements per RDMA WRITE request.
1619 * @max_read_sge: Maximum SGE elements per RDMA READ request. 1658 * @max_read_sge: Maximum SGE elements per RDMA READ request.
@@ -1643,6 +1682,7 @@ struct ib_qp {
1643 u32 max_read_sge; 1682 u32 max_read_sge;
1644 enum ib_qp_type qp_type; 1683 enum ib_qp_type qp_type;
1645 struct ib_rwq_ind_table *rwq_ind_tbl; 1684 struct ib_rwq_ind_table *rwq_ind_tbl;
1685 struct ib_qp_security *qp_sec;
1646}; 1686};
1647 1687
1648struct ib_mr { 1688struct ib_mr {
@@ -1891,6 +1931,7 @@ enum ib_mad_result {
1891}; 1931};
1892 1932
1893struct ib_port_cache { 1933struct ib_port_cache {
1934 u64 subnet_prefix;
1894 struct ib_pkey_cache *pkey; 1935 struct ib_pkey_cache *pkey;
1895 struct ib_gid_table *gid; 1936 struct ib_gid_table *gid;
1896 u8 lmc; 1937 u8 lmc;
@@ -1940,6 +1981,12 @@ struct rdma_netdev {
1940 union ib_gid *gid, u16 mlid); 1981 union ib_gid *gid, u16 mlid);
1941}; 1982};
1942 1983
1984struct ib_port_pkey_list {
1985 /* Lock to hold while modifying the list. */
1986 spinlock_t list_lock;
1987 struct list_head pkey_list;
1988};
1989
1943struct ib_device { 1990struct ib_device {
1944 /* Do not access @dma_device directly from ULP nor from HW drivers. */ 1991 /* Do not access @dma_device directly from ULP nor from HW drivers. */
1945 struct device *dma_device; 1992 struct device *dma_device;
@@ -1963,6 +2010,8 @@ struct ib_device {
1963 2010
1964 int num_comp_vectors; 2011 int num_comp_vectors;
1965 2012
2013 struct ib_port_pkey_list *port_pkey_list;
2014
1966 struct iw_cm_verbs *iwcm; 2015 struct iw_cm_verbs *iwcm;
1967 2016
1968 /** 2017 /**
diff --git a/security/Kconfig b/security/Kconfig
index bdcbb92927ab..d540bfe73190 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,15 @@ config SECURITY_NETWORK
54 implement socket and networking access controls. 54 implement socket and networking access controls.
55 If you are unsure how to answer this question, answer N. 55 If you are unsure how to answer this question, answer N.
56 56
57config SECURITY_INFINIBAND
58 bool "Infiniband Security Hooks"
59 depends on SECURITY && INFINIBAND
60 help
61 This enables the Infiniband security hooks.
62 If enabled, a security module can use these hooks to
63 implement Infiniband access controls.
64 If you are unsure how to answer this question, answer N.
65
57config SECURITY_NETWORK_XFRM 66config SECURITY_NETWORK_XFRM
58 bool "XFRM (IPSec) Networking Security Hooks" 67 bool "XFRM (IPSec) Networking Security Hooks"
59 depends on XFRM && SECURITY_NETWORK 68 depends on XFRM && SECURITY_NETWORK
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 37f04dadc8d6..28d4c3a528ab 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -410,6 +410,22 @@ static void dump_common_audit_data(struct audit_buffer *ab,
410 audit_log_format(ab, " kmod="); 410 audit_log_format(ab, " kmod=");
411 audit_log_untrustedstring(ab, a->u.kmod_name); 411 audit_log_untrustedstring(ab, a->u.kmod_name);
412 break; 412 break;
413 case LSM_AUDIT_DATA_IBPKEY: {
414 struct in6_addr sbn_pfx;
415
416 memset(&sbn_pfx.s6_addr, 0,
417 sizeof(sbn_pfx.s6_addr));
418 memcpy(&sbn_pfx.s6_addr, &a->u.ibpkey->subnet_prefix,
419 sizeof(a->u.ibpkey->subnet_prefix));
420 audit_log_format(ab, " pkey=0x%x subnet_prefix=%pI6c",
421 a->u.ibpkey->pkey, &sbn_pfx);
422 break;
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;
413 } /* switch (a->type) */ 429 } /* switch (a->type) */
414} 430}
415 431
diff --git a/security/security.c b/security/security.c
index 38316bb28b16..30132378d103 100644
--- a/security/security.c
+++ b/security/security.c
@@ -4,6 +4,7 @@
4 * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com> 4 * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
5 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com> 5 * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com> 6 * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
7 * Copyright (C) 2016 Mellanox Technologies
7 * 8 *
8 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -34,6 +35,8 @@
34#define SECURITY_NAME_MAX 10 35#define SECURITY_NAME_MAX 10
35 36
36struct security_hook_heads security_hook_heads __lsm_ro_after_init; 37struct security_hook_heads security_hook_heads __lsm_ro_after_init;
38static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
39
37char *lsm_names; 40char *lsm_names;
38/* Boot-time LSM user choice */ 41/* Boot-time LSM user choice */
39static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = 42static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
@@ -165,6 +168,24 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
165 panic("%s - Cannot get early memory.\n", __func__); 168 panic("%s - Cannot get early memory.\n", __func__);
166} 169}
167 170
171int call_lsm_notifier(enum lsm_event event, void *data)
172{
173 return atomic_notifier_call_chain(&lsm_notifier_chain, event, data);
174}
175EXPORT_SYMBOL(call_lsm_notifier);
176
177int register_lsm_notifier(struct notifier_block *nb)
178{
179 return atomic_notifier_chain_register(&lsm_notifier_chain, nb);
180}
181EXPORT_SYMBOL(register_lsm_notifier);
182
183int unregister_lsm_notifier(struct notifier_block *nb)
184{
185 return atomic_notifier_chain_unregister(&lsm_notifier_chain, nb);
186}
187EXPORT_SYMBOL(unregister_lsm_notifier);
188
168/* 189/*
169 * Hook list operation macros. 190 * Hook list operation macros.
170 * 191 *
@@ -399,9 +420,12 @@ int security_sb_set_mnt_opts(struct super_block *sb,
399EXPORT_SYMBOL(security_sb_set_mnt_opts); 420EXPORT_SYMBOL(security_sb_set_mnt_opts);
400 421
401int security_sb_clone_mnt_opts(const struct super_block *oldsb, 422int security_sb_clone_mnt_opts(const struct super_block *oldsb,
402 struct super_block *newsb) 423 struct super_block *newsb,
424 unsigned long kern_flags,
425 unsigned long *set_kern_flags)
403{ 426{
404 return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb); 427 return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb,
428 kern_flags, set_kern_flags);
405} 429}
406EXPORT_SYMBOL(security_sb_clone_mnt_opts); 430EXPORT_SYMBOL(security_sb_clone_mnt_opts);
407 431
@@ -1515,6 +1539,33 @@ EXPORT_SYMBOL(security_tun_dev_open);
1515 1539
1516#endif /* CONFIG_SECURITY_NETWORK */ 1540#endif /* CONFIG_SECURITY_NETWORK */
1517 1541
1542#ifdef CONFIG_SECURITY_INFINIBAND
1543
1544int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey)
1545{
1546 return call_int_hook(ib_pkey_access, 0, sec, subnet_prefix, pkey);
1547}
1548EXPORT_SYMBOL(security_ib_pkey_access);
1549
1550int security_ib_endport_manage_subnet(void *sec, const char *dev_name, u8 port_num)
1551{
1552 return call_int_hook(ib_endport_manage_subnet, 0, sec, dev_name, port_num);
1553}
1554EXPORT_SYMBOL(security_ib_endport_manage_subnet);
1555
1556int security_ib_alloc_security(void **sec)
1557{
1558 return call_int_hook(ib_alloc_security, 0, sec);
1559}
1560EXPORT_SYMBOL(security_ib_alloc_security);
1561
1562void security_ib_free_security(void *sec)
1563{
1564 call_void_hook(ib_free_security, sec);
1565}
1566EXPORT_SYMBOL(security_ib_free_security);
1567#endif /* CONFIG_SECURITY_INFINIBAND */
1568
1518#ifdef CONFIG_SECURITY_NETWORK_XFRM 1569#ifdef CONFIG_SECURITY_NETWORK_XFRM
1519 1570
1520int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 1571int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 3411c33e2a44..ff5895ede96f 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -5,7 +5,7 @@
5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o 5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
6 6
7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ 7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
8 netnode.o netport.o exports.o \ 8 netnode.o netport.o ibpkey.o exports.o \
9 ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ 9 ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
10 ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o 10 ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o
11 11
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e67a526d1f30..3a06afbd2f6f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -17,6 +17,7 @@
17 * Paul Moore <paul@paul-moore.com> 17 * Paul Moore <paul@paul-moore.com>
18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. 18 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
19 * Yuichi Nakamura <ynakam@hitachisoft.jp> 19 * Yuichi Nakamura <ynakam@hitachisoft.jp>
20 * Copyright (C) 2016 Mellanox Technologies
20 * 21 *
21 * This program is free software; you can redistribute it and/or modify 22 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License version 2, 23 * it under the terms of the GNU General Public License version 2,
@@ -90,6 +91,7 @@
90#include "netif.h" 91#include "netif.h"
91#include "netnode.h" 92#include "netnode.h"
92#include "netport.h" 93#include "netport.h"
94#include "ibpkey.h"
93#include "xfrm.h" 95#include "xfrm.h"
94#include "netlabel.h" 96#include "netlabel.h"
95#include "audit.h" 97#include "audit.h"
@@ -171,6 +173,16 @@ static int selinux_netcache_avc_callback(u32 event)
171 return 0; 173 return 0;
172} 174}
173 175
176static int selinux_lsm_notifier_avc_callback(u32 event)
177{
178 if (event == AVC_CALLBACK_RESET) {
179 sel_ib_pkey_flush();
180 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
181 }
182
183 return 0;
184}
185
174/* 186/*
175 * initialise the security for the init task 187 * initialise the security for the init task
176 */ 188 */
@@ -398,18 +410,6 @@ static void superblock_free_security(struct super_block *sb)
398 kfree(sbsec); 410 kfree(sbsec);
399} 411}
400 412
401/* The file system's label must be initialized prior to use. */
402
403static const char *labeling_behaviors[7] = {
404 "uses xattr",
405 "uses transition SIDs",
406 "uses task SIDs",
407 "uses genfs_contexts",
408 "not configured for labeling",
409 "uses mountpoint labeling",
410 "uses native labeling",
411};
412
413static inline int inode_doinit(struct inode *inode) 413static inline int inode_doinit(struct inode *inode)
414{ 414{
415 return inode_doinit_with_dentry(inode, NULL); 415 return inode_doinit_with_dentry(inode, NULL);
@@ -524,13 +524,17 @@ static int sb_finish_set_opts(struct super_block *sb)
524 } 524 }
525 } 525 }
526 526
527 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
528 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
529 sb->s_id, sb->s_type->name);
530
531 sbsec->flags |= SE_SBINITIALIZED; 527 sbsec->flags |= SE_SBINITIALIZED;
528
529 /*
530 * Explicitly set or clear SBLABEL_MNT. It's not sufficient to simply
531 * leave the flag untouched because sb_clone_mnt_opts might be handing
532 * us a superblock that needs the flag to be cleared.
533 */
532 if (selinux_is_sblabel_mnt(sb)) 534 if (selinux_is_sblabel_mnt(sb))
533 sbsec->flags |= SBLABEL_MNT; 535 sbsec->flags |= SBLABEL_MNT;
536 else
537 sbsec->flags &= ~SBLABEL_MNT;
534 538
535 /* Initialize the root inode. */ 539 /* Initialize the root inode. */
536 rc = inode_doinit_with_dentry(root_inode, root); 540 rc = inode_doinit_with_dentry(root_inode, root);
@@ -809,6 +813,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
809 sbsec->flags |= SE_SBPROC | SE_SBGENFS; 813 sbsec->flags |= SE_SBPROC | SE_SBGENFS;
810 814
811 if (!strcmp(sb->s_type->name, "debugfs") || 815 if (!strcmp(sb->s_type->name, "debugfs") ||
816 !strcmp(sb->s_type->name, "tracefs") ||
812 !strcmp(sb->s_type->name, "sysfs") || 817 !strcmp(sb->s_type->name, "sysfs") ||
813 !strcmp(sb->s_type->name, "pstore")) 818 !strcmp(sb->s_type->name, "pstore"))
814 sbsec->flags |= SE_SBGENFS; 819 sbsec->flags |= SE_SBGENFS;
@@ -963,8 +968,11 @@ mismatch:
963} 968}
964 969
965static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, 970static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
966 struct super_block *newsb) 971 struct super_block *newsb,
972 unsigned long kern_flags,
973 unsigned long *set_kern_flags)
967{ 974{
975 int rc = 0;
968 const struct superblock_security_struct *oldsbsec = oldsb->s_security; 976 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
969 struct superblock_security_struct *newsbsec = newsb->s_security; 977 struct superblock_security_struct *newsbsec = newsb->s_security;
970 978
@@ -979,6 +987,13 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
979 if (!ss_initialized) 987 if (!ss_initialized)
980 return 0; 988 return 0;
981 989
990 /*
991 * Specifying internal flags without providing a place to
992 * place the results is not allowed.
993 */
994 if (kern_flags && !set_kern_flags)
995 return -EINVAL;
996
982 /* how can we clone if the old one wasn't set up?? */ 997 /* how can we clone if the old one wasn't set up?? */
983 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); 998 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
984 999
@@ -994,6 +1009,18 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
994 newsbsec->def_sid = oldsbsec->def_sid; 1009 newsbsec->def_sid = oldsbsec->def_sid;
995 newsbsec->behavior = oldsbsec->behavior; 1010 newsbsec->behavior = oldsbsec->behavior;
996 1011
1012 if (newsbsec->behavior == SECURITY_FS_USE_NATIVE &&
1013 !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) {
1014 rc = security_fs_use(newsb);
1015 if (rc)
1016 goto out;
1017 }
1018
1019 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context) {
1020 newsbsec->behavior = SECURITY_FS_USE_NATIVE;
1021 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
1022 }
1023
997 if (set_context) { 1024 if (set_context) {
998 u32 sid = oldsbsec->mntpoint_sid; 1025 u32 sid = oldsbsec->mntpoint_sid;
999 1026
@@ -1013,8 +1040,9 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
1013 } 1040 }
1014 1041
1015 sb_finish_set_opts(newsb); 1042 sb_finish_set_opts(newsb);
1043out:
1016 mutex_unlock(&newsbsec->lock); 1044 mutex_unlock(&newsbsec->lock);
1017 return 0; 1045 return rc;
1018} 1046}
1019 1047
1020static int selinux_parse_opts_str(char *options, 1048static int selinux_parse_opts_str(char *options,
@@ -2063,8 +2091,9 @@ static inline u32 file_to_av(struct file *file)
2063static inline u32 open_file_to_av(struct file *file) 2091static inline u32 open_file_to_av(struct file *file)
2064{ 2092{
2065 u32 av = file_to_av(file); 2093 u32 av = file_to_av(file);
2094 struct inode *inode = file_inode(file);
2066 2095
2067 if (selinux_policycap_openperm) 2096 if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC)
2068 av |= FILE__OPEN; 2097 av |= FILE__OPEN;
2069 2098
2070 return av; 2099 return av;
@@ -3059,6 +3088,7 @@ static int selinux_inode_permission(struct inode *inode, int mask)
3059static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 3088static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3060{ 3089{
3061 const struct cred *cred = current_cred(); 3090 const struct cred *cred = current_cred();
3091 struct inode *inode = d_backing_inode(dentry);
3062 unsigned int ia_valid = iattr->ia_valid; 3092 unsigned int ia_valid = iattr->ia_valid;
3063 __u32 av = FILE__WRITE; 3093 __u32 av = FILE__WRITE;
3064 3094
@@ -3074,8 +3104,10 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
3074 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 3104 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
3075 return dentry_has_perm(cred, dentry, FILE__SETATTR); 3105 return dentry_has_perm(cred, dentry, FILE__SETATTR);
3076 3106
3077 if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) 3107 if (selinux_policycap_openperm &&
3078 && !(ia_valid & ATTR_FILE)) 3108 inode->i_sb->s_magic != SOCKFS_MAGIC &&
3109 (ia_valid & ATTR_SIZE) &&
3110 !(ia_valid & ATTR_FILE))
3079 av |= FILE__OPEN; 3111 av |= FILE__OPEN;
3080 3112
3081 return dentry_has_perm(cred, dentry, av); 3113 return dentry_has_perm(cred, dentry, av);
@@ -3107,6 +3139,18 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
3107 return dentry_has_perm(cred, dentry, FILE__SETATTR); 3139 return dentry_has_perm(cred, dentry, FILE__SETATTR);
3108} 3140}
3109 3141
3142static bool has_cap_mac_admin(bool audit)
3143{
3144 const struct cred *cred = current_cred();
3145 int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT;
3146
3147 if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit))
3148 return false;
3149 if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true))
3150 return false;
3151 return true;
3152}
3153
3110static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 3154static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3111 const void *value, size_t size, int flags) 3155 const void *value, size_t size, int flags)
3112{ 3156{
@@ -3138,7 +3182,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3138 3182
3139 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); 3183 rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
3140 if (rc == -EINVAL) { 3184 if (rc == -EINVAL) {
3141 if (!capable(CAP_MAC_ADMIN)) { 3185 if (!has_cap_mac_admin(true)) {
3142 struct audit_buffer *ab; 3186 struct audit_buffer *ab;
3143 size_t audit_size; 3187 size_t audit_size;
3144 const char *str; 3188 const char *str;
@@ -3264,13 +3308,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3264 * and lack of permission just means that we fall back to the 3308 * and lack of permission just means that we fall back to the
3265 * in-core context value, not a denial. 3309 * in-core context value, not a denial.
3266 */ 3310 */
3267 error = cap_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
3268 SECURITY_CAP_NOAUDIT);
3269 if (!error)
3270 error = cred_has_capability(current_cred(), CAP_MAC_ADMIN,
3271 SECURITY_CAP_NOAUDIT, true);
3272 isec = inode_security(inode); 3311 isec = inode_security(inode);
3273 if (!error) 3312 if (has_cap_mac_admin(false))
3274 error = security_sid_to_context_force(isec->sid, &context, 3313 error = security_sid_to_context_force(isec->sid, &context,
3275 &size); 3314 &size);
3276 else 3315 else
@@ -3550,6 +3589,18 @@ static int selinux_mmap_addr(unsigned long addr)
3550static int selinux_mmap_file(struct file *file, unsigned long reqprot, 3589static int selinux_mmap_file(struct file *file, unsigned long reqprot,
3551 unsigned long prot, unsigned long flags) 3590 unsigned long prot, unsigned long flags)
3552{ 3591{
3592 struct common_audit_data ad;
3593 int rc;
3594
3595 if (file) {
3596 ad.type = LSM_AUDIT_DATA_FILE;
3597 ad.u.file = file;
3598 rc = inode_has_perm(current_cred(), file_inode(file),
3599 FILE__MAP, &ad);
3600 if (rc)
3601 return rc;
3602 }
3603
3553 if (selinux_checkreqprot) 3604 if (selinux_checkreqprot)
3554 prot = reqprot; 3605 prot = reqprot;
3555 3606
@@ -3710,7 +3761,8 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
3710 3761
3711/* task security operations */ 3762/* task security operations */
3712 3763
3713static int selinux_task_create(unsigned long clone_flags) 3764static int selinux_task_alloc(struct task_struct *task,
3765 unsigned long clone_flags)
3714{ 3766{
3715 u32 sid = current_sid(); 3767 u32 sid = current_sid();
3716 3768
@@ -5918,7 +5970,7 @@ static int selinux_setprocattr(const char *name, void *value, size_t size)
5918 } 5970 }
5919 error = security_context_to_sid(value, size, &sid, GFP_KERNEL); 5971 error = security_context_to_sid(value, size, &sid, GFP_KERNEL);
5920 if (error == -EINVAL && !strcmp(name, "fscreate")) { 5972 if (error == -EINVAL && !strcmp(name, "fscreate")) {
5921 if (!capable(CAP_MAC_ADMIN)) { 5973 if (!has_cap_mac_admin(true)) {
5922 struct audit_buffer *ab; 5974 struct audit_buffer *ab;
5923 size_t audit_size; 5975 size_t audit_size;
5924 5976
@@ -6128,7 +6180,70 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)
6128 *_buffer = context; 6180 *_buffer = context;
6129 return rc; 6181 return rc;
6130} 6182}
6183#endif
6184
6185#ifdef CONFIG_SECURITY_INFINIBAND
6186static int selinux_ib_pkey_access(void *ib_sec, u64 subnet_prefix, u16 pkey_val)
6187{
6188 struct common_audit_data ad;
6189 int err;
6190 u32 sid = 0;
6191 struct ib_security_struct *sec = ib_sec;
6192 struct lsm_ibpkey_audit ibpkey;
6193
6194 err = sel_ib_pkey_sid(subnet_prefix, pkey_val, &sid);
6195 if (err)
6196 return err;
6197
6198 ad.type = LSM_AUDIT_DATA_IBPKEY;
6199 ibpkey.subnet_prefix = subnet_prefix;
6200 ibpkey.pkey = pkey_val;
6201 ad.u.ibpkey = &ibpkey;
6202 return avc_has_perm(sec->sid, sid,
6203 SECCLASS_INFINIBAND_PKEY,
6204 INFINIBAND_PKEY__ACCESS, &ad);
6205}
6206
6207static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
6208 u8 port_num)
6209{
6210 struct common_audit_data ad;
6211 int err;
6212 u32 sid = 0;
6213 struct ib_security_struct *sec = ib_sec;
6214 struct lsm_ibendport_audit ibendport;
6215
6216 err = security_ib_endport_sid(dev_name, port_num, &sid);
6217
6218 if (err)
6219 return err;
6220
6221 ad.type = LSM_AUDIT_DATA_IBENDPORT;
6222 strncpy(ibendport.dev_name, dev_name, sizeof(ibendport.dev_name));
6223 ibendport.port = port_num;
6224 ad.u.ibendport = &ibendport;
6225 return avc_has_perm(sec->sid, sid,
6226 SECCLASS_INFINIBAND_ENDPORT,
6227 INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
6228}
6229
6230static int selinux_ib_alloc_security(void **ib_sec)
6231{
6232 struct ib_security_struct *sec;
6131 6233
6234 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
6235 if (!sec)
6236 return -ENOMEM;
6237 sec->sid = current_sid();
6238
6239 *ib_sec = sec;
6240 return 0;
6241}
6242
6243static void selinux_ib_free_security(void *ib_sec)
6244{
6245 kfree(ib_sec);
6246}
6132#endif 6247#endif
6133 6248
6134static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { 6249static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
@@ -6213,7 +6328,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6213 6328
6214 LSM_HOOK_INIT(file_open, selinux_file_open), 6329 LSM_HOOK_INIT(file_open, selinux_file_open),
6215 6330
6216 LSM_HOOK_INIT(task_create, selinux_task_create), 6331 LSM_HOOK_INIT(task_alloc, selinux_task_alloc),
6217 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank), 6332 LSM_HOOK_INIT(cred_alloc_blank, selinux_cred_alloc_blank),
6218 LSM_HOOK_INIT(cred_free, selinux_cred_free), 6333 LSM_HOOK_INIT(cred_free, selinux_cred_free),
6219 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare), 6334 LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
@@ -6315,7 +6430,13 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6315 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue), 6430 LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
6316 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach), 6431 LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
6317 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open), 6432 LSM_HOOK_INIT(tun_dev_open, selinux_tun_dev_open),
6318 6433#ifdef CONFIG_SECURITY_INFINIBAND
6434 LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
6435 LSM_HOOK_INIT(ib_endport_manage_subnet,
6436 selinux_ib_endport_manage_subnet),
6437 LSM_HOOK_INIT(ib_alloc_security, selinux_ib_alloc_security),
6438 LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
6439#endif
6319#ifdef CONFIG_SECURITY_NETWORK_XFRM 6440#ifdef CONFIG_SECURITY_NETWORK_XFRM
6320 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc), 6441 LSM_HOOK_INIT(xfrm_policy_alloc_security, selinux_xfrm_policy_alloc),
6321 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone), 6442 LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone),
@@ -6379,6 +6500,9 @@ static __init int selinux_init(void)
6379 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) 6500 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6380 panic("SELinux: Unable to register AVC netcache callback\n"); 6501 panic("SELinux: Unable to register AVC netcache callback\n");
6381 6502
6503 if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET))
6504 panic("SELinux: Unable to register AVC LSM notifier callback\n");
6505
6382 if (selinux_enforcing) 6506 if (selinux_enforcing)
6383 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); 6507 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
6384 else 6508 else
@@ -6448,6 +6572,23 @@ static struct nf_hook_ops selinux_nf_ops[] = {
6448#endif /* IPV6 */ 6572#endif /* IPV6 */
6449}; 6573};
6450 6574
6575static int __net_init selinux_nf_register(struct net *net)
6576{
6577 return nf_register_net_hooks(net, selinux_nf_ops,
6578 ARRAY_SIZE(selinux_nf_ops));
6579}
6580
6581static void __net_exit selinux_nf_unregister(struct net *net)
6582{
6583 nf_unregister_net_hooks(net, selinux_nf_ops,
6584 ARRAY_SIZE(selinux_nf_ops));
6585}
6586
6587static struct pernet_operations selinux_net_ops = {
6588 .init = selinux_nf_register,
6589 .exit = selinux_nf_unregister,
6590};
6591
6451static int __init selinux_nf_ip_init(void) 6592static int __init selinux_nf_ip_init(void)
6452{ 6593{
6453 int err; 6594 int err;
@@ -6457,13 +6598,12 @@ static int __init selinux_nf_ip_init(void)
6457 6598
6458 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n"); 6599 printk(KERN_DEBUG "SELinux: Registering netfilter hooks\n");
6459 6600
6460 err = nf_register_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops)); 6601 err = register_pernet_subsys(&selinux_net_ops);
6461 if (err) 6602 if (err)
6462 panic("SELinux: nf_register_hooks: error %d\n", err); 6603 panic("SELinux: register_pernet_subsys: error %d\n", err);
6463 6604
6464 return 0; 6605 return 0;
6465} 6606}
6466
6467__initcall(selinux_nf_ip_init); 6607__initcall(selinux_nf_ip_init);
6468 6608
6469#ifdef CONFIG_SECURITY_SELINUX_DISABLE 6609#ifdef CONFIG_SECURITY_SELINUX_DISABLE
@@ -6471,7 +6611,7 @@ static void selinux_nf_ip_exit(void)
6471{ 6611{
6472 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n"); 6612 printk(KERN_DEBUG "SELinux: Unregistering netfilter hooks\n");
6473 6613
6474 nf_unregister_hooks(selinux_nf_ops, ARRAY_SIZE(selinux_nf_ops)); 6614 unregister_pernet_subsys(&selinux_net_ops);
6475} 6615}
6476#endif 6616#endif
6477 6617
diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c
new file mode 100644
index 000000000000..e3614ee5f1c0
--- /dev/null
+++ b/security/selinux/ibpkey.c
@@ -0,0 +1,245 @@
1/*
2 * Pkey table
3 *
4 * SELinux must keep a mapping of Infinband PKEYs to labels/SIDs. This
5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead.
7 *
8 * This code is heavily based on the "netif" and "netport" concept originally
9 * developed by
10 * James Morris <jmorris@redhat.com> and
11 * Paul Moore <paul@paul-moore.com>
12 * (see security/selinux/netif.c and security/selinux/netport.c for more
13 * information)
14 *
15 */
16
17/*
18 * (c) Mellanox Technologies, 2016
19 *
20 * This program is free software: you can redistribute it and/or modify
21 * it under the terms of version 2 of the GNU General Public License as
22 * published by the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 */
30
31#include <linux/types.h>
32#include <linux/rcupdate.h>
33#include <linux/list.h>
34#include <linux/spinlock.h>
35
36#include "ibpkey.h"
37#include "objsec.h"
38
39#define SEL_PKEY_HASH_SIZE 256
40#define SEL_PKEY_HASH_BKT_LIMIT 16
41
42struct sel_ib_pkey_bkt {
43 int size;
44 struct list_head list;
45};
46
47struct sel_ib_pkey {
48 struct pkey_security_struct psec;
49 struct list_head list;
50 struct rcu_head rcu;
51};
52
53static LIST_HEAD(sel_ib_pkey_list);
54static DEFINE_SPINLOCK(sel_ib_pkey_lock);
55static struct sel_ib_pkey_bkt sel_ib_pkey_hash[SEL_PKEY_HASH_SIZE];
56
57/**
58 * sel_ib_pkey_hashfn - Hashing function for the pkey table
59 * @pkey: pkey number
60 *
61 * Description:
62 * This is the hashing function for the pkey table, it returns the bucket
63 * number for the given pkey.
64 *
65 */
66static unsigned int sel_ib_pkey_hashfn(u16 pkey)
67{
68 return (pkey & (SEL_PKEY_HASH_SIZE - 1));
69}
70
71/**
72 * sel_ib_pkey_find - Search for a pkey record
73 * @subnet_prefix: subnet_prefix
74 * @pkey_num: pkey_num
75 *
76 * Description:
77 * Search the pkey table and return the matching record. If an entry
78 * can not be found in the table return NULL.
79 *
80 */
81static struct sel_ib_pkey *sel_ib_pkey_find(u64 subnet_prefix, u16 pkey_num)
82{
83 unsigned int idx;
84 struct sel_ib_pkey *pkey;
85
86 idx = sel_ib_pkey_hashfn(pkey_num);
87 list_for_each_entry_rcu(pkey, &sel_ib_pkey_hash[idx].list, list) {
88 if (pkey->psec.pkey == pkey_num &&
89 pkey->psec.subnet_prefix == subnet_prefix)
90 return pkey;
91 }
92
93 return NULL;
94}
95
96/**
97 * sel_ib_pkey_insert - Insert a new pkey into the table
98 * @pkey: the new pkey record
99 *
100 * Description:
101 * Add a new pkey record to the hash table.
102 *
103 */
104static void sel_ib_pkey_insert(struct sel_ib_pkey *pkey)
105{
106 unsigned int idx;
107
108 /* we need to impose a limit on the growth of the hash table so check
109 * this bucket to make sure it is within the specified bounds
110 */
111 idx = sel_ib_pkey_hashfn(pkey->psec.pkey);
112 list_add_rcu(&pkey->list, &sel_ib_pkey_hash[idx].list);
113 if (sel_ib_pkey_hash[idx].size == SEL_PKEY_HASH_BKT_LIMIT) {
114 struct sel_ib_pkey *tail;
115
116 tail = list_entry(
117 rcu_dereference_protected(
118 sel_ib_pkey_hash[idx].list.prev,
119 lockdep_is_held(&sel_ib_pkey_lock)),
120 struct sel_ib_pkey, list);
121 list_del_rcu(&tail->list);
122 kfree_rcu(tail, rcu);
123 } else {
124 sel_ib_pkey_hash[idx].size++;
125 }
126}
127
128/**
129 * sel_ib_pkey_sid_slow - Lookup the SID of a pkey using the policy
130 * @subnet_prefix: subnet prefix
131 * @pkey_num: pkey number
132 * @sid: pkey SID
133 *
134 * Description:
135 * This function determines the SID of a pkey by querying the security
136 * policy. The result is added to the pkey table to speedup future
137 * queries. Returns zero on success, negative values on failure.
138 *
139 */
140static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid)
141{
142 int ret;
143 struct sel_ib_pkey *pkey;
144 struct sel_ib_pkey *new = NULL;
145 unsigned long flags;
146
147 spin_lock_irqsave(&sel_ib_pkey_lock, flags);
148 pkey = sel_ib_pkey_find(subnet_prefix, pkey_num);
149 if (pkey) {
150 *sid = pkey->psec.sid;
151 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
152 return 0;
153 }
154
155 ret = security_ib_pkey_sid(subnet_prefix, pkey_num, sid);
156 if (ret)
157 goto out;
158
159 /* If this memory allocation fails still return 0. The SID
160 * is valid, it just won't be added to the cache.
161 */
162 new = kzalloc(sizeof(*new), GFP_ATOMIC);
163 if (!new)
164 goto out;
165
166 new->psec.subnet_prefix = subnet_prefix;
167 new->psec.pkey = pkey_num;
168 new->psec.sid = *sid;
169 sel_ib_pkey_insert(new);
170
171out:
172 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
173 return ret;
174}
175
176/**
177 * sel_ib_pkey_sid - Lookup the SID of a PKEY
178 * @subnet_prefix: subnet_prefix
179 * @pkey_num: pkey number
180 * @sid: pkey SID
181 *
182 * Description:
183 * This function determines the SID of a PKEY using the fastest method
184 * possible. First the pkey table is queried, but if an entry can't be found
185 * then the policy is queried and the result is added to the table to speedup
186 * future queries. Returns zero on success, negative values on failure.
187 *
188 */
189int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *sid)
190{
191 struct sel_ib_pkey *pkey;
192
193 rcu_read_lock();
194 pkey = sel_ib_pkey_find(subnet_prefix, pkey_num);
195 if (pkey) {
196 *sid = pkey->psec.sid;
197 rcu_read_unlock();
198 return 0;
199 }
200 rcu_read_unlock();
201
202 return sel_ib_pkey_sid_slow(subnet_prefix, pkey_num, sid);
203}
204
205/**
206 * sel_ib_pkey_flush - Flush the entire pkey table
207 *
208 * Description:
209 * Remove all entries from the pkey table
210 *
211 */
212void sel_ib_pkey_flush(void)
213{
214 unsigned int idx;
215 struct sel_ib_pkey *pkey, *pkey_tmp;
216 unsigned long flags;
217
218 spin_lock_irqsave(&sel_ib_pkey_lock, flags);
219 for (idx = 0; idx < SEL_PKEY_HASH_SIZE; idx++) {
220 list_for_each_entry_safe(pkey, pkey_tmp,
221 &sel_ib_pkey_hash[idx].list, list) {
222 list_del_rcu(&pkey->list);
223 kfree_rcu(pkey, rcu);
224 }
225 sel_ib_pkey_hash[idx].size = 0;
226 }
227 spin_unlock_irqrestore(&sel_ib_pkey_lock, flags);
228}
229
230static __init int sel_ib_pkey_init(void)
231{
232 int iter;
233
234 if (!selinux_enabled)
235 return 0;
236
237 for (iter = 0; iter < SEL_PKEY_HASH_SIZE; iter++) {
238 INIT_LIST_HEAD(&sel_ib_pkey_hash[iter].list);
239 sel_ib_pkey_hash[iter].size = 0;
240 }
241
242 return 0;
243}
244
245subsys_initcall(sel_ib_pkey_init);
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 1e0cc9b5de20..b9fe3434b036 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -1,7 +1,7 @@
1#include <linux/capability.h> 1#include <linux/capability.h>
2 2
3#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \ 3#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
4 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append" 4 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append", "map"
5 5
6#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \ 6#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
7 "rename", "execute", "quotaon", "mounton", "audit_access", \ 7 "rename", "execute", "quotaon", "mounton", "audit_access", \
@@ -231,6 +231,10 @@ struct security_class_mapping secclass_map[] = {
231 { COMMON_SOCK_PERMS, NULL } }, 231 { COMMON_SOCK_PERMS, NULL } },
232 { "smc_socket", 232 { "smc_socket",
233 { COMMON_SOCK_PERMS, NULL } }, 233 { COMMON_SOCK_PERMS, NULL } },
234 { "infiniband_pkey",
235 { "access", NULL } },
236 { "infiniband_endport",
237 { "manage_subnet", NULL } },
234 { NULL } 238 { NULL }
235 }; 239 };
236 240
diff --git a/security/selinux/include/ibpkey.h b/security/selinux/include/ibpkey.h
new file mode 100644
index 000000000000..b17a19e348e6
--- /dev/null
+++ b/security/selinux/include/ibpkey.h
@@ -0,0 +1,31 @@
1/*
2 * pkey table
3 *
4 * SELinux must keep a mapping of pkeys to labels/SIDs. This
5 * mapping is maintained as part of the normal policy but a fast cache is
6 * needed to reduce the lookup overhead.
7 *
8 */
9
10/*
11 * (c) Mellanox Technologies, 2016
12 *
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 */
23
24#ifndef _SELINUX_IB_PKEY_H
25#define _SELINUX_IB_PKEY_H
26
27void sel_ib_pkey_flush(void);
28
29int sel_ib_pkey_sid(u64 subnet_prefix, u16 pkey, u32 *sid);
30
31#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c03cdcd12a3b..6ebc61e370ff 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -10,6 +10,7 @@
10 * 10 *
11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc. 11 * Copyright (C) 2001,2002 Networks Associates Technology, Inc.
12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Copyright (C) 2016 Mellanox Technologies
13 * 14 *
14 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2, 16 * it under the terms of the GNU General Public License version 2,
@@ -139,6 +140,16 @@ struct key_security_struct {
139 u32 sid; /* SID of key */ 140 u32 sid; /* SID of key */
140}; 141};
141 142
143struct ib_security_struct {
144 u32 sid; /* SID of the queue pair or MAD agent */
145};
146
147struct pkey_security_struct {
148 u64 subnet_prefix; /* Port subnet prefix */
149 u16 pkey; /* PKey number */
150 u32 sid; /* SID of pkey */
151};
152
142extern unsigned int selinux_checkreqprot; 153extern unsigned int selinux_checkreqprot;
143 154
144#endif /* _SELINUX_OBJSEC_H_ */ 155#endif /* _SELINUX_OBJSEC_H_ */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index f979c35e037e..e91f08c16c0b 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -36,10 +36,11 @@
36#define POLICYDB_VERSION_DEFAULT_TYPE 28 36#define POLICYDB_VERSION_DEFAULT_TYPE 28
37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29 37#define POLICYDB_VERSION_CONSTRAINT_NAMES 29
38#define POLICYDB_VERSION_XPERMS_IOCTL 30 38#define POLICYDB_VERSION_XPERMS_IOCTL 30
39#define POLICYDB_VERSION_INFINIBAND 31
39 40
40/* Range of policy versions we understand*/ 41/* Range of policy versions we understand*/
41#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 42#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
42#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL 43#define POLICYDB_VERSION_MAX POLICYDB_VERSION_INFINIBAND
43 44
44/* Mask for just the mount related flags */ 45/* Mask for just the mount related flags */
45#define SE_MNTMASK 0x0f 46#define SE_MNTMASK 0x0f
@@ -76,6 +77,8 @@ enum {
76}; 77};
77#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 78#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
78 79
80extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX];
81
79extern int selinux_policycap_netpeer; 82extern int selinux_policycap_netpeer;
80extern int selinux_policycap_openperm; 83extern int selinux_policycap_openperm;
81extern int selinux_policycap_extsockclass; 84extern int selinux_policycap_extsockclass;
@@ -178,6 +181,10 @@ int security_get_user_sids(u32 callsid, char *username,
178 181
179int security_port_sid(u8 protocol, u16 port, u32 *out_sid); 182int security_port_sid(u8 protocol, u16 port, u32 *out_sid);
180 183
184int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid);
185
186int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid);
187
181int security_netif_sid(char *name, u32 *if_sid); 188int security_netif_sid(char *name, u32 *if_sid);
182 189
183int security_node_sid(u16 domain, void *addr, u32 addrlen, 190int security_node_sid(u16 domain, void *addr, u32 addrlen,
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 50062e70140d..9010a3632d6f 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -41,15 +41,6 @@
41#include "objsec.h" 41#include "objsec.h"
42#include "conditional.h" 42#include "conditional.h"
43 43
44/* Policy capability filenames */
45static char *policycap_names[] = {
46 "network_peer_controls",
47 "open_perms",
48 "extended_socket_class",
49 "always_check_network",
50 "cgroup_seclabel"
51};
52
53unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 44unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
54 45
55static int __init checkreqprot_setup(char *str) 46static int __init checkreqprot_setup(char *str)
@@ -163,6 +154,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
163 avc_ss_reset(0); 154 avc_ss_reset(0);
164 selnl_notify_setenforce(selinux_enforcing); 155 selnl_notify_setenforce(selinux_enforcing);
165 selinux_status_update_setenforce(selinux_enforcing); 156 selinux_status_update_setenforce(selinux_enforcing);
157 if (!selinux_enforcing)
158 call_lsm_notifier(LSM_POLICY_CHANGE, NULL);
166 } 159 }
167 length = count; 160 length = count;
168out: 161out:
@@ -1750,9 +1743,9 @@ static int sel_make_policycap(void)
1750 sel_remove_entries(policycap_dir); 1743 sel_remove_entries(policycap_dir);
1751 1744
1752 for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) { 1745 for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
1753 if (iter < ARRAY_SIZE(policycap_names)) 1746 if (iter < ARRAY_SIZE(selinux_policycap_names))
1754 dentry = d_alloc_name(policycap_dir, 1747 dentry = d_alloc_name(policycap_dir,
1755 policycap_names[iter]); 1748 selinux_policycap_names[iter]);
1756 else 1749 else
1757 dentry = d_alloc_name(policycap_dir, "unknown"); 1750 dentry = d_alloc_name(policycap_dir, "unknown");
1758 1751
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 9db4709a6877..ad38299164c3 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -24,6 +24,8 @@
24 24
25#define BITS_PER_U64 (sizeof(u64) * 8) 25#define BITS_PER_U64 (sizeof(u64) * 8)
26 26
27static struct kmem_cache *ebitmap_node_cachep;
28
27int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 29int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
28{ 30{
29 struct ebitmap_node *n1, *n2; 31 struct ebitmap_node *n1, *n2;
@@ -54,7 +56,7 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
54 n = src->node; 56 n = src->node;
55 prev = NULL; 57 prev = NULL;
56 while (n) { 58 while (n) {
57 new = kzalloc(sizeof(*new), GFP_ATOMIC); 59 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
58 if (!new) { 60 if (!new) {
59 ebitmap_destroy(dst); 61 ebitmap_destroy(dst);
60 return -ENOMEM; 62 return -ENOMEM;
@@ -162,7 +164,7 @@ int ebitmap_netlbl_import(struct ebitmap *ebmap,
162 if (e_iter == NULL || 164 if (e_iter == NULL ||
163 offset >= e_iter->startbit + EBITMAP_SIZE) { 165 offset >= e_iter->startbit + EBITMAP_SIZE) {
164 e_prev = e_iter; 166 e_prev = e_iter;
165 e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); 167 e_iter = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
166 if (e_iter == NULL) 168 if (e_iter == NULL)
167 goto netlbl_import_failure; 169 goto netlbl_import_failure;
168 e_iter->startbit = offset - (offset % EBITMAP_SIZE); 170 e_iter->startbit = offset - (offset % EBITMAP_SIZE);
@@ -288,7 +290,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
288 prev->next = n->next; 290 prev->next = n->next;
289 else 291 else
290 e->node = n->next; 292 e->node = n->next;
291 kfree(n); 293 kmem_cache_free(ebitmap_node_cachep, n);
292 } 294 }
293 return 0; 295 return 0;
294 } 296 }
@@ -299,7 +301,7 @@ int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
299 if (!value) 301 if (!value)
300 return 0; 302 return 0;
301 303
302 new = kzalloc(sizeof(*new), GFP_ATOMIC); 304 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
303 if (!new) 305 if (!new)
304 return -ENOMEM; 306 return -ENOMEM;
305 307
@@ -332,7 +334,7 @@ void ebitmap_destroy(struct ebitmap *e)
332 while (n) { 334 while (n) {
333 temp = n; 335 temp = n;
334 n = n->next; 336 n = n->next;
335 kfree(temp); 337 kmem_cache_free(ebitmap_node_cachep, temp);
336 } 338 }
337 339
338 e->highbit = 0; 340 e->highbit = 0;
@@ -400,7 +402,7 @@ int ebitmap_read(struct ebitmap *e, void *fp)
400 402
401 if (!n || startbit >= n->startbit + EBITMAP_SIZE) { 403 if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
402 struct ebitmap_node *tmp; 404 struct ebitmap_node *tmp;
403 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); 405 tmp = kmem_cache_zalloc(ebitmap_node_cachep, GFP_KERNEL);
404 if (!tmp) { 406 if (!tmp) {
405 printk(KERN_ERR 407 printk(KERN_ERR
406 "SELinux: ebitmap: out of memory\n"); 408 "SELinux: ebitmap: out of memory\n");
@@ -519,3 +521,15 @@ int ebitmap_write(struct ebitmap *e, void *fp)
519 } 521 }
520 return 0; 522 return 0;
521} 523}
524
525void ebitmap_cache_init(void)
526{
527 ebitmap_node_cachep = kmem_cache_create("ebitmap_node",
528 sizeof(struct ebitmap_node),
529 0, SLAB_PANIC, NULL);
530}
531
532void ebitmap_cache_destroy(void)
533{
534 kmem_cache_destroy(ebitmap_node_cachep);
535}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 9637b8c71085..6d5a9ac4251f 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -130,6 +130,9 @@ void ebitmap_destroy(struct ebitmap *e);
130int ebitmap_read(struct ebitmap *e, void *fp); 130int ebitmap_read(struct ebitmap *e, void *fp);
131int ebitmap_write(struct ebitmap *e, void *fp); 131int ebitmap_write(struct ebitmap *e, void *fp);
132 132
133void ebitmap_cache_init(void);
134void ebitmap_cache_destroy(void);
135
133#ifdef CONFIG_NETLABEL 136#ifdef CONFIG_NETLABEL
134int ebitmap_netlbl_export(struct ebitmap *ebmap, 137int ebitmap_netlbl_export(struct ebitmap *ebmap,
135 struct netlbl_lsm_catmap **catmap); 138 struct netlbl_lsm_catmap **catmap);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 0080122760ad..aa6500abb178 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -17,6 +17,11 @@
17 * 17 *
18 * Added support for the policy capability bitmap 18 * Added support for the policy capability bitmap
19 * 19 *
20 * Update: Mellanox Techonologies
21 *
22 * Added Infiniband support
23 *
24 * Copyright (C) 2016 Mellanox Techonologies
20 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. 25 * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
21 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 26 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
22 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 27 * Copyright (C) 2003 - 2004 Tresys Technology, LLC
@@ -76,81 +81,86 @@ static struct policydb_compat_info policydb_compat[] = {
76 { 81 {
77 .version = POLICYDB_VERSION_BASE, 82 .version = POLICYDB_VERSION_BASE,
78 .sym_num = SYM_NUM - 3, 83 .sym_num = SYM_NUM - 3,
79 .ocon_num = OCON_NUM - 1, 84 .ocon_num = OCON_NUM - 3,
80 }, 85 },
81 { 86 {
82 .version = POLICYDB_VERSION_BOOL, 87 .version = POLICYDB_VERSION_BOOL,
83 .sym_num = SYM_NUM - 2, 88 .sym_num = SYM_NUM - 2,
84 .ocon_num = OCON_NUM - 1, 89 .ocon_num = OCON_NUM - 3,
85 }, 90 },
86 { 91 {
87 .version = POLICYDB_VERSION_IPV6, 92 .version = POLICYDB_VERSION_IPV6,
88 .sym_num = SYM_NUM - 2, 93 .sym_num = SYM_NUM - 2,
89 .ocon_num = OCON_NUM, 94 .ocon_num = OCON_NUM - 2,
90 }, 95 },
91 { 96 {
92 .version = POLICYDB_VERSION_NLCLASS, 97 .version = POLICYDB_VERSION_NLCLASS,
93 .sym_num = SYM_NUM - 2, 98 .sym_num = SYM_NUM - 2,
94 .ocon_num = OCON_NUM, 99 .ocon_num = OCON_NUM - 2,
95 }, 100 },
96 { 101 {
97 .version = POLICYDB_VERSION_MLS, 102 .version = POLICYDB_VERSION_MLS,
98 .sym_num = SYM_NUM, 103 .sym_num = SYM_NUM,
99 .ocon_num = OCON_NUM, 104 .ocon_num = OCON_NUM - 2,
100 }, 105 },
101 { 106 {
102 .version = POLICYDB_VERSION_AVTAB, 107 .version = POLICYDB_VERSION_AVTAB,
103 .sym_num = SYM_NUM, 108 .sym_num = SYM_NUM,
104 .ocon_num = OCON_NUM, 109 .ocon_num = OCON_NUM - 2,
105 }, 110 },
106 { 111 {
107 .version = POLICYDB_VERSION_RANGETRANS, 112 .version = POLICYDB_VERSION_RANGETRANS,
108 .sym_num = SYM_NUM, 113 .sym_num = SYM_NUM,
109 .ocon_num = OCON_NUM, 114 .ocon_num = OCON_NUM - 2,
110 }, 115 },
111 { 116 {
112 .version = POLICYDB_VERSION_POLCAP, 117 .version = POLICYDB_VERSION_POLCAP,
113 .sym_num = SYM_NUM, 118 .sym_num = SYM_NUM,
114 .ocon_num = OCON_NUM, 119 .ocon_num = OCON_NUM - 2,
115 }, 120 },
116 { 121 {
117 .version = POLICYDB_VERSION_PERMISSIVE, 122 .version = POLICYDB_VERSION_PERMISSIVE,
118 .sym_num = SYM_NUM, 123 .sym_num = SYM_NUM,
119 .ocon_num = OCON_NUM, 124 .ocon_num = OCON_NUM - 2,
120 }, 125 },
121 { 126 {
122 .version = POLICYDB_VERSION_BOUNDARY, 127 .version = POLICYDB_VERSION_BOUNDARY,
123 .sym_num = SYM_NUM, 128 .sym_num = SYM_NUM,
124 .ocon_num = OCON_NUM, 129 .ocon_num = OCON_NUM - 2,
125 }, 130 },
126 { 131 {
127 .version = POLICYDB_VERSION_FILENAME_TRANS, 132 .version = POLICYDB_VERSION_FILENAME_TRANS,
128 .sym_num = SYM_NUM, 133 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM, 134 .ocon_num = OCON_NUM - 2,
130 }, 135 },
131 { 136 {
132 .version = POLICYDB_VERSION_ROLETRANS, 137 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM, 138 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM, 139 .ocon_num = OCON_NUM - 2,
135 }, 140 },
136 { 141 {
137 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 142 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
138 .sym_num = SYM_NUM, 143 .sym_num = SYM_NUM,
139 .ocon_num = OCON_NUM, 144 .ocon_num = OCON_NUM - 2,
140 }, 145 },
141 { 146 {
142 .version = POLICYDB_VERSION_DEFAULT_TYPE, 147 .version = POLICYDB_VERSION_DEFAULT_TYPE,
143 .sym_num = SYM_NUM, 148 .sym_num = SYM_NUM,
144 .ocon_num = OCON_NUM, 149 .ocon_num = OCON_NUM - 2,
145 }, 150 },
146 { 151 {
147 .version = POLICYDB_VERSION_CONSTRAINT_NAMES, 152 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
148 .sym_num = SYM_NUM, 153 .sym_num = SYM_NUM,
149 .ocon_num = OCON_NUM, 154 .ocon_num = OCON_NUM - 2,
150 }, 155 },
151 { 156 {
152 .version = POLICYDB_VERSION_XPERMS_IOCTL, 157 .version = POLICYDB_VERSION_XPERMS_IOCTL,
153 .sym_num = SYM_NUM, 158 .sym_num = SYM_NUM,
159 .ocon_num = OCON_NUM - 2,
160 },
161 {
162 .version = POLICYDB_VERSION_INFINIBAND,
163 .sym_num = SYM_NUM,
154 .ocon_num = OCON_NUM, 164 .ocon_num = OCON_NUM,
155 }, 165 },
156}; 166};
@@ -538,34 +548,30 @@ static int policydb_index(struct policydb *p)
538 symtab_hash_eval(p->symtab); 548 symtab_hash_eval(p->symtab);
539#endif 549#endif
540 550
541 rc = -ENOMEM;
542 p->class_val_to_struct = kcalloc(p->p_classes.nprim, 551 p->class_val_to_struct = kcalloc(p->p_classes.nprim,
543 sizeof(*p->class_val_to_struct), 552 sizeof(*p->class_val_to_struct),
544 GFP_KERNEL); 553 GFP_KERNEL);
545 if (!p->class_val_to_struct) 554 if (!p->class_val_to_struct)
546 goto out; 555 return -ENOMEM;
547 556
548 rc = -ENOMEM;
549 p->role_val_to_struct = kcalloc(p->p_roles.nprim, 557 p->role_val_to_struct = kcalloc(p->p_roles.nprim,
550 sizeof(*p->role_val_to_struct), 558 sizeof(*p->role_val_to_struct),
551 GFP_KERNEL); 559 GFP_KERNEL);
552 if (!p->role_val_to_struct) 560 if (!p->role_val_to_struct)
553 goto out; 561 return -ENOMEM;
554 562
555 rc = -ENOMEM;
556 p->user_val_to_struct = kcalloc(p->p_users.nprim, 563 p->user_val_to_struct = kcalloc(p->p_users.nprim,
557 sizeof(*p->user_val_to_struct), 564 sizeof(*p->user_val_to_struct),
558 GFP_KERNEL); 565 GFP_KERNEL);
559 if (!p->user_val_to_struct) 566 if (!p->user_val_to_struct)
560 goto out; 567 return -ENOMEM;
561 568
562 /* Yes, I want the sizeof the pointer, not the structure */ 569 /* Yes, I want the sizeof the pointer, not the structure */
563 rc = -ENOMEM;
564 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), 570 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
565 p->p_types.nprim, 571 p->p_types.nprim,
566 GFP_KERNEL | __GFP_ZERO); 572 GFP_KERNEL | __GFP_ZERO);
567 if (!p->type_val_to_struct_array) 573 if (!p->type_val_to_struct_array)
568 goto out; 574 return -ENOMEM;
569 575
570 rc = flex_array_prealloc(p->type_val_to_struct_array, 0, 576 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
571 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO); 577 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
@@ -577,12 +583,11 @@ static int policydb_index(struct policydb *p)
577 goto out; 583 goto out;
578 584
579 for (i = 0; i < SYM_NUM; i++) { 585 for (i = 0; i < SYM_NUM; i++) {
580 rc = -ENOMEM;
581 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), 586 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
582 p->symtab[i].nprim, 587 p->symtab[i].nprim,
583 GFP_KERNEL | __GFP_ZERO); 588 GFP_KERNEL | __GFP_ZERO);
584 if (!p->sym_val_to_name[i]) 589 if (!p->sym_val_to_name[i])
585 goto out; 590 return -ENOMEM;
586 591
587 rc = flex_array_prealloc(p->sym_val_to_name[i], 592 rc = flex_array_prealloc(p->sym_val_to_name[i],
588 0, p->symtab[i].nprim, 593 0, p->symtab[i].nprim,
@@ -2211,6 +2216,51 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2211 goto out; 2216 goto out;
2212 break; 2217 break;
2213 } 2218 }
2219 case OCON_IBPKEY:
2220 rc = next_entry(nodebuf, fp, sizeof(u32) * 4);
2221 if (rc)
2222 goto out;
2223
2224 c->u.ibpkey.subnet_prefix = be64_to_cpu(*((__be64 *)nodebuf));
2225
2226 if (nodebuf[2] > 0xffff ||
2227 nodebuf[3] > 0xffff) {
2228 rc = -EINVAL;
2229 goto out;
2230 }
2231
2232 c->u.ibpkey.low_pkey = le32_to_cpu(nodebuf[2]);
2233 c->u.ibpkey.high_pkey = le32_to_cpu(nodebuf[3]);
2234
2235 rc = context_read_and_validate(&c->context[0],
2236 p,
2237 fp);
2238 if (rc)
2239 goto out;
2240 break;
2241 case OCON_IBENDPORT:
2242 rc = next_entry(buf, fp, sizeof(u32) * 2);
2243 if (rc)
2244 goto out;
2245 len = le32_to_cpu(buf[0]);
2246
2247 rc = str_read(&c->u.ibendport.dev_name, GFP_KERNEL, fp, len);
2248 if (rc)
2249 goto out;
2250
2251 if (buf[1] > 0xff || buf[1] == 0) {
2252 rc = -EINVAL;
2253 goto out;
2254 }
2255
2256 c->u.ibendport.port = le32_to_cpu(buf[1]);
2257
2258 rc = context_read_and_validate(&c->context[0],
2259 p,
2260 fp);
2261 if (rc)
2262 goto out;
2263 break;
2214 } 2264 }
2215 } 2265 }
2216 } 2266 }
@@ -3140,6 +3190,33 @@ static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
3140 if (rc) 3190 if (rc)
3141 return rc; 3191 return rc;
3142 break; 3192 break;
3193 case OCON_IBPKEY:
3194 *((__be64 *)nodebuf) = cpu_to_be64(c->u.ibpkey.subnet_prefix);
3195
3196 nodebuf[2] = cpu_to_le32(c->u.ibpkey.low_pkey);
3197 nodebuf[3] = cpu_to_le32(c->u.ibpkey.high_pkey);
3198
3199 rc = put_entry(nodebuf, sizeof(u32), 4, fp);
3200 if (rc)
3201 return rc;
3202 rc = context_write(p, &c->context[0], fp);
3203 if (rc)
3204 return rc;
3205 break;
3206 case OCON_IBENDPORT:
3207 len = strlen(c->u.ibendport.dev_name);
3208 buf[0] = cpu_to_le32(len);
3209 buf[1] = cpu_to_le32(c->u.ibendport.port);
3210 rc = put_entry(buf, sizeof(u32), 2, fp);
3211 if (rc)
3212 return rc;
3213 rc = put_entry(c->u.ibendport.dev_name, 1, len, fp);
3214 if (rc)
3215 return rc;
3216 rc = context_write(p, &c->context[0], fp);
3217 if (rc)
3218 return rc;
3219 break;
3143 } 3220 }
3144 } 3221 }
3145 } 3222 }
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 725d5945a97e..5d23eed35fa7 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -187,6 +187,15 @@ struct ocontext {
187 u32 addr[4]; 187 u32 addr[4];
188 u32 mask[4]; 188 u32 mask[4];
189 } node6; /* IPv6 node information */ 189 } node6; /* IPv6 node information */
190 struct {
191 u64 subnet_prefix;
192 u16 low_pkey;
193 u16 high_pkey;
194 } ibpkey;
195 struct {
196 char *dev_name;
197 u8 port;
198 } ibendport;
190 } u; 199 } u;
191 union { 200 union {
192 u32 sclass; /* security class for genfs */ 201 u32 sclass; /* security class for genfs */
@@ -215,14 +224,16 @@ struct genfs {
215#define SYM_NUM 8 224#define SYM_NUM 8
216 225
217/* object context array indices */ 226/* object context array indices */
218#define OCON_ISID 0 /* initial SIDs */ 227#define OCON_ISID 0 /* initial SIDs */
219#define OCON_FS 1 /* unlabeled file systems */ 228#define OCON_FS 1 /* unlabeled file systems */
220#define OCON_PORT 2 /* TCP and UDP port numbers */ 229#define OCON_PORT 2 /* TCP and UDP port numbers */
221#define OCON_NETIF 3 /* network interfaces */ 230#define OCON_NETIF 3 /* network interfaces */
222#define OCON_NODE 4 /* nodes */ 231#define OCON_NODE 4 /* nodes */
223#define OCON_FSUSE 5 /* fs_use */ 232#define OCON_FSUSE 5 /* fs_use */
224#define OCON_NODE6 6 /* IPv6 nodes */ 233#define OCON_NODE6 6 /* IPv6 nodes */
225#define OCON_NUM 7 234#define OCON_IBPKEY 7 /* Infiniband PKeys */
235#define OCON_IBENDPORT 8 /* Infiniband end ports */
236#define OCON_NUM 9
226 237
227/* The policy database */ 238/* The policy database */
228struct policydb { 239struct policydb {
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 60d9b0252321..2f02fa67ec2e 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -70,6 +70,15 @@
70#include "ebitmap.h" 70#include "ebitmap.h"
71#include "audit.h" 71#include "audit.h"
72 72
73/* Policy capability names */
74char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = {
75 "network_peer_controls",
76 "open_perms",
77 "extended_socket_class",
78 "always_check_network",
79 "cgroup_seclabel"
80};
81
73int selinux_policycap_netpeer; 82int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 83int selinux_policycap_openperm;
75int selinux_policycap_extsockclass; 84int selinux_policycap_extsockclass;
@@ -1986,6 +1995,9 @@ bad:
1986 1995
1987static void security_load_policycaps(void) 1996static void security_load_policycaps(void)
1988{ 1997{
1998 unsigned int i;
1999 struct ebitmap_node *node;
2000
1989 selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, 2001 selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps,
1990 POLICYDB_CAPABILITY_NETPEER); 2002 POLICYDB_CAPABILITY_NETPEER);
1991 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 2003 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
@@ -1997,6 +2009,17 @@ static void security_load_policycaps(void)
1997 selinux_policycap_cgroupseclabel = 2009 selinux_policycap_cgroupseclabel =
1998 ebitmap_get_bit(&policydb.policycaps, 2010 ebitmap_get_bit(&policydb.policycaps,
1999 POLICYDB_CAPABILITY_CGROUPSECLABEL); 2011 POLICYDB_CAPABILITY_CGROUPSECLABEL);
2012
2013 for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++)
2014 pr_info("SELinux: policy capability %s=%d\n",
2015 selinux_policycap_names[i],
2016 ebitmap_get_bit(&policydb.policycaps, i));
2017
2018 ebitmap_for_each_positive_bit(&policydb.policycaps, node, i) {
2019 if (i >= ARRAY_SIZE(selinux_policycap_names))
2020 pr_info("SELinux: unknown policy capability %u\n",
2021 i);
2022 }
2000} 2023}
2001 2024
2002static int security_preserve_bools(struct policydb *p); 2025static int security_preserve_bools(struct policydb *p);
@@ -2031,9 +2054,11 @@ int security_load_policy(void *data, size_t len)
2031 2054
2032 if (!ss_initialized) { 2055 if (!ss_initialized) {
2033 avtab_cache_init(); 2056 avtab_cache_init();
2057 ebitmap_cache_init();
2034 rc = policydb_read(&policydb, fp); 2058 rc = policydb_read(&policydb, fp);
2035 if (rc) { 2059 if (rc) {
2036 avtab_cache_destroy(); 2060 avtab_cache_destroy();
2061 ebitmap_cache_destroy();
2037 goto out; 2062 goto out;
2038 } 2063 }
2039 2064
@@ -2044,6 +2069,7 @@ int security_load_policy(void *data, size_t len)
2044 if (rc) { 2069 if (rc) {
2045 policydb_destroy(&policydb); 2070 policydb_destroy(&policydb);
2046 avtab_cache_destroy(); 2071 avtab_cache_destroy();
2072 ebitmap_cache_destroy();
2047 goto out; 2073 goto out;
2048 } 2074 }
2049 2075
@@ -2051,6 +2077,7 @@ int security_load_policy(void *data, size_t len)
2051 if (rc) { 2077 if (rc) {
2052 policydb_destroy(&policydb); 2078 policydb_destroy(&policydb);
2053 avtab_cache_destroy(); 2079 avtab_cache_destroy();
2080 ebitmap_cache_destroy();
2054 goto out; 2081 goto out;
2055 } 2082 }
2056 2083
@@ -2210,6 +2237,87 @@ out:
2210} 2237}
2211 2238
2212/** 2239/**
2240 * security_pkey_sid - Obtain the SID for a pkey.
2241 * @subnet_prefix: Subnet Prefix
2242 * @pkey_num: pkey number
2243 * @out_sid: security identifier
2244 */
2245int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid)
2246{
2247 struct ocontext *c;
2248 int rc = 0;
2249
2250 read_lock(&policy_rwlock);
2251
2252 c = policydb.ocontexts[OCON_IBPKEY];
2253 while (c) {
2254 if (c->u.ibpkey.low_pkey <= pkey_num &&
2255 c->u.ibpkey.high_pkey >= pkey_num &&
2256 c->u.ibpkey.subnet_prefix == subnet_prefix)
2257 break;
2258
2259 c = c->next;
2260 }
2261
2262 if (c) {
2263 if (!c->sid[0]) {
2264 rc = sidtab_context_to_sid(&sidtab,
2265 &c->context[0],
2266 &c->sid[0]);
2267 if (rc)
2268 goto out;
2269 }
2270 *out_sid = c->sid[0];
2271 } else
2272 *out_sid = SECINITSID_UNLABELED;
2273
2274out:
2275 read_unlock(&policy_rwlock);
2276 return rc;
2277}
2278
2279/**
2280 * security_ib_endport_sid - Obtain the SID for a subnet management interface.
2281 * @dev_name: device name
2282 * @port: port number
2283 * @out_sid: security identifier
2284 */
2285int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid)
2286{
2287 struct ocontext *c;
2288 int rc = 0;
2289
2290 read_lock(&policy_rwlock);
2291
2292 c = policydb.ocontexts[OCON_IBENDPORT];
2293 while (c) {
2294 if (c->u.ibendport.port == port_num &&
2295 !strncmp(c->u.ibendport.dev_name,
2296 dev_name,
2297 IB_DEVICE_NAME_MAX))
2298 break;
2299
2300 c = c->next;
2301 }
2302
2303 if (c) {
2304 if (!c->sid[0]) {
2305 rc = sidtab_context_to_sid(&sidtab,
2306 &c->context[0],
2307 &c->sid[0]);
2308 if (rc)
2309 goto out;
2310 }
2311 *out_sid = c->sid[0];
2312 } else
2313 *out_sid = SECINITSID_UNLABELED;
2314
2315out:
2316 read_unlock(&policy_rwlock);
2317 return rc;
2318}
2319
2320/**
2213 * security_netif_sid - Obtain the SID for a network interface. 2321 * security_netif_sid - Obtain the SID for a network interface.
2214 * @name: interface name 2322 * @name: interface name
2215 * @if_sid: interface SID 2323 * @if_sid: interface SID
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index f6915f257486..c5f436b15d19 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -32,13 +32,11 @@ int sidtab_init(struct sidtab *s)
32 32
33int sidtab_insert(struct sidtab *s, u32 sid, struct context *context) 33int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
34{ 34{
35 int hvalue, rc = 0; 35 int hvalue;
36 struct sidtab_node *prev, *cur, *newnode; 36 struct sidtab_node *prev, *cur, *newnode;
37 37
38 if (!s) { 38 if (!s)
39 rc = -ENOMEM; 39 return -ENOMEM;
40 goto out;
41 }
42 40
43 hvalue = SIDTAB_HASH(sid); 41 hvalue = SIDTAB_HASH(sid);
44 prev = NULL; 42 prev = NULL;
@@ -48,21 +46,17 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
48 cur = cur->next; 46 cur = cur->next;
49 } 47 }
50 48
51 if (cur && sid == cur->sid) { 49 if (cur && sid == cur->sid)
52 rc = -EEXIST; 50 return -EEXIST;
53 goto out;
54 }
55 51
56 newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC); 52 newnode = kmalloc(sizeof(*newnode), GFP_ATOMIC);
57 if (!newnode) { 53 if (!newnode)
58 rc = -ENOMEM; 54 return -ENOMEM;
59 goto out; 55
60 }
61 newnode->sid = sid; 56 newnode->sid = sid;
62 if (context_cpy(&newnode->context, context)) { 57 if (context_cpy(&newnode->context, context)) {
63 kfree(newnode); 58 kfree(newnode);
64 rc = -ENOMEM; 59 return -ENOMEM;
65 goto out;
66 } 60 }
67 61
68 if (prev) { 62 if (prev) {
@@ -78,8 +72,7 @@ int sidtab_insert(struct sidtab *s, u32 sid, struct context *context)
78 s->nel++; 72 s->nel++;
79 if (sid >= s->next_sid) 73 if (sid >= s->next_sid)
80 s->next_sid = sid + 1; 74 s->next_sid = sid + 1;
81out: 75 return 0;
82 return rc;
83} 76}
84 77
85static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force) 78static struct context *sidtab_search_core(struct sidtab *s, u32 sid, int force)