sctp_sm_pull_sack() derives its pull length from the num_gap_ack_blocks
and num_dup_tsns fields in the SACK body, but validates it against
chunk->skb->len (the remaining packet data) rather than the SACK chunk's
declared length. A malformed SACK with an inflated num_dup_tsns can pass
this check when subsequent chunks pad the skb, advancing skb->data past
the SACK boundary into later chunks.
This misaligns the skb cursor for subsequent chunk processing. When an
AUTH chunk follows, sctp_sf_authenticate() reads and compares the HMAC
digest from the wrong skb offset while sctp_auth_calculate_hmac() writes
the computed HMAC through the correct chunk_hdr pointer, bypassing the
authentication check.
Fix by validating the computed pull length against the chunk's declared
body length instead of the total remaining skb data.
Fixes: 730fc3d05cd4 ("[SCTP]: Implete SCTP-AUTH parameter processing")
Reported-by: on Sim <redacted>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/sm_statefuns.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b2f609f177fb..44b1770d43c1 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6368,7 +6368,8 @@ static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk)
num_dup_tsns = ntohs(sack->num_dup_tsns);
len = sizeof(struct sctp_sackhdr);
len += (num_blocks + num_dup_tsns) * sizeof(__u32);
- if (len > chunk->skb->len)
+ if (len > ntohs(chunk->chunk_hdr->length) -
+ sizeof(struct sctp_chunkhdr))
return NULL;
skb_pull(chunk->skb, len);
--
2.47.1