|
@@ -39,6 +39,8 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/mutex.h>
|
|
|
#include <linux/netdevice.h>
|
|
|
+#include <linux/security.h>
|
|
|
+#include <linux/notifier.h>
|
|
|
#include <rdma/rdma_netlink.h>
|
|
|
#include <rdma/ib_addr.h>
|
|
|
#include <rdma/ib_cache.h>
|
|
@@ -82,6 +84,14 @@ static LIST_HEAD(client_list);
|
|
|
static DEFINE_MUTEX(device_mutex);
|
|
|
static DECLARE_RWSEM(lists_rwsem);
|
|
|
|
|
|
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
|
|
|
+ void *lsm_data);
|
|
|
+static void ib_policy_change_task(struct work_struct *work);
|
|
|
+static DECLARE_WORK(ib_policy_change_work, ib_policy_change_task);
|
|
|
+
|
|
|
+static struct notifier_block ibdev_lsm_nb = {
|
|
|
+ .notifier_call = ib_security_change,
|
|
|
+};
|
|
|
|
|
|
static int ib_device_check_mandatory(struct ib_device *device)
|
|
|
{
|
|
@@ -349,6 +359,40 @@ static int setup_port_pkey_list(struct ib_device *device)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void ib_policy_change_task(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct ib_device *dev;
|
|
|
+
|
|
|
+ down_read(&lists_rwsem);
|
|
|
+ list_for_each_entry(dev, &device_list, core_list) {
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = rdma_start_port(dev); i <= rdma_end_port(dev); i++) {
|
|
|
+ u64 sp;
|
|
|
+ int ret = ib_get_cached_subnet_prefix(dev,
|
|
|
+ i,
|
|
|
+ &sp);
|
|
|
+
|
|
|
+ WARN_ONCE(ret,
|
|
|
+ "ib_get_cached_subnet_prefix err: %d, this should never happen here\n",
|
|
|
+ ret);
|
|
|
+ ib_security_cache_change(dev, i, sp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ up_read(&lists_rwsem);
|
|
|
+}
|
|
|
+
|
|
|
+static int ib_security_change(struct notifier_block *nb, unsigned long event,
|
|
|
+ void *lsm_data)
|
|
|
+{
|
|
|
+ if (event != LSM_POLICY_CHANGE)
|
|
|
+ return NOTIFY_DONE;
|
|
|
+
|
|
|
+ schedule_work(&ib_policy_change_work);
|
|
|
+
|
|
|
+ return NOTIFY_OK;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* ib_register_device - Register an IB device with IB core
|
|
|
* @device:Device to register
|
|
@@ -1115,10 +1159,18 @@ static int __init ib_core_init(void)
|
|
|
goto err_sa;
|
|
|
}
|
|
|
|
|
|
+ ret = register_lsm_notifier(&ibdev_lsm_nb);
|
|
|
+ if (ret) {
|
|
|
+ pr_warn("Couldn't register LSM notifier. ret %d\n", ret);
|
|
|
+ goto err_ibnl_clients;
|
|
|
+ }
|
|
|
+
|
|
|
ib_cache_setup();
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
+err_ibnl_clients:
|
|
|
+ ib_remove_ibnl_clients();
|
|
|
err_sa:
|
|
|
ib_sa_cleanup();
|
|
|
err_mad:
|
|
@@ -1138,6 +1190,7 @@ err:
|
|
|
|
|
|
static void __exit ib_core_cleanup(void)
|
|
|
{
|
|
|
+ unregister_lsm_notifier(&ibdev_lsm_nb);
|
|
|
ib_cache_cleanup();
|
|
|
ib_remove_ibnl_clients();
|
|
|
ib_sa_cleanup();
|