[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210405085019.951555935@linuxfoundation.org>
Date: Mon, 5 Apr 2021 10:54:09 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, teroincn@...il.com,
Richard Guy Briggs <rgb@...hat.com>,
Paul Moore <paul@...l-moore.com>,
Wen Yang <wenyang@...ux.alibaba.com>
Subject: [PATCH 4.9 34/35] audit: fix a net reference leak in audit_send_reply()
From: Paul Moore <paul@...l-moore.com>
commit a48b284b403a4a073d8beb72d2bb33e54df67fb6 upstream.
If audit_send_reply() fails when trying to create a new thread to
send the reply it also fails to cleanup properly, leaking a reference
to a net structure. This patch fixes the error path and makes a
handful of other cleanups that came up while fixing the code.
Reported-by: teroincn@...il.com
Reviewed-by: Richard Guy Briggs <rgb@...hat.com>
Signed-off-by: Paul Moore <paul@...l-moore.com>
Cc: <stable@...r.kernel.org> # 4.9.x
Signed-off-by: Wen Yang <wenyang@...ux.alibaba.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
kernel/audit.c | 46 ++++++++++++++++++++++++++++------------------
1 file changed, 28 insertions(+), 18 deletions(-)
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -580,6 +580,18 @@ out_kfree_skb:
return NULL;
}
+static void audit_free_reply(struct audit_reply *reply)
+{
+ if (!reply)
+ return;
+
+ if (reply->skb)
+ kfree_skb(reply->skb);
+ if (reply->net)
+ put_net(reply->net);
+ kfree(reply);
+}
+
static int audit_send_reply_thread(void *arg)
{
struct audit_reply *reply = (struct audit_reply *)arg;
@@ -592,8 +604,8 @@ static int audit_send_reply_thread(void
/* Ignore failure. It'll only happen if the sender goes away,
because our timeout is set to infinite. */
netlink_unicast(aunet->nlsk , reply->skb, reply->portid, 0);
- put_net(net);
- kfree(reply);
+ reply->skb = NULL;
+ audit_free_reply(reply);
return 0;
}
/**
@@ -606,36 +618,34 @@ static int audit_send_reply_thread(void
* @payload: payload data
* @size: payload size
*
- * Allocates an skb, builds the netlink message, and sends it to the port id.
- * No failure notifications.
+ * Allocates a skb, builds the netlink message, and sends it to the port id.
*/
static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
int multi, const void *payload, int size)
{
u32 portid = NETLINK_CB(request_skb).portid;
- struct net *net = sock_net(NETLINK_CB(request_skb).sk);
- struct sk_buff *skb;
struct task_struct *tsk;
- struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
- GFP_KERNEL);
+ struct audit_reply *reply;
+ reply = kzalloc(sizeof(*reply), GFP_KERNEL);
if (!reply)
return;
- skb = audit_make_reply(portid, seq, type, done, multi, payload, size);
- if (!skb)
- goto out;
+ reply->skb = audit_make_reply(portid, seq, type, done, multi, payload, size);
+ if (!reply->skb)
+ goto err;
- reply->net = get_net(net);
+ reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
reply->portid = portid;
- reply->skb = skb;
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
- if (!IS_ERR(tsk))
- return;
- kfree_skb(skb);
-out:
- kfree(reply);
+ if (IS_ERR(tsk))
+ goto err;
+
+ return;
+
+err:
+ audit_free_reply(reply);
}
/*
Powered by blists - more mailing lists