diff mbox series

[bpf,v3,1/2] bpf, sockmap: fix potential memory leak on unlikely error case

Message ID 20210706163150.112591-2-john.fastabend@gmail.com
State New
Headers show
Series potential sockmap memleak and proc stats fix | expand

Commit Message

John Fastabend July 6, 2021, 4:31 p.m. UTC
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: 4363023d2668e ("bpf, sockmap: Avoid failures from skb_to_sgvec when skb has frag_list")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 net/core/skmsg.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

Comments

Cong Wang July 8, 2021, 7:38 p.m. UTC | #1
On Tue, Jul 6, 2021 at 9:31 AM John Fastabend <john.fastabend@gmail.com> wrote:
>

> 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.


sk_psock_skb_ingress_self() also needs the same fix, right?
Other than this, it looks good to me.

Thanks.
John Fastabend July 8, 2021, 8:39 p.m. UTC | #2
Cong Wang wrote:
> On Tue, Jul 6, 2021 at 9:31 AM John Fastabend <john.fastabend@gmail.com> wrote:

> >

> > 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.

> 

> sk_psock_skb_ingress_self() also needs the same fix, right?


Yep.

> Other than this, it looks good to me.


I'll do another spin to get the other one as well. Mind as well
fix both cases at once.

> 

> Thanks.
diff mbox series

Patch

diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 9b6160a191f8..1a9059e5b3b3 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -508,10 +508,8 @@  static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
 	if (skb_linearize(skb))
 		return -EAGAIN;
 	num_sge = skb_to_sgvec(skb, msg->sg.data, 0, skb->len);
-	if (unlikely(num_sge < 0)) {
-		kfree(msg);
+	if (unlikely(num_sge < 0))
 		return num_sge;
-	}
 
 	copied = skb->len;
 	msg->sg.start = 0;
@@ -530,6 +528,7 @@  static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb)
 {
 	struct sock *sk = psock->sk;
 	struct sk_msg *msg;
+	int err;
 
 	/* If we are receiving on the same sock skb->sk is already assigned,
 	 * 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)
 	 * into user buffers.
 	 */
 	skb_set_owner_r(skb, sk);
-	return sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
+	err = sk_psock_skb_ingress_enqueue(skb, psock, sk, msg);
+	if (err < 0)
+		kfree(msg);
+	return err;
 }
 
 /* Puts an skb on the ingress queue of the socket already assigned to the