mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 03:24:19 +02:00
xfrm: ah: use skb_to_full_sk in async output callbacks
When AH output is offloaded to an asynchronous crypto provider (hardware accelerators such as AMD CCP, or a forced-async software shim used for testing), the digest completion fires ah_output_done() / ah6_output_done() on a workqueue. The egress skb at that point may have been originated by a TCP listener sending a SYN-ACK, which sets skb->sk to a request_sock via skb_set_owner_edemux(); it may also have been originated by an inet_timewait_sock retransmit. Neither is a full struct sock, and passing the raw skb->sk to xfrm_output_resume() then forwards a non-full socket through the rest of the xfrm output chain. xfrm_output_resume() and its downstream consumers expect a full sk where they dereference at all. The natural egress path through ah_output_done() does not crash today because the consumers that read past sock_common are either gated by sk_fullsock() or short-circuit on flags that are clear on a fresh request_sock; an exhaustive walk of the 50 most plausible consumers under sch_fq, dev_queue_xmit, netfilter, tc-egress and cgroup-egress BPF found no current unguarded deref. The bug is still a real type confusion that future consumer changes could turn into a memory-corruption primitive. This is the same bug class fixed for ESP in commit1620c88887("xfrm: Fix the usage of skb->sk"). Apply the analogous fix to AH: convert skb->sk to a full socket pointer (or NULL) via skb_to_full_sk() before handing it to xfrm_output_resume(). The same async AH callbacks were touched recently for an independent ESN-related ICV layout bug in commitec54093e6a("xfrm: ah: account for ESN high bits in async callbacks"); the sk type-confusion addressed here is orthogonal. This patch is part of an ongoing audit of the AH callback paths; an ah_output ihl-validation hardening series is also currently under review on netdev. Reproduced under UML + KASAN + lockdep with a forced-async hmac(sha1) shim that registers at priority 9999 and wraps the sync in-tree hmac-sha1-lib. With the shim loaded, ah_output_done runs on every SYN-ACK egress through a transport-mode AH SA and skb->sk arrives as a request_sock (TCP_NEW_SYN_RECV); after this patch, xfrm_output_resume() receives the listener (the result of sk_to_full_sk()) and consumer derefs land on full-sock fields as intended. Fixes:9ab1265d52("xfrm: Use actual socket sk instead of skb socket for xfrm_output_resume") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
742b04d055
commit
79d8be2623
|
|
@ -143,7 +143,7 @@ static void ah_output_done(void *data, int err)
|
|||
}
|
||||
|
||||
kfree(AH_SKB_CB(skb)->tmp);
|
||||
xfrm_output_resume(skb->sk, skb, err);
|
||||
xfrm_output_resume(skb_to_full_sk(skb), skb, err);
|
||||
}
|
||||
|
||||
static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ static void ah6_output_done(void *data, int err)
|
|||
ah6_restore_hdrs(top_iph, iph_ext, extlen);
|
||||
|
||||
kfree(AH_SKB_CB(skb)->tmp);
|
||||
xfrm_output_resume(skb->sk, skb, err);
|
||||
xfrm_output_resume(skb_to_full_sk(skb), skb, err);
|
||||
}
|
||||
|
||||
static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user