mirror of
https://github.com/torvalds/linux.git
synced 2026-10-04 02:09:03 +02:00
tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack()
When tcp_send_synack() replaces the cloned SYN skb at the head of the
retransmit queue with a copy, it frees the original with
tcp_rtx_queue_unlink_and_free() and only repairs tp->highest_sack.
tp->retransmit_skb_hint keeps pointing at the freed
skbuff_fclone_cache object.
The dangling hint is read in tcp_verify_retransmit_hint() and used as
the root of the rbtree walk in tcp_xmit_retransmit_queue(). An
unprivileged TFO client (sendmsg(MSG_FASTOPEN)) can arm the hint with
an attacker-supplied ICMP fragmentation-needed message, after which a
simultaneous open frees the armed SYN skb:
BUG: KASAN: slab-use-after-free in tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
Read of size 4 at addr ffff88800604d928 by task swapper/1/0
Call Trace:
tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
tcp_simple_retransmit (net/ipv4/tcp_input.c:3158)
tcp_v4_err (net/ipv4/tcp_ipv4.c:587)
Sync the hint to the copy.
Fixes: c31b70c996 ("tcp: Add logic to check for SYN w/ data in tcp_simple_retransmit")
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Tested-by: Weiming Shi <shiweiming@moonshot.ai>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/8a9dff4063a2745653b7e88ceb745d75efa16e68.1790224474.git.yilinzhang@moonshot.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
26cc0e69cc
commit
fe99bbeee5
|
|
@ -3886,6 +3886,7 @@ void tcp_send_active_reset(struct sock *sk, enum sk_rst_reason reason)
|
|||
*/
|
||||
int tcp_send_synack(struct sock *sk)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = tcp_rtx_queue_head(sk);
|
||||
|
|
@ -3903,6 +3904,8 @@ int tcp_send_synack(struct sock *sk)
|
|||
if (!nskb)
|
||||
return -ENOMEM;
|
||||
INIT_LIST_HEAD(&nskb->tcp_tsorted_anchor);
|
||||
if (skb == tp->retransmit_skb_hint)
|
||||
tp->retransmit_skb_hint = nskb;
|
||||
tcp_highest_sack_replace(sk, skb, nskb);
|
||||
tcp_rtx_queue_unlink_and_free(skb, sk);
|
||||
__skb_header_release(nskb);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user