Skip to content

Commit 7e6b27a

Browse files
jrfastabborkmann
authored andcommitted
bpf, sockmap: Fix potential memory leak on unlikely error case
If skb_linearize is needed and fails we could leak a msg on the error handling. To fix ensure we kfree the msg block before returning error. Found during code review. Fixes: 4363023 ("bpf, sockmap: Avoid failures from skb_to_sgvec when skb has frag_list") Signed-off-by: John Fastabend <john.fastabend@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: Cong Wang <cong.wang@bytedance.com> Link: https://lore.kernel.org/bpf/20210712195546.423990-2-john.fastabend@gmail.com
1 parent 9109165 commit 7e6b27a

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

net/core/skmsg.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -508,10 +508,8 @@ static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
508508
if (skb_linearize(skb))
509509
return -EAGAIN;
510510
num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len);
511-
if (unlikely(num_sge < 0)) {
512-
kfree(msg);
511+
if (unlikely(num_sge < 0))
513512
return num_sge;
514-
}
515513

516514
copied = skb->len;
517515
msg->sg.start = 0;
@@ -530,6 +528,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb)
530528
{
531529
struct sock *sk = psock->sk;
532530
struct sk_msg *msg;
531+
int err;
533532

534533
/* If we are receiving on the same sock skb->sk is already assigned,
535534
* skip memory accounting and owner transition seeing it already set
@@ -548,7 +547,10 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb)
548547
* into user buffers.
549548
*/
550549
skb_set_owner_r(skb, sk);
551-
return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
550+
err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
551+
if (err < 0)
552+
kfree(msg);
553+
return err;
552554
}
553555

554556
/* Puts an skb on the ingress queue of the socket already assigned to the
@@ -559,12 +561,16 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb
559561
{
560562
struct sk_msg *msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_ATOMIC);
561563
struct sock *sk = psock->sk;
564+
int err;
562565

563566
if (unlikely(!msg))
564567
return -EAGAIN;
565568
sk_msg_init(msg);
566569
skb_set_owner_r(skb, sk);
567-
return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
570+
err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
571+
if (err < 0)
572+
kfree(msg);
573+
return err;
568574
}
569575

570576
static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb,

0 commit comments

Comments
 (0)