From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 162863C3456; Mon, 20 Apr 2026 19:27:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776713221; cv=none; b=NWBVyD86+Erzynj04QSsPd2kJI3KT5Fkz7ZW62NDQ15Q2bWiZpfasjWHfUTQ4J1YubxMGfUWSdGzXPtUc0IZdIKssQ5lNOf/41KSujuqHxJSQkJ/i0IwTzUBsnbNbTF4Ey2dBeABNRJCYv2YzlkdyXbuP/HSNuGfnhPXuxfvuZU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776713221; c=relaxed/simple; bh=9OSHuZePSrTe460DCMA4DIILHzJARLfaMLLe9QELeUk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=W4QVfyd+J5xOu0cJRf9DuRf8kU82xQ1Upc37CxzPPGsv7Pq0nKYhhX3sP/Tz/FIVwMhZwGocQcZuS6v9HBOUWnHXbPsf6+0SIWdw9UdFz+UY5vIwu3Sa8/vZmWLyPtcNLKq7sWum/lfi8CpCrebrpXbu32xZJ3IalfvSDSaK/VE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=CWK9L9cb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="CWK9L9cb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0EAAC2BCB4; Mon, 20 Apr 2026 19:26:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1776713220; bh=9OSHuZePSrTe460DCMA4DIILHzJARLfaMLLe9QELeUk=; h=From:To:Cc:Subject:Date:From; b=CWK9L9cbbg0xJ8FShogiVwFuEs07qbpT27CU7iRqhiBPAEdaz+o40J1+aJq73MHKS LxFgg6lqztBg96qOLANvhpPTi5+qpFmSX4MlUkOltsUi35wjYiM/VFxBDzADEGbByT GZd10GNOerPkF1gfKBCfrzATvFVss4ICE3W0s8zM= From: Greg Kroah-Hartman To: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Kroah-Hartman , "David S. Miller" , David Ahern , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , stable Subject: [PATCH net] ipv4: clamp MCAST_MSFILTER getsockopt to optlen, not gf_numsrc Date: Mon, 20 Apr 2026 21:26:55 +0200 Message-ID: <2026042054-dime-spectator-820e@gregkh> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2688; i=gregkh@linuxfoundation.org; h=from:subject:message-id; bh=9OSHuZePSrTe460DCMA4DIILHzJARLfaMLLe9QELeUk=; b=owGbwMvMwCRo6H6F97bub03G02pJDJnPav+dZt28e56KrofE2unGr7fO6nA9x5tWunXrz/eLN vufv63A2hHLwiDIxCArpsjyZRvP0f0VhxS9DG1Pw8xhZQIZwsDFKQAT8W9lmO99tFUkN8bq8+qm 79J5dTfZFQLC+BjmivAsDp79RFnuTk6kDyPj7EnBM+9zAAA= X-Developer-Key: i=gregkh@linuxfoundation.org; a=openpgp; fpr=F4B60CC5BF78C2214A313DCB3147D40DDB2DFB29 Content-Transfer-Encoding: 8bit ip_get_mcast_msfilter() and its compat sibling read gf_numsrc from the user's buffer header and pass it to ip_mc_gsfget(), which writes: min(actual_sources, gf_numsrc) * sizeof(struct sockaddr_storage) bytes back into the user's optval starting at the gf_slist_flex offset. The only optlen check is len >= size0 (the header), so a user can pass optlen = 144 (header only) with gf_numsrc = 4. If the socket has at least 4 sources joined, the kernel writes 4*128 = 512 bytes via copy_to_sockptr_offset() past the end of the user buffer. This is a kernel-driven userspace heap overflow: the user told the kernel their buffer size via optlen, the kernel ignored it and used a field inside the buffer instead. On a real system the writes go into adjacent userspace heap and copy_to_user does not fault on mapped heap pages. Clamp gf_numsrc to (len - size0) / sizeof(sockaddr_storage) before the call so the kernel never writes past what the user provided. The setsockopt path already has the equivalent check (GROUP_FILTER_SIZE(gf_numsrc) > optlen at line 790). Cc: "David S. Miller" Cc: David Ahern Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: Simon Horman Reported-by: Anthropic Assisted-by: gkh_clanker_t1000 Cc: stable Signed-off-by: Greg Kroah-Hartman --- net/ipv4/ip_sockglue.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a55ef327ec93..c9bf5d223f21 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1456,6 +1456,11 @@ static int ip_get_mcast_msfilter(struct sock *sk, sockptr_t optval, return -EFAULT; num = gsf.gf_numsrc; + + if (num > (len - size0) / sizeof(struct sockaddr_storage)) + num = (len - size0) / sizeof(struct sockaddr_storage); + gsf.gf_numsrc = num; + err = ip_mc_gsfget(sk, &gsf, optval, offsetof(struct group_filter, gf_slist_flex)); if (err) @@ -1486,8 +1491,12 @@ static int compat_ip_get_mcast_msfilter(struct sock *sk, sockptr_t optval, gf.gf_interface = gf32.gf_interface; gf.gf_fmode = gf32.gf_fmode; num = gf.gf_numsrc = gf32.gf_numsrc; - gf.gf_group = gf32.gf_group; + if (num > (len - size0) / sizeof(struct sockaddr_storage)) + num = (len - size0) / sizeof(struct sockaddr_storage); + gf.gf_numsrc = num; + + gf.gf_group = gf32.gf_group; err = ip_mc_gsfget(sk, &gf, optval, offsetof(struct compat_group_filter, gf_slist_flex)); if (err) -- 2.53.0