aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/lsm_hook_defs.h1
-rw-r--r--include/linux/lsm_hooks.h1
-rw-r--r--security/security.c20
-rw-r--r--security/selinux/hooks.c18
-rw-r--r--security/selinux/include/objsec.h6
5 files changed, 29 insertions, 17 deletions
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 4fcbc5b3f58c..12c81be78eb9 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -439,7 +439,6 @@ LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
#ifdef CONFIG_PERF_EVENTS
LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type)
LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event)
-LSM_HOOK(void, LSM_RET_VOID, perf_event_free, struct perf_event *event)
LSM_HOOK(int, 0, perf_event_read, struct perf_event *event)
LSM_HOOK(int, 0, perf_event_write, struct perf_event *event)
#endif /* CONFIG_PERF_EVENTS */
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index b6fc6ac88723..f1ca8082075a 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -79,6 +79,7 @@ struct lsm_blob_sizes {
int lbs_ipc;
int lbs_key;
int lbs_msg_msg;
+ int lbs_perf_event;
int lbs_task;
int lbs_xattr_count; /* number of xattr slots in new_xattrs array */
int lbs_tun_dev;
diff --git a/security/security.c b/security/security.c
index 80dc58d60aab..93ed7670fbc9 100644
--- a/security/security.c
+++ b/security/security.c
@@ -28,6 +28,7 @@
#include <linux/xattr.h>
#include <linux/msg.h>
#include <linux/overflow.h>
+#include <linux/perf_event.h>
#include <net/flow.h>
#include <net/sock.h>
@@ -230,6 +231,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key);
lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
+ lsm_set_blob_size(&needed->lbs_perf_event, &blob_sizes.lbs_perf_event);
lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
@@ -412,6 +414,7 @@ static void __init ordered_lsm_init(void)
init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
+ init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
init_debug("task blob size = %d\n", blob_sizes.lbs_task);
init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
@@ -5685,7 +5688,19 @@ int security_perf_event_open(struct perf_event_attr *attr, int type)
*/
int security_perf_event_alloc(struct perf_event *event)
{
- return call_int_hook(perf_event_alloc, event);
+ int rc;
+
+ rc = lsm_blob_alloc(&event->security, blob_sizes.lbs_perf_event,
+ GFP_KERNEL);
+ if (rc)
+ return rc;
+
+ rc = call_int_hook(perf_event_alloc, event);
+ if (rc) {
+ kfree(event->security);
+ event->security = NULL;
+ }
+ return rc;
}
/**
@@ -5696,7 +5711,8 @@ int security_perf_event_alloc(struct perf_event *event)
*/
void security_perf_event_free(struct perf_event *event)
{
- call_void_hook(perf_event_free, event);
+ kfree(event->security);
+ event->security = NULL;
}
/**
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 675c69ebb77c..0939816e9671 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6955,6 +6955,9 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
.lbs_ipc = sizeof(struct ipc_security_struct),
.lbs_key = sizeof(struct key_security_struct),
.lbs_msg_msg = sizeof(struct msg_security_struct),
+#ifdef CONFIG_PERF_EVENTS
+ .lbs_perf_event = sizeof(struct perf_event_security_struct),
+#endif
.lbs_sock = sizeof(struct sk_security_struct),
.lbs_superblock = sizeof(struct superblock_security_struct),
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
@@ -6986,24 +6989,12 @@ static int selinux_perf_event_alloc(struct perf_event *event)
{
struct perf_event_security_struct *perfsec;
- perfsec = kzalloc(sizeof(*perfsec), GFP_KERNEL);
- if (!perfsec)
- return -ENOMEM;
-
+ perfsec = selinux_perf_event(event->security);
perfsec->sid = current_sid();
- event->security = perfsec;
return 0;
}
-static void selinux_perf_event_free(struct perf_event *event)
-{
- struct perf_event_security_struct *perfsec = event->security;
-
- event->security = NULL;
- kfree(perfsec);
-}
-
static int selinux_perf_event_read(struct perf_event *event)
{
struct perf_event_security_struct *perfsec = event->security;
@@ -7316,7 +7307,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
#ifdef CONFIG_PERF_EVENTS
LSM_HOOK_INIT(perf_event_open, selinux_perf_event_open),
- LSM_HOOK_INIT(perf_event_free, selinux_perf_event_free),
LSM_HOOK_INIT(perf_event_read, selinux_perf_event_read),
LSM_HOOK_INIT(perf_event_write, selinux_perf_event_write),
#endif
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index ed9e37f3c9b5..c88cae81ee4c 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -217,4 +217,10 @@ static inline struct ib_security_struct *selinux_ib(void *ib_sec)
return ib_sec + selinux_blob_sizes.lbs_ib;
}
+static inline struct perf_event_security_struct *
+selinux_perf_event(void *perf_event)
+{
+ return perf_event + selinux_blob_sizes.lbs_perf_event;
+}
+
#endif /* _SELINUX_OBJSEC_H_ */