From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Ren Wei <n05ec@lzu.edu.cn>
Cc: netfilter-devel@vger.kernel.org, security@kernel.org,
fw@strlen.de, phil@nwl.cc, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
horms@kernel.org, shuah@kernel.org, yuantan098@gmail.com,
bird@lzu.edu.cn, z1652074432@gmail.com, kaber@trash.net,
yasuyuki.kozakai@toshiba.co.jp, yifanwucs@gmail.com,
tomapufckgml@gmail.com, enjou1224z@gmail.com
Subject: Re: [PATCH v2] netfilter: xt_multiport: reject trailing range markers
Date: Wed, 1 Apr 2026 01:29:35 +0200 [thread overview]
Message-ID: <acxY3z1h2qkpzaEw@chamomile> (raw)
In-Reply-To: <dc1b0139fc250e188657e874ce4bb67f60af6e0c.1774659119.git.n05ec@lzu.edu.cn>
Hi,
On Sat, Mar 28, 2026 at 10:51:23PM +0800, Ren Wei wrote:
> diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
> index 44a00f5acde8..38aa5b90d38e 100644
> --- a/net/netfilter/xt_multiport.c
> +++ b/net/netfilter/xt_multiport.c
> @@ -26,10 +26,10 @@ MODULE_ALIAS("ip6t_multiport");
> /* Returns 1 if the port is matched by the test, 0 otherwise. */
> static inline bool
> ports_match_v1(const struct xt_multiport_v1 *minfo,
> - u_int16_t src, u_int16_t dst)
> + u16 src, u16 dst)
> {
> unsigned int i;
> - u_int16_t s, e;
> + u16 s, e;
>
> for (i = 0; i < minfo->count; i++) {
> s = minfo->ports[i];
I see, this is a cleanup to use preferred datatypes.
> @@ -106,20 +106,36 @@ multiport_mt(const struct sk_buff *skb, struct xt_action_param *par)
> }
>
> static inline bool
> -check(u_int16_t proto,
> - u_int8_t ip_invflags,
> - u_int8_t match_flags,
> - u_int8_t count)
> +multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < multiinfo->count; i++) {
> + if (!multiinfo->pflags[i])
> + continue;
> +
> + if (i == multiinfo->count - 1)
> + return false;
> +
> + i++;
> + }
Why so convoluted? This should just fix this bug:
static bool multiport_valid_ranges(const struct xt_multiport_v1 *multiinfo)
{
return multiinfo->pflags[multiinfo->count - 1] == 0;
}
This is an off-by-one read bug from packet path that is possible
because the last slot in the multiport array _must_ be zero.
pflags[i] non-zero means beginning of a range, and pflags[i+1] zero
means end of range (or singleton port).
Actually multiport_valid_ranges() can just go away too given the more
simple fix.
> +
> + return true;
> +}
> +
> +static inline bool
> +check(u16 proto, u8 ip_invflags, const struct xt_multiport_v1 *multiinfo)
> {
> /* Must specify supported protocol, no unknown flags or bad count */
> - return (proto == IPPROTO_TCP || proto == IPPROTO_UDP
> - || proto == IPPROTO_UDPLITE
> - || proto == IPPROTO_SCTP || proto == IPPROTO_DCCP)
> - && !(ip_invflags & XT_INV_PROTO)
> - && (match_flags == XT_MULTIPORT_SOURCE
> - || match_flags == XT_MULTIPORT_DESTINATION
> - || match_flags == XT_MULTIPORT_EITHER)
> - && count <= XT_MULTI_PORTS;
> + return (proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
> + proto == IPPROTO_UDPLITE ||
> + proto == IPPROTO_SCTP || proto == IPPROTO_DCCP) &&
> + !(ip_invflags & XT_INV_PROTO) &&
> + (multiinfo->flags == XT_MULTIPORT_SOURCE ||
> + multiinfo->flags == XT_MULTIPORT_DESTINATION ||
> + multiinfo->flags == XT_MULTIPORT_EITHER) &&
> + multiinfo->count <= XT_MULTI_PORTS &&
> + multiport_valid_ranges(multiinfo);
It took me a while to review this cleanup-in-fix is doing what it is
intended. While this coding style is preferred these days, I'm unsure
I want this cleanup in this fix.
I think this fix can be turned into a oneliner...
> }
>
> static int multiport_mt_check(const struct xt_mtchk_param *par)
> @@ -127,8 +143,7 @@ static int multiport_mt_check(const struct xt_mtchk_param *par)
> const struct ipt_ip *ip = par->entryinfo;
> const struct xt_multiport_v1 *multiinfo = par->matchinfo;
>
> - return check(ip->proto, ip->invflags, multiinfo->flags,
> - multiinfo->count) ? 0 : -EINVAL;
> + return check(ip->proto, ip->invflags, multiinfo) ? 0 : -EINVAL;
> }
>
> static int multiport_mt6_check(const struct xt_mtchk_param *par)
> @@ -136,8 +151,7 @@ static int multiport_mt6_check(const struct xt_mtchk_param *par)
> const struct ip6t_ip6 *ip = par->entryinfo;
> const struct xt_multiport_v1 *multiinfo = par->matchinfo;
>
> - return check(ip->proto, ip->invflags, multiinfo->flags,
> - multiinfo->count) ? 0 : -EINVAL;
> + return check(ip->proto, ip->invflags, multiinfo) ? 0 : -EINVAL;
> }
>
> static struct xt_match multiport_mt_reg[] __read_mostly = {
> --
> 2.51.0
>
next prev parent reply other threads:[~2026-03-31 23:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1774624314.git.n05ec@lzu.edu.cn>
2026-03-28 14:51 ` [PATCH v2] netfilter: xt_multiport: reject trailing range markers Ren Wei
2026-03-31 23:29 ` Pablo Neira Ayuso [this message]
2026-03-31 23:39 ` Pablo Neira Ayuso
2026-04-02 17:34 ` [PATCH v2] netfilter: xt_multiport: validate range encoding in checkentry Ren Wei
2026-04-02 18:21 ` [PATCH v3] " Ren Wei
2026-04-03 11:31 ` Pablo Neira Ayuso
2026-04-03 11:38 ` Pablo Neira Ayuso
2026-04-03 15:52 ` [PATCH v4] " Ren Wei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=acxY3z1h2qkpzaEw@chamomile \
--to=pablo@netfilter.org \
--cc=bird@lzu.edu.cn \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=enjou1224z@gmail.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=kaber@trash.net \
--cc=kuba@kernel.org \
--cc=n05ec@lzu.edu.cn \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=phil@nwl.cc \
--cc=security@kernel.org \
--cc=shuah@kernel.org \
--cc=tomapufckgml@gmail.com \
--cc=yasuyuki.kozakai@toshiba.co.jp \
--cc=yifanwucs@gmail.com \
--cc=yuantan098@gmail.com \
--cc=z1652074432@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox