Thread (11 messages) flat view 11 messages, 4 authors, 15h ago
HOTtoday

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

From: Breno Leitao <leitao@debian.org>
Date: 2026-08-06 09:42:24
Also in: lkml, stable
Subsystem: networking [general], networking [ipv4/ipv6], the rest · Maintainers: "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds

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.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Breno Leitao <leitao@debian.org>
---
 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;
-- 
2.53.0-Meta
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help