[{"id":3673084,"web_url":"http://patchwork.ozlabs.org/comment/3673084/","msgid":"<ac-lHcg6NTg9sWGY@lemonverbena>","list_archive_url":null,"date":"2026-04-03T11:31:41","subject":"Re: [PATCH v3] netfilter: xt_multiport: validate range encoding in\n checkentry","submitter":{"id":1315,"url":"http://patchwork.ozlabs.org/api/people/1315/","name":"Pablo Neira Ayuso","email":"pablo@netfilter.org"},"content":"On Fri, Apr 03, 2026 at 02:21:17AM +0800, Ren Wei wrote:\n> ports_match_v1() treats any non-zero pflags entry as the start of a\n> port range and unconditionally consumes the next ports[] element as\n> the range end.\n> \n> The checkentry path currently validates protocol, flags and count, but\n> it does not validate the range encoding itself. As a result, malformed\n> rules can mark the last slot as a range start or place two range starts\n> back to back, leaving ports_match_v1() to step past the last valid\n> ports[] element while interpreting the rule.\n> \n> Reject malformed multiport v1 rules in checkentry by validating that\n> each range start has a following element and that the following element\n> is not itself marked as another range start.\n> \n> Fixes: a89ecb6a2ef7 (\"[NETFILTER]: x_tables: unify IPv4/IPv6 multiport match\")\n> Reported-by: Yifan Wu <yifanwucs@gmail.com>\n> Reported-by: Juefei Pu <tomapufckgml@gmail.com>\n> Co-developed-by: Yuan Tan <yuantan098@gmail.com>\n> Signed-off-by: Yuan Tan <yuantan098@gmail.com>\n> Suggested-by: Xin Liu <bird@lzu.edu.cn>\n> Tested-by: Yuhang Zheng <z1652074432@gmail.com>\n> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>\n> ---\n> Changes in v2:\n> - drop the selftest patch\n> - send the fix publicly to netfilter-devel\n> \n> Changes in v3:\n> - drop datatype cleanup from the fix\n> - keep the original check() interface unchanged\n> - validate malformed range encoding in checkentry\n> \n>  net/netfilter/xt_multiport.c | 30 ++++++++++++++++++++++++++----\n>  1 file changed, 26 insertions(+), 4 deletions(-)\n> \n> diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c\n> index 44a00f5acde8..07a0f2a3fc75 100644\n> --- a/net/netfilter/xt_multiport.c\n> +++ b/net/netfilter/xt_multiport.c\n> @@ -105,6 +105,24 @@ multiport_mt(const struct sk_buff *skb, struct xt_action_param *par)\n>  \treturn ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));\n>  }\n>  \n> +static inline bool\n> +multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)\n> +{\n> +\tunsigned int i;\n> +\n> +\tfor (i = 0; i < multiinfo->count; i++) {\n> +\t\tif (!multiinfo->pflags[i])\n> +\t\t\tcontinue;\n> +\n> +\t\tif (i + 1 >= multiinfo->count || multiinfo->pflags[i + 1])\n> +\t\t\treturn false;\n> +\n> +\t\ti++;\n> +\t}\n> +\n> +\treturn true;\n> +}\n\nI'd suggest:\n\nstatic inline bool\nmultiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)\n{\n        unsigned int i;\n \n        for (i = 0; i < multiinfo->count; i++) {\n                if (!multiinfo->pflags[i])\n                        continue;\n\n                if (++i >= multiinfo->count)\n                        return false;\n         \n                if (multiinfo->pflags[i])\n                        return false;\n         \n                if (multiinfo->ports[i - 1] > multiinfo->ports[i])\n                        return false;\n        }\n \n        return true;\n}\n\nThen, this validate non-sense ports array too.","headers":{"Return-Path":"\n <netfilter-devel+bounces-11598-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","netfilter-devel@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=netfilter.org header.i=@netfilter.org\n header.a=rsa-sha256 header.s=2025 header.b=Drw526LX;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c09:e001:a7::12fc:5321; helo=sto.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11598-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=\"Drw526LX\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=217.70.190.124","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=netfilter.org"],"Received":["from sto.lore.kernel.org (sto.lore.kernel.org\n [IPv6:2600:3c09:e001:a7::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fnGrV2bxKz1yCs\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 22:36:10 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sto.lore.kernel.org (Postfix) with ESMTP id 91936306EA04\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  3 Apr 2026 11:31:59 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 613173B9DA9;\n\tFri,  3 Apr 2026 11:31:55 +0000 (UTC)","from mail.netfilter.org (mail.netfilter.org [217.70.190.124])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id EF9883B7B80;\n\tFri,  3 Apr 2026 11:31:47 +0000 (UTC)","from netfilter.org (mail-agni [217.70.190.124])\n\tby mail.netfilter.org (Postfix) with UTF8SMTPSA id DB77F60263;\n\tFri,  3 Apr 2026 13:31:44 +0200 (CEST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775215913; cv=none;\n b=skyn8OQuCtTo54Mwk1LgFlhrQkcevjdOVRVDh/y8CZmkKvhXRWXuYSl3rE5gmPMg87lMcx25t5tctZ8DKN1+QGIsyozTOCdAvAZqwc7ziLJB4Y/6rMqqSdqBG1JgwNWrpike+7gy+OllRMxL4BB2o9TMicNpGd8nq7d1ym5fjws=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775215913; c=relaxed/simple;\n\tbh=hw9vVJ/9ofYm7xcOtSUi3kDUj/K6JiJZWSWNvpjo6SM=;\n\th=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version:\n\t Content-Type:Content-Disposition:In-Reply-To;\n b=ea6VnP8mlTIJMkKQkog+q16BH4GhfhSTozs8cQZ32/E1XqKPPbGXPDYPpz30t23xETK84uK5kK/EfPAXFULifN4D1kW3JNZMQWcZsZlmYsdwPcdg0Eh5K9ggFAEvyQ5j5qZ2VGckfx/BfcCrG6mT1ukunVw6UP+4tpd5Q4AJH2g=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org;\n spf=pass smtp.mailfrom=netfilter.org;\n dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=Drw526LX; arc=none smtp.client-ip=217.70.190.124","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org;\n\ts=2025; t=1775215905;\n\tbh=f2Ze/DFrB8iHp4LQ1YCD1tHzYUC4hCcRW+FKgOT532A=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Drw526LXxLn+vnzboYmZuPfsGy1xJngDeu13z5ivmayIuIrbI7JMFAcbTFlMoYEx2\n\t 4xs0Hvr5Kn96xk5KxUJplOaoCajHeUHZ/DzyQI4Cs0YFn6LYeo4GWl55tCWydWpK/e\n\t SqWBU27Q9XbX+bJ/GChReF9Y9dYKP+lpODk49ww8sAqoItV4891YmfsJ3KnUkreHD9\n\t gtDOG1C0xCFpMIvGUBMusQpq+LxVDf2YGew1hmqhYpYOGxtna/SGRJAVyMh+UPicyD\n\t b5uXsLJI/FcjJrhuFYJULAtm1WKpkgdd3MYgZhGzOCO126BmA6crIMgjIKPtqpxBxG\n\t n39c3NHZmGqDw==","Date":"Fri, 3 Apr 2026 13:31:41 +0200","From":"Pablo Neira Ayuso <pablo@netfilter.org>","To":"Ren Wei <n05ec@lzu.edu.cn>","Cc":"netfilter-devel@vger.kernel.org, netdev@vger.kernel.org, fw@strlen.de,\n\tphil@nwl.cc, davem@davemloft.net, edumazet@google.com,\n\tkuba@kernel.org, pabeni@redhat.com, horms@kernel.org,\n\tyasuyuki.kozakai@toshiba.co.jp, kaber@trash.net,\n\tyifanwucs@gmail.com, tomapufckgml@gmail.com, yuantan098@gmail.com,\n\tbird@lzu.edu.cn, z1652074432@gmail.com","Subject":"Re: [PATCH v3] netfilter: xt_multiport: validate range encoding in\n checkentry","Message-ID":"<ac-lHcg6NTg9sWGY@lemonverbena>","References":"<cover.1774624314.git.n05ec@lzu.edu.cn>\n <d5c0d106e724c732436b985dd694272bcb813bb1.1775153311.git.n05ec@lzu.edu.cn>","Precedence":"bulk","X-Mailing-List":"netfilter-devel@vger.kernel.org","List-Id":"<netfilter-devel.vger.kernel.org>","List-Subscribe":"<mailto:netfilter-devel+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:netfilter-devel+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"\n <d5c0d106e724c732436b985dd694272bcb813bb1.1775153311.git.n05ec@lzu.edu.cn>"}},{"id":3673085,"web_url":"http://patchwork.ozlabs.org/comment/3673085/","msgid":"<ac-mqkVOMHu673UC@lemonverbena>","list_archive_url":null,"date":"2026-04-03T11:38:18","subject":"Re: [PATCH v3] netfilter: xt_multiport: validate range encoding in\n checkentry","submitter":{"id":1315,"url":"http://patchwork.ozlabs.org/api/people/1315/","name":"Pablo Neira Ayuso","email":"pablo@netfilter.org"},"content":"On Fri, Apr 03, 2026 at 01:31:41PM +0200, Pablo Neira Ayuso wrote:\n> On Fri, Apr 03, 2026 at 02:21:17AM +0800, Ren Wei wrote:\n> > ports_match_v1() treats any non-zero pflags entry as the start of a\n> > port range and unconditionally consumes the next ports[] element as\n> > the range end.\n> > \n> > The checkentry path currently validates protocol, flags and count, but\n> > it does not validate the range encoding itself. As a result, malformed\n> > rules can mark the last slot as a range start or place two range starts\n> > back to back, leaving ports_match_v1() to step past the last valid\n> > ports[] element while interpreting the rule.\n> > \n> > Reject malformed multiport v1 rules in checkentry by validating that\n> > each range start has a following element and that the following element\n> > is not itself marked as another range start.\n> > \n> > Fixes: a89ecb6a2ef7 (\"[NETFILTER]: x_tables: unify IPv4/IPv6 multiport match\")\n> > Reported-by: Yifan Wu <yifanwucs@gmail.com>\n> > Reported-by: Juefei Pu <tomapufckgml@gmail.com>\n> > Co-developed-by: Yuan Tan <yuantan098@gmail.com>\n> > Signed-off-by: Yuan Tan <yuantan098@gmail.com>\n> > Suggested-by: Xin Liu <bird@lzu.edu.cn>\n> > Tested-by: Yuhang Zheng <z1652074432@gmail.com>\n> > Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>\n> > ---\n> > Changes in v2:\n> > - drop the selftest patch\n> > - send the fix publicly to netfilter-devel\n> > \n> > Changes in v3:\n> > - drop datatype cleanup from the fix\n> > - keep the original check() interface unchanged\n> > - validate malformed range encoding in checkentry\n> > \n> >  net/netfilter/xt_multiport.c | 30 ++++++++++++++++++++++++++----\n> >  1 file changed, 26 insertions(+), 4 deletions(-)\n> > \n> > diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c\n> > index 44a00f5acde8..07a0f2a3fc75 100644\n> > --- a/net/netfilter/xt_multiport.c\n> > +++ b/net/netfilter/xt_multiport.c\n> > @@ -105,6 +105,24 @@ multiport_mt(const struct sk_buff *skb, struct xt_action_param *par)\n> >  \treturn ports_match_v1(multiinfo, ntohs(pptr[0]), ntohs(pptr[1]));\n> >  }\n> >  \n> > +static inline bool\n> > +multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)\n> > +{\n> > +\tunsigned int i;\n> > +\n> > +\tfor (i = 0; i < multiinfo->count; i++) {\n> > +\t\tif (!multiinfo->pflags[i])\n> > +\t\t\tcontinue;\n> > +\n> > +\t\tif (i + 1 >= multiinfo->count || multiinfo->pflags[i + 1])\n> > +\t\t\treturn false;\n> > +\n> > +\t\ti++;\n> > +\t}\n> > +\n> > +\treturn true;\n> > +}\n> \n> I'd suggest:\n> \n> static inline bool\n\nActually, inline is silly here, no inline here.\n\n> multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)\n> {\n>         unsigned int i;\n>  \n>         for (i = 0; i < multiinfo->count; i++) {\n>                 if (!multiinfo->pflags[i])\n>                         continue;\n> \n>                 if (++i >= multiinfo->count)\n>                         return false;\n>          \n>                 if (multiinfo->pflags[i])\n>                         return false;\n>          \n>                 if (multiinfo->ports[i - 1] > multiinfo->ports[i])\n>                         return false;\n>         }\n>  \n>         return true;\n> }\n> \n> Then, this validate non-sense ports array too.\n\nYou can also mention in the patch description that this leads to\noff-by-one read after the array that is reported via UBSAN.\n\nThanks.","headers":{"Return-Path":"\n <netfilter-devel+bounces-11599-incoming=patchwork.ozlabs.org@vger.kernel.org>","X-Original-To":["incoming@patchwork.ozlabs.org","netfilter-devel@vger.kernel.org"],"Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=netfilter.org header.i=@netfilter.org\n header.a=rsa-sha256 header.s=2025 header.b=pGM/W+k4;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=netfilter-devel+bounces-11599-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=\"pGM/W+k4\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=217.70.190.124","smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=netfilter.org"],"Received":["from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fnGy754Vzz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 03 Apr 2026 22:41:03 +1100 (AEDT)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id 85293301E3F4\n\tfor <incoming@patchwork.ozlabs.org>; Fri,  3 Apr 2026 11:38:26 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id AA32A3B27FC;\n\tFri,  3 Apr 2026 11:38:25 +0000 (UTC)","from mail.netfilter.org (mail.netfilter.org [217.70.190.124])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D80E31D375;\n\tFri,  3 Apr 2026 11:38:23 +0000 (UTC)","from netfilter.org (mail-agni [217.70.190.124])\n\tby mail.netfilter.org (Postfix) with UTF8SMTPSA id 01C0560251;\n\tFri,  3 Apr 2026 13:38:22 +0200 (CEST)"],"ARC-Seal":"i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775216305; cv=none;\n b=sZo+wmBYoFab3gkfKfJyfYsjq8dvf9w7u8Gk9kGqOt5ifa3X3sDKbSuv4Ey/sUBoNo6B5Hs4AjEw/m9NfTjMexCj8byL7c1NrfVflqcdiDSvyX3QURk8le/fDd8VtuF8ikHCcqNdfSrB5sm/skWQQXdtQomZPB3vC0YfHikT218=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775216305; c=relaxed/simple;\n\tbh=Vpm56VZ1GZ1Y7W9CVZyWBqubGh02QR8XtmUh7YGRPUc=;\n\th=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version:\n\t Content-Type:Content-Disposition:In-Reply-To;\n b=ktTYvJTfgI1OKwjSL9V9pEyKEhRtD67eOqc0WHM8lWX1oc9bh+DKUoaCDwmD43qbpM5h9kRTkJ17jC/WyEbgkgqEqk05kRFFOLKCayN7EDTdR9tUr1mFcJhJVASDtxbj/61SMFUaC8PFCt1dPZDTgSNqr2GuZV8I4VlJ5rI5Izs=","ARC-Authentication-Results":"i=1; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=netfilter.org;\n spf=pass smtp.mailfrom=netfilter.org;\n dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org\n header.b=pGM/W+k4; arc=none smtp.client-ip=217.70.190.124","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org;\n\ts=2025; t=1775216302;\n\tbh=b7Q9vhu468ezbsFTKuz/mFheQzvf86bCacmkT7oDh4g=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=pGM/W+k4sf9TU1cj1tAL9bQwvZSBUfsYhxKpA/i4SVcREdOSqPv/c53jV5jM4E1h9\n\t NdDbeKwtndII6cv4Ju30pW12SNnWMI8k3BphFUXUL0as0J4hZFvyAHlTDCSCmuob+k\n\t PlXC8pJX5vPMhevmqM29wUMihN8OX73PzeyL9k7W4gvGWHbU3sqg4XkmarUPdVChCi\n\t ORhui7I4ZtVIkf7hful83LIJszwv6aP8VJdN5g65V++zEhRWqGhxgifPnLUzyn4GO/\n\t jtEccGGASv9mBOujSrCt+WXOzMdLh9uXLpjIhs9mhAbefHJnLQKh7Dujoh5RdZzz1P\n\t Ha/WDlBX98aGw==","Date":"Fri, 3 Apr 2026 13:38:18 +0200","From":"Pablo Neira Ayuso <pablo@netfilter.org>","To":"Ren Wei <n05ec@lzu.edu.cn>","Cc":"netfilter-devel@vger.kernel.org, netdev@vger.kernel.org, fw@strlen.de,\n\tphil@nwl.cc, davem@davemloft.net, edumazet@google.com,\n\tkuba@kernel.org, pabeni@redhat.com, horms@kernel.org,\n\tyasuyuki.kozakai@toshiba.co.jp, kaber@trash.net,\n\tyifanwucs@gmail.com, tomapufckgml@gmail.com, yuantan098@gmail.com,\n\tbird@lzu.edu.cn, z1652074432@gmail.com","Subject":"Re: [PATCH v3] netfilter: xt_multiport: validate range encoding in\n checkentry","Message-ID":"<ac-mqkVOMHu673UC@lemonverbena>","References":"<cover.1774624314.git.n05ec@lzu.edu.cn>\n <d5c0d106e724c732436b985dd694272bcb813bb1.1775153311.git.n05ec@lzu.edu.cn>\n <ac-lHcg6NTg9sWGY@lemonverbena>","Precedence":"bulk","X-Mailing-List":"netfilter-devel@vger.kernel.org","List-Id":"<netfilter-devel.vger.kernel.org>","List-Subscribe":"<mailto:netfilter-devel+subscribe@vger.kernel.org>","List-Unsubscribe":"<mailto:netfilter-devel+unsubscribe@vger.kernel.org>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<ac-lHcg6NTg9sWGY@lemonverbena>"}}]