lkml.org 
[lkml]   [2020]   [Jun]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 073/261] audit: fix a net reference leak in audit_list_rules_send()
    Date
    From: Paul Moore <paul@paul-moore.com>

    [ 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>
    ---
    kernel/audit.c | 2 +-
    kernel/audit.h | 2 +-
    kernel/auditfilter.c | 16 +++++++---------
    3 files changed, 9 insertions(+), 11 deletions(-)

    diff --git a/kernel/audit.c b/kernel/audit.c
    index a4eeece2eecd..05ae208ad442 100644
    --- a/kernel/audit.c
    +++ b/kernel/audit.c
    @@ -879,7 +879,7 @@ main_queue:
    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;
    diff --git a/kernel/audit.h b/kernel/audit.h
    index 6fb7160412d4..ddc22878433d 100644
    --- a/kernel/audit.h
    +++ b/kernel/audit.h
    @@ -229,7 +229,7 @@ struct audit_netlink_list {
    struct sk_buff_head q;
    };

    -int audit_send_list(void *_dest);
    +int audit_send_list_thread(void *_dest);

    extern int selinux_audit_rule_update(void);

    diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
    index 026e34da4ace..a10e2997aa6c 100644
    --- a/kernel/auditfilter.c
    +++ b/kernel/auditfilter.c
    @@ -1161,11 +1161,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
    @@ -1173,25 +1170,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)
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-06-19 18:09    [W:4.085 / U:0.304 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site