[PATCH net] rxrpc: Fix the ACK parser to extract the SACK table for parsing

Jeffrey E Altman jaltman at auristor.com
Wed May 20 19:42:20 PDT 2026


On 5/20/2026 10:19 PM, Jakub Kicinski wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> rxrpc: Fix the ACK parser to extract the SACK table for parsing
>
> This commit fixes modification of the received skbuff and incorrect access
> of the buffer in fragmented UDP packets during SACK table parsing. It copies
> out the contents of the SACK table into a flat stack buffer instead of
> relying on skb_condense().
>
> Link: https://lore.kernel.org/r/20260513180907.2061972-1-michael.bommarito@gmail.com
>
>> diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
>> index 24aceb183c2c3..0c15ebf19eae9 100644
>> --- a/net/rxrpc/input.c
>> +++ b/net/rxrpc/input.c
>> @@ -963,21 +963,34 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call,
>>   	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
>>   	struct rxrpc_txqueue *tq = call->tx_queue;
>>   	unsigned long extracted = ~0UL;
>> -	unsigned int nr = 0;
>> +	unsigned int nr = 0, nsack;
>>   	rxrpc_seq_t seq = call->acks_hard_ack + 1;
>>   	rxrpc_seq_t lowest_nak = seq + sp->ack.nr_acks;
>> -	u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket);
>> +	u8 sack[256] __aligned(sizeof(unsigned long));
>> +	u8 *acks = sack;
> [ ... ]
>
>>   	for (unsigned int i = 0; i < sp->ack.nr_acks; i++) {
>>   		/* Decant ACKs until we hit a txqueue boundary. */
>>   		shiftr_adv_rotr(acks, extracted);
>>   		if (i == 256) {
>> -			acks -= i;
>> +			acks = sack;
>>   			i = 0;
>>   		}
> Can this lead to an out-of-bounds access and an infinite loop if
> sp->ack.nr_acks is greater than 256?
>
> If a received packet has sp->ack.nr_acks > 256, on the 257th iteration
> (where i == 256), the shiftr_adv_rotr(acks, extracted) macro will execute
> before the wrap-around check resets the acks pointer.
>
> Since the acks pointer has been incremented 256 times by previous iterations,
> wouldn't it point to sack + 256 at this point, causing an out-of-bounds read
> and write on the sack[] array?
>
> Furthermore, resetting i to 0 inside the loop means the loop's i++
> operation will set it to 1 for the next iteration. Because the counter is
> reset without breaking out of the loop, will this ever terminate if
> sp->ack.nr_acks > 256, or will it cycle infinitely and eventually cause a NULL
> pointer dereference when tq->next runs out of transmit queues?

Due to the lack of support for Extended SACK within the current rxrpc 
implementation the value of ack.nr_acks cannot exceed 255. The value of 
ack.nr_acks is assigned in rxrpc_extract_header() from the struct 
rxrpc_ackpacket.nAcks field which is an unsigned 8-bit value whose 
maximum is 255.

When support for Extended SACK tables is added the processing in 
rxrpc_input_soft_acks() must be updated.

Jeffrey Altman






More information about the linux-afs mailing list