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.7 099/376] audit: fix a net reference leak in audit_send_reply()
    Date
    From: Paul Moore <paul@paul-moore.com>

    [ Upstream commit a48b284b403a4a073d8beb72d2bb33e54df67fb6 ]

    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 <rgb@redhat.com>
    Signed-off-by: Paul Moore <paul@paul-moore.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    kernel/audit.c | 50 +++++++++++++++++++++++++++++---------------------
    1 file changed, 29 insertions(+), 21 deletions(-)

    diff --git a/kernel/audit.c b/kernel/audit.c
    index 87f31bf1f0a0..033b14712340 100644
    --- a/kernel/audit.c
    +++ b/kernel/audit.c
    @@ -924,19 +924,30 @@ 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;
    - struct sock *sk = audit_get_sk(reply->net);

    audit_ctl_lock();
    audit_ctl_unlock();

    /* Ignore failure. It'll only happen if the sender goes away,
    because our timeout is set to infinite. */
    - netlink_unicast(sk, reply->skb, reply->portid, 0);
    - put_net(reply->net);
    - kfree(reply);
    + netlink_unicast(audit_get_sk(reply->net), reply->skb, reply->portid, 0);
    + reply->skb = NULL;
    + audit_free_reply(reply);
    return 0;
    }

    @@ -950,35 +961,32 @@ static int audit_send_reply_thread(void *arg)
    * @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)
    {
    - 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(seq, type, done, multi, payload, size);
    - if (!skb)
    - goto out;
    -
    - reply->net = get_net(net);
    + reply->skb = audit_make_reply(seq, type, done, multi, payload, size);
    + if (!reply->skb)
    + goto err;
    + reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
    reply->portid = NETLINK_CB(request_skb).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);
    }

    /*
    --
    2.25.1


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