mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
xfrm: fix stale skb->prev after async crypto steals a GSO segment
skb_gso_segment() leaves the segment list head with ->prev pointing at
the last segment, an invariant validate_xmit_skb_list() relies on when
it sets its tail pointer (tail = skb->prev).
When validate_xmit_xfrm() walks a GSO list and some segments are stolen
by async crypto (->xmit() returns -EINPROGRESS), those segments are
unlinked from the list but the head ->prev is never updated. If the
last segment is the one stolen, the returned head still has ->prev
pointing at it, even though it is now owned by the crypto engine and may
be freed. validate_xmit_skb_list() later does tail->next = skb, writing
through that stale pointer -- a use-after-free.
Repoint skb->prev at the last retained segment before returning.
Fixes: f53c723902 ("net: Add asynchronous callbacks for xfrm on layer 2.")
Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
6860b467f5
commit
3f4c3919ba
|
|
@ -224,6 +224,14 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
|
|||
pskb = skb2;
|
||||
}
|
||||
|
||||
/* skb_gso_segment() set skb->prev to the last segment, but async
|
||||
* crypto may have stolen it above without updating ->prev. Repoint
|
||||
* it at the last retained segment so validate_xmit_skb_list() does
|
||||
* not chain onto a segment now owned by the crypto engine.
|
||||
*/
|
||||
if (skb)
|
||||
skb->prev = pskb;
|
||||
|
||||
return skb ? skb : ERR_PTR(-EINPROGRESS);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user