]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: xt_connmark: reject invalid shift parameters
authorWyatt Feng <bronzed_45_vested@icloud.com>
Fri, 3 Jul 2026 05:04:46 +0000 (13:04 +0800)
committerFlorian Westphal <fw@strlen.de>
Fri, 3 Jul 2026 12:45:21 +0000 (14:45 +0200)
Revision 2 of the CONNMARK target accepts user-controlled shift
parameters and applies them to 32-bit mark values in
connmark_tg_shift().

A shift_bits value of 32 or more triggers an undefined-shift bug when
the rule is evaluated. Invalid shift_dir values are also accepted and
silently fall back to the left-shift path.

Reject invalid revision-2 shift parameters in connmark_tg_check() so
malformed rules fail at installation time, before they can reach the
packet path.

Fixes: 472a73e00757 ("netfilter: xt_conntrack: Support bit-shifting for CONNMARK & MARK targets.")
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <dstsmallbird@foxmail.com>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com>
Reviewed-by: Ren Wei <enjou1224z@gmail.com>
Reviewed-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/xt_connmark.c

index 4277084de2e70c995f49cadd411cab70473b3ad9..2cf27f7d59b95fc8beb0c1b75c7f3e67ea74d6e7 100644 (file)
@@ -112,6 +112,16 @@ static int connmark_tg_check(const struct xt_tgchk_param *par)
        return ret;
 }
 
+static int connmark_tg_check_v2(const struct xt_tgchk_param *par)
+{
+       const struct xt_connmark_tginfo2 *info = par->targinfo;
+
+       if (info->shift_dir > D_SHIFT_RIGHT || info->shift_bits >= 32)
+               return -EINVAL;
+
+       return connmark_tg_check(par);
+}
+
 static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
 {
        nf_ct_netns_put(par->net, par->family);
@@ -162,7 +172,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
                .name           = "CONNMARK",
                .revision       = 2,
                .family         = NFPROTO_IPV4,
-               .checkentry     = connmark_tg_check,
+               .checkentry     = connmark_tg_check_v2,
                .target         = connmark_tg_v2,
                .targetsize     = sizeof(struct xt_connmark_tginfo2),
                .destroy        = connmark_tg_destroy,
@@ -183,7 +193,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
                .name           = "CONNMARK",
                .revision       = 2,
                .family         = NFPROTO_IPV6,
-               .checkentry     = connmark_tg_check,
+               .checkentry     = connmark_tg_check_v2,
                .target         = connmark_tg_v2,
                .targetsize     = sizeof(struct xt_connmark_tginfo2),
                .destroy        = connmark_tg_destroy,