]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: nft_compat: add more restrictions on netlink attributes
authorFlorian Westphal <fw@strlen.de>
Fri, 19 Aug 2022 14:16:07 +0000 (16:16 +0200)
committerFlorian Westphal <fw@strlen.de>
Tue, 20 Jan 2026 15:23:37 +0000 (16:23 +0100)
As far as I can see nothing bad can happen when NFTA_TARGET/MATCH_NAME
are too large because this calls x_tables helpers which check for the
length, but it seems better to already reject it during netlink parsing.

Rest of the changes avoid silent u8/u16 truncations.

For _TYPE, its expected to be only 1 or 0. In x_tables world, this
variable is set by kernel, for IPT_SO_GET_REVISION_TARGET its 1, for
all others its set to 0.

As older versions of nf_tables permitted any value except 1 to mean 'match',
keep this as-is but sanitize the value for consistency.

Fixes: 0ca743a55991 ("netfilter: nf_tables: add compatibility layer for x_tables")
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nft_compat.c

index 72711d62fddfa4608e5ea6199d724b4b5d03e21c..08f620311b03f140d26f2931ebddf62db2db89b6 100644 (file)
@@ -134,7 +134,8 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
 }
 
 static const struct nla_policy nft_target_policy[NFTA_TARGET_MAX + 1] = {
-       [NFTA_TARGET_NAME]      = { .type = NLA_NUL_STRING },
+       [NFTA_TARGET_NAME]      = { .type = NLA_NUL_STRING,
+                                   .len = XT_EXTENSION_MAXNAMELEN, },
        [NFTA_TARGET_REV]       = NLA_POLICY_MAX(NLA_BE32, 255),
        [NFTA_TARGET_INFO]      = { .type = NLA_BINARY },
 };
@@ -434,7 +435,8 @@ static void nft_match_eval(const struct nft_expr *expr,
 }
 
 static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
-       [NFTA_MATCH_NAME]       = { .type = NLA_NUL_STRING },
+       [NFTA_MATCH_NAME]       = { .type = NLA_NUL_STRING,
+                                   .len = XT_EXTENSION_MAXNAMELEN },
        [NFTA_MATCH_REV]        = NLA_POLICY_MAX(NLA_BE32, 255),
        [NFTA_MATCH_INFO]       = { .type = NLA_BINARY },
 };
@@ -693,7 +695,12 @@ static int nfnl_compat_get_rcu(struct sk_buff *skb,
 
        name = nla_data(tb[NFTA_COMPAT_NAME]);
        rev = ntohl(nla_get_be32(tb[NFTA_COMPAT_REV]));
-       target = ntohl(nla_get_be32(tb[NFTA_COMPAT_TYPE]));
+       /* x_tables api checks for 'target == 1' to mean target,
+        * everything else means 'match'.
+        * In x_tables world, the number is set by kernel, not
+        * userspace.
+        */
+       target = nla_get_be32(tb[NFTA_COMPAT_TYPE]) == htonl(1);
 
        switch(family) {
        case AF_INET: