Re: [PATCH net] sctp: fix OOB write to userspace in sctp_getsockopt_peer_auth_chunks

From: Xin Long

Date: Thu Apr 16 2026 - 09:51:13 EST


On Wed, Apr 15, 2026 at 11:19 PM Michael Bommarito
<michael.bommarito@xxxxxxxxx> 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: stable@xxxxxxxxxxxxxxx
> Assisted-by: Claude:claude-opus-4-6
> Signed-off-by: Michael Bommarito <michael.bommarito@xxxxxxxxx>
> ---
> 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 <lucien.xin@xxxxxxxxx>