Re: [PATCH net] sctp: fix possible out-of-bounds read in SCTP_PARAM_SUPPORTED_ADDRESS_TYPES
Xin Long <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.kernel.vger.linux-sctp,org.kernel.vger.netdev |
|---|---|
| Message-ID | <CADvbK_dRmpABM=DA6B1MxZLDf7pcqD0f_mWios+ecJnCBOqqNA@mail.gmail.com> |
On Tue, Aug 18, 2026 at 5:23 AM luoqing <[email protected]> wrote: > > From: Qing Luo <[email protected]> > > While processing SCTP_PARAM_SUPPORTED_ADDRESS_TYPES in > sctp_process_param(), the length field is subtracted from > sizeof(struct sctp_paramhdr) and stored in a __u16 variable. If the > length is less than sizeof(struct sctp_paramhdr) (4 bytes), the unsigned > subtraction underflows, resulting in a value near 0xFFFF. The subsequent > for() loop then iterates far beyond the parameter boundaries, causing an > out-of-bounds read. > > sctp_verify_param() performs no length validation for this parameter > type, so a malformed parameter with insufficient length can reach > sctp_process_param() through the INIT/INIT-ACK/COOKIE-ECHO processing > path. > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Cc: [email protected] > Signed-off-by: Qing Luo <[email protected]> > --- > net/sctp/sm_make_chunk.c | 12 +++++++++++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c > index 236e25abc7a4..ebf791969454 100644 > --- a/net/sctp/sm_make_chunk.c > +++ b/net/sctp/sm_make_chunk.c > @@ -2169,12 +2169,19 @@ static enum sctp_ierror sctp_verify_param(struct net *net, > case SCTP_PARAM_IPV4_ADDRESS: > case SCTP_PARAM_IPV6_ADDRESS: > case SCTP_PARAM_COOKIE_PRESERVATIVE: > - case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES: > case SCTP_PARAM_STATE_COOKIE: > case SCTP_PARAM_HEARTBEAT_INFO: > case SCTP_PARAM_UNRECOGNIZED_PARAMETERS: > case SCTP_PARAM_ECN_CAPABLE: > break; > + > + case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES: > + if (ntohs(param.p->length) < sizeof(struct sctp_paramhdr)) { > + sctp_process_inv_paramlength(asoc, param.p, > + chunk, err_chunk); > + retval = SCTP_IERROR_ABORT; > + } > + break; > case SCTP_PARAM_ADAPTATION_LAYER_IND: > if (ntohs(param.p->length) != sizeof(*param.aind)) { > sctp_process_inv_paramlength(asoc, param.p, > @@ -2600,6 +2607,9 @@ static int sctp_process_param(struct sctp_association *asoc, > asoc->peer.ipv4_address = 1; > > /* Cycle through address types; avoid divide by 0. */ > + if (ntohs(param.p->length) < sizeof(struct sctp_paramhdr)) > + break; > + > sat = ntohs(param.p->length) - sizeof(struct sctp_paramhdr); > if (sat) > sat /= sizeof(__u16); > -- > 2.25.1 > This is not necessary. Please check sctp_walk_params(), and I think it's already validated this for all params: ntohs(pos.p->length) >= sizeof(struct sctp_paramhdr) Thanks.