mirror of
https://github.com/torvalds/linux.git
synced 2026-10-09 20:09:02 +02:00
tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow
Commit48a5fe3877("tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG") rejected duplicate/stale ACKs in tipc_group_proto_rcv() by returning early when less_eq(acked, m->bc_acked). However, that check remains incomplete in two ways: 1. When grp->bc_ackers is zero (e.g. on a quiet group, when replicast ACKs were not requested, or after all expected members have already acknowledged), an unexpected GRP_ACK_MSG with acked > m->bc_acked passes less_eq() and unconditionally decrements grp->bc_ackers. Because bc_ackers is a u16, this wraps to 65535, causing tipc_group_bc_cong() to permanently report congestion and blocking all future group broadcasts on the socket. 2. During an active broadcast round (grp->bc_ackers > 0), the sender transmits packet S and advances grp->bc_snd_nxt to S + 1. Receivers increment their expected counter to S + 1 upon consuming packet S, so the only valid ACK value for the current round is strictly acked == grp->bc_snd_nxt. However, tipc_group_update_bc_members() initializes each member's m->bc_acked to prev = grp->bc_snd_nxt - 1 (S - 1 before increment). This leaves a 2-sequence gap (S - 1 to S + 1) in sequence space. An incoming ACK is therefore neither rejected as duplicate nor prevented from decrementing grp->bc_ackers if an unexpected or stale value (such as S) is received. A member sending acked = S followed by acked = S + 1 could decrement grp->bc_ackers twice in the same round, prematurely clearing bc_ackers or underflowing it. Fix this by: - Dropping GRP_ACK_MSG immediately if grp->bc_ackers is zero. - Requiring acked == grp->bc_snd_nxt and rejecting duplicates where m->bc_acked == acked. Because replicast broadcast rounds are strictly sequential, only grp->bc_snd_nxt can be acknowledged, and each member can acknowledge at most once per round. Note that a related pre-existing issue in tipc_group_delete_member() (where grp->bc_ackers decrementing to zero upon member departure does not restore *grp->open or trigger a socket wakeup) will be addressed in a separate patch. Fixes:48a5fe3877("tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG") Fixes:2f487712b8("tipc: guarantee that group broadcast doesn't bypass group unicast") Reported-by: James Burton <jamesburton@meta.com> Cc: stable@vger.kernel.org Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260913044233.193927-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
46bc52d135
commit
99cc2a62e0
|
|
@ -797,10 +797,10 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
|
|||
tipc_group_open(m, usr_wakeup);
|
||||
return;
|
||||
case GRP_ACK_MSG:
|
||||
if (!m)
|
||||
if (!m || !grp->bc_ackers)
|
||||
return;
|
||||
acked = msg_grp_bc_acked(hdr);
|
||||
if (less_eq(acked, m->bc_acked))
|
||||
if (acked != grp->bc_snd_nxt || m->bc_acked == acked)
|
||||
return;
|
||||
m->bc_acked = acked;
|
||||
if (--grp->bc_ackers)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user