summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/lsm_hook_defs.h3
-rw-r--r--include/linux/lsm_hooks.h1
-rw-r--r--security/security.c17
-rw-r--r--security/selinux/hooks.c22
-rw-r--r--security/selinux/include/objsec.h5
5 files changed, 28 insertions, 20 deletions
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 8cc60644f3bd..22c475f530ae 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -353,8 +353,7 @@ LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_inc, void)
LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void)
LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct request_sock *req,
struct flowi_common *flic)
-LSM_HOOK(int, 0, tun_dev_alloc_security, void **security)
-LSM_HOOK(void, LSM_RET_VOID, tun_dev_free_security, void *security)
+LSM_HOOK(int, 0, tun_dev_alloc_security, void *security)
LSM_HOOK(int, 0, tun_dev_create, void)
LSM_HOOK(int, 0, tun_dev_attach_queue, void *security)
LSM_HOOK(int, 0, tun_dev_attach, struct sock *sk, void *security)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7233bc0737be..0ff14ff128c8 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -80,6 +80,7 @@ struct lsm_blob_sizes {
int lbs_msg_msg;
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 15efcf43e168..137a1f7e0e8b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -232,6 +232,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
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);
+ lsm_set_blob_size(&needed->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
lsm_set_blob_size(&needed->lbs_xattr_count,
&blob_sizes.lbs_xattr_count);
}
@@ -410,6 +411,7 @@ static void __init ordered_lsm_init(void)
init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
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);
/*
@@ -4875,7 +4877,18 @@ EXPORT_SYMBOL(security_secmark_refcount_dec);
*/
int security_tun_dev_alloc_security(void **security)
{
- return call_int_hook(tun_dev_alloc_security, security);
+ int rc;
+
+ rc = lsm_blob_alloc(security, blob_sizes.lbs_tun_dev, GFP_KERNEL);
+ if (rc)
+ return rc;
+
+ rc = call_int_hook(tun_dev_alloc_security, *security);
+ if (rc) {
+ kfree(*security);
+ *security = NULL;
+ }
+ return rc;
}
EXPORT_SYMBOL(security_tun_dev_alloc_security);
@@ -4887,7 +4900,7 @@ EXPORT_SYMBOL(security_tun_dev_alloc_security);
*/
void security_tun_dev_free_security(void *security)
{
- call_void_hook(tun_dev_free_security, security);
+ kfree(security);
}
EXPORT_SYMBOL(security_tun_dev_free_security);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7dbf169f733f..793cfdc4c0ef 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5578,24 +5578,14 @@ static void selinux_req_classify_flow(const struct request_sock *req,
flic->flowic_secid = req->secid;
}
-static int selinux_tun_dev_alloc_security(void **security)
+static int selinux_tun_dev_alloc_security(void *security)
{
- struct tun_security_struct *tunsec;
+ struct tun_security_struct *tunsec = selinux_tun_dev(security);
- tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
- if (!tunsec)
- return -ENOMEM;
tunsec->sid = current_sid();
-
- *security = tunsec;
return 0;
}
-static void selinux_tun_dev_free_security(void *security)
-{
- kfree(security);
-}
-
static int selinux_tun_dev_create(void)
{
u32 sid = current_sid();
@@ -5613,7 +5603,7 @@ static int selinux_tun_dev_create(void)
static int selinux_tun_dev_attach_queue(void *security)
{
- struct tun_security_struct *tunsec = security;
+ struct tun_security_struct *tunsec = selinux_tun_dev(security);
return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
TUN_SOCKET__ATTACH_QUEUE, NULL);
@@ -5621,7 +5611,7 @@ static int selinux_tun_dev_attach_queue(void *security)
static int selinux_tun_dev_attach(struct sock *sk, void *security)
{
- struct tun_security_struct *tunsec = security;
+ struct tun_security_struct *tunsec = selinux_tun_dev(security);
struct sk_security_struct *sksec = selinux_sock(sk);
/* we don't currently perform any NetLabel based labeling here and it
@@ -5639,7 +5629,7 @@ static int selinux_tun_dev_attach(struct sock *sk, void *security)
static int selinux_tun_dev_open(void *security)
{
- struct tun_security_struct *tunsec = security;
+ struct tun_security_struct *tunsec = selinux_tun_dev(security);
u32 sid = current_sid();
int err;
@@ -6978,6 +6968,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
.lbs_sock = sizeof(struct sk_security_struct),
.lbs_superblock = sizeof(struct superblock_security_struct),
.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
+ .lbs_tun_dev = sizeof(struct tun_security_struct),
};
#ifdef CONFIG_PERF_EVENTS
@@ -7289,7 +7280,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
- LSM_HOOK_INIT(tun_dev_free_security, selinux_tun_dev_free_security),
LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 83b9443d6919..b7d4b1fc8fee 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -207,4 +207,9 @@ static inline struct sk_security_struct *selinux_sock(const struct sock *sock)
return sock->sk_security + selinux_blob_sizes.lbs_sock;
}
+static inline struct tun_security_struct *selinux_tun_dev(void *security)
+{
+ return security + selinux_blob_sizes.lbs_tun_dev;
+}
+
#endif /* _SELINUX_OBJSEC_H_ */