Commit cda26c64 authored by Florian Westphal's avatar Florian Westphal
Browse files

netfilter: nft_compat: add more restrictions on netlink attributes



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: 0ca743a5 ("netfilter: nf_tables: add compatibility layer for x_tables")
Reviewed-by: default avatarFernando Fernandez Mancera <fmancera@suse.de>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent a4400a5b
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -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: