Re: [PATCH net 2/2] ipv6: mcast: do not write past optlen in the source filter getsockopt

David Laight <[email protected]>
Newsgroups gmane.linux.network,gmane.linux.kernel,gmane.linux.kernel.stable
Message-ID <20260807174437.01bf2e33@pumpkin>
On Thu, 06 Aug 2026 02:42:01 -0700
Breno Leitao <[email protected]> wrote:

> getsockopt(MCAST_MSFILTER) on an IPv6 socket overruns the caller's buffer
> the same way the IPv4 one does. ip6_mc_msfget() fills the source list from
> the numsrc left in optval, and nothing compares that against optlen, which
> ipv6_get_msfilter() has already reused for the length of the reply.
> 
> Clamp numsrc to what optlen holds, as the IPv4 side now does.

Nak, same as IPv4.

	David

> 
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Cc: [email protected]
> Signed-off-by: Breno Leitao <[email protected]>
> ---
>  net/ipv6/ipv6_sockglue.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
> index b4c977434c2e0..2c3fbde7cb058 100644
> --- a/net/ipv6/ipv6_sockglue.c
> +++ b/net/ipv6/ipv6_sockglue.c
> @@ -1012,6 +1012,7 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
>  {
>  	const int size0 = offsetof(struct group_filter, gf_slist_flex);
>  	struct group_filter gsf;
> +	unsigned int max_numsrc;
>  	int num;
>  	int err;
>  
> @@ -1021,6 +1022,11 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
>  		return -EFAULT;
>  	if (gsf.gf_group.ss_family != AF_INET6)
>  		return -EADDRNOTAVAIL;
> +
> +	/* Number of sources that would fit in the userspace buffer */
> +	max_numsrc = (len - size0) / sizeof(gsf.gf_slist_flex[0]);
> +	gsf.gf_numsrc = min_t(u32, gsf.gf_numsrc, max_numsrc);
> +
>  	num = gsf.gf_numsrc;
>  	sockopt_lock_sock(sk);
>  	err = ip6_mc_msfget(sk, &gsf, optval, size0);
> @@ -1041,6 +1047,7 @@ static int compat_ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
>  {
>  	const int size0 = offsetof(struct compat_group_filter, gf_slist_flex);
>  	struct compat_group_filter gf32;
> +	unsigned int max_numsrc;
>  	struct group_filter gf;
>  	int err;
>  	int num;
> @@ -1050,6 +1057,10 @@ static int compat_ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
>  
>  	if (copy_from_sockptr(&gf32, optval, size0))
>  		return -EFAULT;
> +
> +	max_numsrc = (len - size0) / sizeof(gf32.gf_slist_flex[0]);
> +	gf32.gf_numsrc = min_t(u32, gf32.gf_numsrc, max_numsrc);
> +
>  	gf.gf_interface = gf32.gf_interface;
>  	gf.gf_fmode = gf32.gf_fmode;
>  	num = gf.gf_numsrc = gf32.gf_numsrc;
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.