Skip to content

Commit

Permalink
net: drop skb on failure in ip_check_defrag()
Browse files Browse the repository at this point in the history
[ Upstream commit 7de414a ]

Most callers of pskb_trim_rcsum() simply drop the skb when
it fails, however, ip_check_defrag() still continues to pass
the skb up to stack. This is suspicious.

In ip_check_defrag(), after we learn the skb is an IP fragment,
passing the skb to callers makes no sense, because callers expect
fragments are defrag'ed on success. So, dropping the skb when we
can't defrag it is reasonable.

Note, prior to commit 88078d9, this is not a big problem as
checksum will be fixed up anyway. After it, the checksum is not
correct on failure.

Found this during code review.

Fixes: 88078d9 ("net: pskb_trim_rcsum() and CHECKSUM_COMPLETE are friends")
Cc: Eric Dumazet <[email protected]>
Signed-off-by: Cong Wang <[email protected]>
Reviewed-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
congwang authored and gregkh committed Nov 10, 2018
1 parent 55eb3e7 commit d64a820
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions net/ipv4/ip_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -684,10 +684,14 @@ struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
if (ip_is_fragment(&iph)) {
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb) {
if (!pskb_may_pull(skb, netoff + iph.ihl * 4))
return skb;
if (pskb_trim_rcsum(skb, netoff + len))
return skb;
if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) {
kfree_skb(skb);
return NULL;
}
if (pskb_trim_rcsum(skb, netoff + len)) {
kfree_skb(skb);
return NULL;
}
memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
if (ip_defrag(skb, user))
return NULL;
Expand Down

0 comments on commit d64a820

Please sign in to comment.