Commit 9e9c3dc3 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Greg Kroah-Hartman

net: netem: fix error path for corrupted GSO frames

[ Upstream commit a7fa12d1 ]

To corrupt a GSO frame we first perform segmentation.  We then
proceed using the first segment instead of the full GSO skb and
requeue the rest of the segments as separate packets.

If there are any issues with processing the first segment we
still want to process the rest, therefore we jump to the
finish_segs label.

Commit 177b8007 ("net: netem: fix backlog accounting for
corrupted GSO frames") started using the pointer to the first
segment in the "rest of segments processing", but as mentioned
above the first segment may had already been freed at this point.

Backlog corrections for parent qdiscs have to be adjusted.

Fixes: 177b8007 ("net: netem: fix backlog accounting for corrupted GSO frames")
Reported-by: default avatarkbuild test robot <lkp@intel.com>
Reported-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Reported-by: default avatarBen Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 963938f5
......@@ -509,6 +509,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (skb->ip_summed == CHECKSUM_PARTIAL &&
skb_checksum_help(skb)) {
qdisc_drop(skb, sch, to_free);
skb = NULL;
goto finish_segs;
}
......@@ -584,9 +585,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
finish_segs:
if (segs) {
unsigned int len, last_len;
int nb = 0;
int nb;
len = skb->len;
len = skb ? skb->len : 0;
nb = skb ? 1 : 0;
while (segs) {
skb2 = segs->next;
......@@ -603,7 +605,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
segs = skb2;
}
qdisc_tree_reduce_backlog(sch, -nb, prev_len - len);
/* Parent qdiscs accounted for 1 skb of size @prev_len */
qdisc_tree_reduce_backlog(sch, -(nb - 1), -(len - prev_len));
}
return NET_XMIT_SUCCESS;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment