Skip to content

Commit 8260354

Browse files
committed
netfilter: nf_tables: add __nft_chain_type_get()
This new helper function validates that unknown family and chain type coming from userspace do not trigger an out-of-bound array access. Bail out in case __nft_chain_type_get() returns NULL from nft_chain_parse_hook(). Fixes: 9370761 ("netfilter: nf_tables: convert built-in tables/chains to chain types") Reported-by: [email protected] Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent c83de17 commit 8260354

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -552,15 +552,28 @@ static inline u64 nf_tables_alloc_handle(struct nft_table *table)
552552

553553
static const struct nft_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX];
554554

555+
static const struct nft_chain_type *
556+
__nft_chain_type_get(u8 family, enum nft_chain_types type)
557+
{
558+
if (family >= NFPROTO_NUMPROTO ||
559+
type >= NFT_CHAIN_T_MAX)
560+
return NULL;
561+
562+
return chain_type[family][type];
563+
}
564+
555565
static const struct nft_chain_type *
556566
__nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family)
557567
{
568+
const struct nft_chain_type *type;
558569
int i;
559570

560571
for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
561-
if (chain_type[family][i] != NULL &&
562-
!nla_strcmp(nla, chain_type[family][i]->name))
563-
return chain_type[family][i];
572+
type = __nft_chain_type_get(family, i);
573+
if (!type)
574+
continue;
575+
if (!nla_strcmp(nla, type->name))
576+
return type;
564577
}
565578
return NULL;
566579
}
@@ -1162,11 +1175,8 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx)
11621175

11631176
void nft_register_chain_type(const struct nft_chain_type *ctype)
11641177
{
1165-
if (WARN_ON(ctype->family >= NFPROTO_NUMPROTO))
1166-
return;
1167-
11681178
nfnl_lock(NFNL_SUBSYS_NFTABLES);
1169-
if (WARN_ON(chain_type[ctype->family][ctype->type] != NULL)) {
1179+
if (WARN_ON(__nft_chain_type_get(ctype->family, ctype->type))) {
11701180
nfnl_unlock(NFNL_SUBSYS_NFTABLES);
11711181
return;
11721182
}
@@ -1768,7 +1778,10 @@ static int nft_chain_parse_hook(struct net *net,
17681778
hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
17691779
hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
17701780

1771-
type = chain_type[family][NFT_CHAIN_T_DEFAULT];
1781+
type = __nft_chain_type_get(family, NFT_CHAIN_T_DEFAULT);
1782+
if (!type)
1783+
return -EOPNOTSUPP;
1784+
17721785
if (nla[NFTA_CHAIN_TYPE]) {
17731786
type = nf_tables_chain_type_lookup(net, nla[NFTA_CHAIN_TYPE],
17741787
family, autoload);

0 commit comments

Comments
 (0)