Blob Blame History Raw
From: Julian Wiedmann <jwi@linux.ibm.com>
Subject: net/af_iucv: drop inbound packets with invalid flags
Patch-mainline: v4.19-rc4
Git-commit: 222440996d6daf635bed6cb35041be22ede3e8a0
References: bnc#1113501, LTC#172679

Description:  net/af_iucv: fix skb leaks for HiperTransport
Symptom:      Memory leaks and/or double-freed network packets.
Problem:      Inbound packets may have any combination of flag bits set in
              their iucv header. Current code only handles certain
              combinations, and ignores (ie. leaks) all packets with other
              flags.
              On Transmit, current code is inconsistent about whether the error
              paths need to free the skb. Depending on which error path is
              taken, it may either get freed twice, or leak.
Solution:     On receive, drop any skb with an unexpected combination of iucv
              Header flags.
              On transmit, be consistent in all error paths about free'ing the
              skb.
Reproduction: -

Upstream-Description:

              net/af_iucv: drop inbound packets with invalid flags

              Inbound packets may have any combination of flag bits set in their iucv
              header. If we don't know how to handle a specific combination, drop the
              skb instead of leaking it.

              To clarify what error is returned in this case, replace the hard-coded
              0 with the corresponding macro.

              Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
              Signed-off-by: David S. Miller <davem@davemloft.net>


Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 net/iucv/af_iucv.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -2159,8 +2159,8 @@ static int afiucv_hs_rcv(struct sk_buff
 	struct sock *sk;
 	struct iucv_sock *iucv;
 	struct af_iucv_trans_hdr *trans_hdr;
+	int err = NET_RX_SUCCESS;
 	char nullstring[8];
-	int err = 0;
 
 	if (skb->len < (ETH_HLEN + sizeof(struct af_iucv_trans_hdr))) {
 		WARN_ONCE(1, "AF_IUCV too short skb, len=%d, min=%d",
@@ -2258,7 +2258,7 @@ static int afiucv_hs_rcv(struct sk_buff
 		err = afiucv_hs_callback_rx(sk, skb);
 		break;
 	default:
-		;
+		kfree_skb(skb);
 	}
 
 	return err;