Re: [PATCH net] sctp: fix OOB write to userspace in sctp_getsockopt_peer_auth_chunks
Xin Long <[email protected]> Thu, 16 Apr 2026 09:46:51 -0400
| Newsgroups | org.kernel.vger.linux-sctp,org.kernel.vger.linux-kernel,org.kernel.vger.netdev,org.kernel.vger.stable |
|---|---|
| Message-ID | <CADvbK_d_T++kjJ1U3g8RZRM8AUTHsrqD47Y3EuB3wZQTxeZ6Fg@mail.gmail.com> |
On Wed, Apr 15, 2026 at 11:19 PM Michael Bommarito <[email protected]> wrote: > > sctp_getsockopt_peer_auth_chunks() checks that the caller's optval > buffer is large enough for the peer AUTH chunk list with > > if (len < num_chunks) > return -EINVAL; > > but then writes num_chunks bytes to p->gauth_chunks, which lives > at offset offsetof(struct sctp_authchunks, gauth_chunks) == 8 > inside optval. The check is missing the sizeof(struct > sctp_authchunks) = 8-byte header. When the caller supplies > len == num_chunks (for any num_chunks > 0) the test passes but > copy_to_user() writes sizeof(struct sctp_authchunks) = 8 bytes > past the declared buffer. > > The sibling function sctp_getsockopt_local_auth_chunks() at the > next line already has the correct check: > > if (len < sizeof(struct sctp_authchunks) + num_chunks) > return -EINVAL; > > Align the peer variant with its sibling. > > Reproducer confirms on v7.0-13-generic: an unprivileged userspace > caller that opens a loopback SCTP association with AUTH enabled, > queries num_chunks with a short optval, then issues the real > getsockopt with len == num_chunks and sentinel bytes painted past > the buffer observes those sentinel bytes overwritten with the > peer's AUTH chunk type. The bytes written are under the peer's > control but land in the caller's own userspace; this is not a > kernel memory corruption, but it is a kernel-side contract > violation that can silently corrupt adjacent userspace data. > > Fixes: 65b07e5d0d09 ("[SCTP]: API updates to suport SCTP-AUTH extensions.") > Cc: [email protected] > Assisted-by: Claude:claude-opus-4-6 > Signed-off-by: Michael Bommarito <[email protected]> > --- > net/sctp/socket.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/sctp/socket.c b/net/sctp/socket.c > index 05fb00c9c335..f5d442753dc9 100644 > --- a/net/sctp/socket.c > +++ b/net/sctp/socket.c > @@ -7033,7 +7033,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, > > /* See if the user provided enough room for all the data */ > num_chunks = ntohs(ch->param_hdr.length) - sizeof(struct sctp_paramhdr); > - if (len < num_chunks) > + if (len < sizeof(struct sctp_authchunks) + num_chunks) > return -EINVAL; > > if (copy_to_user(to, ch->chunks, num_chunks)) > -- > 2.53.0 > Acked-by: Xin Long <[email protected]>