From 27c801c8da0222bd26a52c4d173f382103231f93 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Apr 2021 10:45:48 +0200 Subject: [PATCH] 4.9-stable patches added patches: audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch audit-fix-a-net-reference-leak-in-audit_send_reply.patch --- ...erence-leak-in-audit_list_rules_send.patch | 94 +++++++++++++++ ...t-reference-leak-in-audit_send_reply.patch | 107 ++++++++++++++++++ queue-4.9/series | 2 + 3 files changed, 203 insertions(+) create mode 100644 queue-4.9/audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch create mode 100644 queue-4.9/audit-fix-a-net-reference-leak-in-audit_send_reply.patch diff --git a/queue-4.9/audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch b/queue-4.9/audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch new file mode 100644 index 00000000000..9f883a5abad --- /dev/null +++ b/queue-4.9/audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch @@ -0,0 +1,94 @@ +From 3054d06719079388a543de6adb812638675ad8f5 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 21 Apr 2020 09:10:56 -0400 +Subject: audit: fix a net reference leak in audit_list_rules_send() + +From: Paul Moore + +commit 3054d06719079388a543de6adb812638675ad8f5 upstream. + +If audit_list_rules_send() fails when trying to create a new thread +to send the rules it also fails to cleanup properly, leaking a +reference to a net structure. This patch fixes the error patch and +renames audit_send_list() to audit_send_list_thread() to better +match its cousin, audit_send_reply_thread(). + +Reported-by: teroincn@gmail.com +Reviewed-by: Richard Guy Briggs +Signed-off-by: Paul Moore +Cc: # 4.9.x +Signed-off-by: Wen Yang +Signed-off-by: Greg Kroah-Hartman +--- + kernel/audit.c | 2 +- + kernel/audit.h | 2 +- + kernel/auditfilter.c | 13 ++++++------- + 3 files changed, 8 insertions(+), 9 deletions(-) + +--- a/kernel/audit.c ++++ b/kernel/audit.c +@@ -535,7 +535,7 @@ static int kauditd_thread(void *dummy) + return 0; + } + +-int audit_send_list(void *_dest) ++int audit_send_list_thread(void *_dest) + { + struct audit_netlink_list *dest = _dest; + struct sk_buff *skb; +--- a/kernel/audit.h ++++ b/kernel/audit.h +@@ -245,7 +245,7 @@ struct audit_netlink_list { + struct sk_buff_head q; + }; + +-int audit_send_list(void *); ++int audit_send_list_thread(void *); + + struct audit_net { + struct sock *nlsk; +--- a/kernel/auditfilter.c ++++ b/kernel/auditfilter.c +@@ -1139,10 +1139,8 @@ int audit_rule_change(int type, __u32 po + int audit_list_rules_send(struct sk_buff *request_skb, int seq) + { + u32 portid = NETLINK_CB(request_skb).portid; +- struct net *net = sock_net(NETLINK_CB(request_skb).sk); + struct task_struct *tsk; + struct audit_netlink_list *dest; +- int err = 0; + + /* We can't just spew out the rules here because we might fill + * the available socket buffer space and deadlock waiting for +@@ -1150,10 +1148,10 @@ int audit_list_rules_send(struct sk_buff + * happen if we're actually running in the context of auditctl + * trying to _send_ the stuff */ + +- dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); ++ dest = kmalloc(sizeof(*dest), GFP_KERNEL); + if (!dest) + return -ENOMEM; +- dest->net = get_net(net); ++ dest->net = get_net(sock_net(NETLINK_CB(request_skb).sk)); + dest->portid = portid; + skb_queue_head_init(&dest->q); + +@@ -1161,14 +1159,15 @@ int audit_list_rules_send(struct sk_buff + audit_list_rules(portid, seq, &dest->q); + mutex_unlock(&audit_filter_mutex); + +- tsk = kthread_run(audit_send_list, dest, "audit_send_list"); ++ tsk = kthread_run(audit_send_list_thread, dest, "audit_send_list"); + if (IS_ERR(tsk)) { + skb_queue_purge(&dest->q); ++ put_net(dest->net); + kfree(dest); +- err = PTR_ERR(tsk); ++ return PTR_ERR(tsk); + } + +- return err; ++ return 0; + } + + int audit_comparator(u32 left, u32 op, u32 right) diff --git a/queue-4.9/audit-fix-a-net-reference-leak-in-audit_send_reply.patch b/queue-4.9/audit-fix-a-net-reference-leak-in-audit_send_reply.patch new file mode 100644 index 00000000000..ff1fd931f3e --- /dev/null +++ b/queue-4.9/audit-fix-a-net-reference-leak-in-audit_send_reply.patch @@ -0,0 +1,107 @@ +From a48b284b403a4a073d8beb72d2bb33e54df67fb6 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Mon, 20 Apr 2020 10:09:29 -0400 +Subject: audit: fix a net reference leak in audit_send_reply() + +From: Paul Moore + +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@gmail.com +Reviewed-by: Richard Guy Briggs +Signed-off-by: Paul Moore +Cc: # 4.9.x +Signed-off-by: Wen Yang +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + + /* diff --git a/queue-4.9/series b/queue-4.9/series index 8ffe9aff9be..a28f777ba15 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -31,3 +31,5 @@ usb-cdc-acm-downgrade-message-to-debug.patch usb-cdc-acm-fix-use-after-free-after-probe-failure.patch staging-rtl8192e-fix-incorrect-source-in-memcpy.patch staging-rtl8192e-change-state-information-from-u16-to-u8.patch +audit-fix-a-net-reference-leak-in-audit_send_reply.patch +audit-fix-a-net-reference-leak-in-audit_list_rules_send.patch -- 2.47.3