Skip to content

Commit a48b284

Browse files
committed
audit: fix a net reference leak in audit_send_reply()
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: [email protected] Reviewed-by: Richard Guy Briggs <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 8f3d9f3 commit a48b284

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

kernel/audit.c

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -924,19 +924,30 @@ struct sk_buff *audit_make_reply(int seq, int type, int done,
924924
return NULL;
925925
}
926926

927+
static void audit_free_reply(struct audit_reply *reply)
928+
{
929+
if (!reply)
930+
return;
931+
932+
if (reply->skb)
933+
kfree_skb(reply->skb);
934+
if (reply->net)
935+
put_net(reply->net);
936+
kfree(reply);
937+
}
938+
927939
static int audit_send_reply_thread(void *arg)
928940
{
929941
struct audit_reply *reply = (struct audit_reply *)arg;
930-
struct sock *sk = audit_get_sk(reply->net);
931942

932943
audit_ctl_lock();
933944
audit_ctl_unlock();
934945

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

@@ -950,35 +961,32 @@ static int audit_send_reply_thread(void *arg)
950961
* @payload: payload data
951962
* @size: payload size
952963
*
953-
* Allocates an skb, builds the netlink message, and sends it to the port id.
954-
* No failure notifications.
964+
* Allocates a skb, builds the netlink message, and sends it to the port id.
955965
*/
956966
static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int done,
957967
int multi, const void *payload, int size)
958968
{
959-
struct net *net = sock_net(NETLINK_CB(request_skb).sk);
960-
struct sk_buff *skb;
961969
struct task_struct *tsk;
962-
struct audit_reply *reply = kmalloc(sizeof(struct audit_reply),
963-
GFP_KERNEL);
970+
struct audit_reply *reply;
964971

972+
reply = kzalloc(sizeof(*reply), GFP_KERNEL);
965973
if (!reply)
966974
return;
967975

968-
skb = audit_make_reply(seq, type, done, multi, payload, size);
969-
if (!skb)
970-
goto out;
971-
972-
reply->net = get_net(net);
976+
reply->skb = audit_make_reply(seq, type, done, multi, payload, size);
977+
if (!reply->skb)
978+
goto err;
979+
reply->net = get_net(sock_net(NETLINK_CB(request_skb).sk));
973980
reply->portid = NETLINK_CB(request_skb).portid;
974-
reply->skb = skb;
975981

976982
tsk = kthread_run(audit_send_reply_thread, reply, "audit_send_reply");
977-
if (!IS_ERR(tsk))
978-
return;
979-
kfree_skb(skb);
980-
out:
981-
kfree(reply);
983+
if (IS_ERR(tsk))
984+
goto err;
985+
986+
return;
987+
988+
err:
989+
audit_free_reply(reply);
982990
}
983991

984992
/*

0 commit comments

Comments
 (0)