diff options
author | Paul Moore <paul@paul-moore.com> | 2020-04-21 09:10:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-06-22 09:05:13 +0200 |
commit | 4fe5dcafc74d9729e5f11f2d418c394eadbe0035 (patch) | |
tree | e573f443c6ef6ba1daf9d1d8e26a58716017ea57 /kernel/auditfilter.c | |
parent | e366d4001a16d5f0b0b82ba59ef8bc5de18bdd55 (diff) | |
download | linux-stable-4fe5dcafc74d9729e5f11f2d418c394eadbe0035.tar.gz linux-stable-4fe5dcafc74d9729e5f11f2d418c394eadbe0035.tar.bz2 linux-stable-4fe5dcafc74d9729e5f11f2d418c394eadbe0035.zip |
audit: fix a net reference leak in audit_list_rules_send()
[ Upstream commit 3054d06719079388a543de6adb812638675ad8f5 ]
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 <rgb@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'kernel/auditfilter.c')
-rw-r--r-- | kernel/auditfilter.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 1c8a48abda80..b2cc63ca0068 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -1157,11 +1157,8 @@ int audit_rule_change(int type, int seq, void *data, size_t datasz) */ 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 @@ -1169,25 +1166,26 @@ int audit_list_rules_send(struct sk_buff *request_skb, int seq) * 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->portid = portid; + dest->net = get_net(sock_net(NETLINK_CB(request_skb).sk)); + dest->portid = NETLINK_CB(request_skb).portid; skb_queue_head_init(&dest->q); mutex_lock(&audit_filter_mutex); audit_list_rules(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) |