Re: [PATCH net 2/2] sctp: add INIT verification after cookie unpacking

Xin Long <[email protected]> Thu, 18 Jun 2026 18:08:52 -0400
Newsgroups org.kernel.vger.linux-sctp,org.kernel.vger.netdev
Message-ID <CADvbK_c_+tm=sX_NH-JoppGaqrzt-jAb43NKs-2VXaohb9z1Vg@mail.gmail.com>
On Wed, Jun 17, 2026 at 6:40 AM Simon Horman <[email protected]> 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.
> Full review at: https://netdev-ai.bots.linux.dev/sashiko/
> ---
> Now I have enough verified information to produce the report.
>
> commit 9d74027bfd0cb22a103cca034883f0fcb4e2535a
> Author: Xin Long <[email protected]>
>
> sctp: add INIT verification after cookie unpacking
>
> This commit adds sctp_verify_init() checks after cookie unpacking in
> the COOKIE-ECHO processing paths when cookie_auth_enable is disabled.
> It also changes the bounds comparison inside sctp_verify_init() from
> chunk->chunk_end to peer_init + ntohs(peer_init->chunk_hdr.length).
>
> > diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
> > index 41958b8e59fd..21b9eb1c02e9 100644
> > --- a/net/sctp/sm_make_chunk.c
> > +++ b/net/sctp/sm_make_chunk.c
> > @@ -2298,7 +2298,7 @@ int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
> >        * VIOLATION error.  We build the ERROR chunk here and let the normal
> >        * error handling code build and send the packet.
> >        */
> > -     if (param.v != (void *)chunk->chunk_end)
> > +     if (param.v != (void *)peer_init + ntohs(peer_init->chunk_hdr.length))
> >               return sctp_process_inv_paramlength(asoc, param.p, chunk, errp);
>
> [High]
> Can this new comparison reject INIT chunks whose final parameter has a
> length that is not a multiple of 4?
>
> sctp_walk_params() advances pos.v by SCTP_PAD4(ntohs(pos.p->length)) on
> every iteration:
>
>   include/net/sctp/sctp.h:
>   #define _sctp_walk_params(pos, chunk, end)\
>   for (pos.v = (u8 *)(chunk + 1);\
>        ...
>        pos.v += SCTP_PAD4(ntohs(pos.p->length)))
>
> so when the final parameter has an unpadded length L that is not 4-byte
> aligned, pos.v ends at peer_init + offset_of_last_param + SCTP_PAD4(L),
> which exceeds peer_init + ntohs(peer_init->chunk_hdr.length) by 1..3.
>
> The previous comparison used chunk->chunk_end, which inqueue.c computes
> with the padding included:
>
>   net/sctp/inqueue.c:
>   chunk->chunk_end = ((__u8 *)ch) + SCTP_PAD4(ntohs(ch->length));
>
> so the old check accepted unaligned-length final parameters; the new
> check returns 0 from sctp_verify_init(), and the callers then invoke
> sctp_abort_on_init_err() and emit an ABORT.
>
> Note that this change is in sctp_verify_init() itself, so it affects
> every caller, not just the new COOKIE-ECHO sites: sctp_sf_do_5_1B_init,
> sctp_sf_do_5_1C_ack, sctp_sf_do_unexpected_init, sctp_sf_do_5_1D_ce
> and sctp_sf_do_5_2_4_dupcook all reach this comparison.
>
> Realistic triggers include:
>
>   - Locally-generated INITs constructed by sctp_make_init() when both
>     auth_enable and asconf_enable are set: with the default chunk IDs
>     ASCONF + ASCONF_ACK the AUTH-CHUNKS parameter has length 6 and is
>     typically the last parameter, leaving chunk_hdr.length unaligned.
>
>   - Peer INITs containing any final parameter with non-4-aligned
>     length, e.g. SCTP_PARAM_SUPPORTED_ADDRESS_TYPES with 1 or 3 types
>     last, AUTH-CHUNKS with N=1,2,3 entries last, or any unknown TLV.
>
> Even in the COOKIE-ECHO context the new bound seems too strict, since
> sctp_pack_cookie() copies the INIT verbatim with memcpy(cookie + 1,
> init_chunk->chunk_hdr, ntohs(...->length)) followed immediately by
> raw_addrs, so unpacked cookies recovered from peers that sent an INIT
> with an unaligned-length final parameter would also be spuriously
> rejected.
>
> Would comparing against peer_init + SCTP_PAD4(ntohs(peer_init->
> chunk_hdr.length)) preserve the long-standing semantics of chunk_end
> while still validating the cookie-derived peer_init bounds?
>
There's no problem here, as INIT or INIT_ACK chunk's length is always
a multiple of 4, unless it's an abnormal one. We don't need SCTP_PAD4()
for this check.

Thanks.