[Devel] [PATCH vz7 3/3] ms/netfilter: nf_tables: Allow chain name of up to 255 chars
Nikita Yushchenko
nikita.yushchenko at virtuozzo.com
Tue Nov 23 13:32:48 MSK 2021
From: Phil Sutter <phil at nwl.cc>
Same conversion as for table names, use NFT_NAME_MAXLEN as upper
boundary as well.
Signed-off-by: Phil Sutter <phil at nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
Upstream commit b7263e071aba736cea9e71cdf2e76dfa7aebd039.
https://jira.sw.ru/browse/PSBM-136188
Signed-off-by: Nikita Yushchenko <nikita.yushchenko at virtuozzo.com>
---
include/net/netfilter/nf_tables.h | 4 +--
include/uapi/linux/netfilter/nf_tables.h | 2 +-
net/netfilter/nf_tables_api.c | 34 ++++++++++++++++++------
net/netfilter/nf_tables_trace.c | 27 +++++++++++++++++--
4 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 3c94afed1caf..ad8039659fc6 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -812,7 +812,7 @@ struct nft_chain {
u16 level;
u8 flags:6,
genmask:2;
- char name[NFT_CHAIN_MAXNAMELEN];
+ char *name;
};
enum nft_chain_type {
@@ -1132,7 +1132,7 @@ struct nft_trans_set {
struct nft_trans_chain {
bool update;
- char name[NFT_CHAIN_MAXNAMELEN];
+ char *name;
struct nft_stats __percpu *stats;
u8 policy;
};
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 85693fa68a32..98ad9c3d98f4 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -3,7 +3,7 @@
#define NFT_NAME_MAXLEN 256
#define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN
-#define NFT_CHAIN_MAXNAMELEN 32
+#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN
#define NFT_USERDATA_MAXLEN 256
/**
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 99fa883eae2d..afada68cac7e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1201,8 +1201,10 @@ static void nf_tables_chain_destroy(struct nft_chain *chain)
if (chain->flags & NFT_BASE_CHAIN) {
module_put(nft_base_chain(chain)->type->owner);
free_percpu(nft_base_chain(chain)->stats);
+ kfree(chain->name);
kfree(nft_base_chain(chain));
} else {
+ kfree(chain->name);
kfree(chain);
}
}
@@ -1405,8 +1407,13 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
nft_trans_chain_policy(trans) = -1;
if (nla[NFTA_CHAIN_HANDLE] && name) {
- nla_strlcpy(nft_trans_chain_name(trans), name,
- NFT_CHAIN_MAXNAMELEN);
+ nft_trans_chain_name(trans) =
+ nla_strdup(name, GFP_KERNEL);
+ if (!nft_trans_chain_name(trans)) {
+ kfree(trans);
+ free_percpu(stats);
+ return -ENOMEM;
+ }
}
list_add_tail(&trans->list, &net->nft.commit_list);
return 0;
@@ -1478,7 +1485,11 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
INIT_LIST_HEAD(&chain->rules);
chain->handle = nf_tables_alloc_handle(table);
chain->table = table;
- nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
+ chain->name = nla_strdup(name, GFP_KERNEL);
+ if (!chain->name) {
+ err = -ENOMEM;
+ goto err1;
+ }
err = nf_tables_register_hooks(table, chain, afi->nops);
if (err < 0)
@@ -1906,7 +1917,7 @@ err:
struct nft_rule_dump_ctx {
char *table;
- char chain[NFT_CHAIN_MAXNAMELEN];
+ char *chain;
};
static int nf_tables_dump_rules(struct sk_buff *skb,
@@ -1974,6 +1985,7 @@ static int nf_tables_dump_rules_done(struct netlink_callback *cb)
if (ctx) {
kfree(ctx->table);
+ kfree(ctx->chain);
kfree(ctx);
}
return 0;
@@ -2015,9 +2027,15 @@ static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
return -ENOMEM;
}
}
- if (nla[NFTA_RULE_CHAIN])
- nla_strlcpy(ctx->chain, nla[NFTA_RULE_CHAIN],
- sizeof(ctx->chain));
+ if (nla[NFTA_RULE_CHAIN]) {
+ ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
+ GFP_KERNEL);
+ if (!ctx->chain) {
+ kfree(ctx->table);
+ kfree(ctx);
+ return -ENOMEM;
+ }
+ }
c.data = ctx;
}
@@ -4043,7 +4061,7 @@ static void nft_chain_commit_update(struct nft_trans *trans)
{
struct nft_base_chain *basechain;
- if (nft_trans_chain_name(trans)[0])
+ if (nft_trans_chain_name(trans))
strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans));
if (!(trans->ctx.chain->flags & NFT_BASE_CHAIN))
diff --git a/net/netfilter/nf_tables_trace.c b/net/netfilter/nf_tables_trace.c
index 2c4cbbd66ea9..bdcd490fc034 100644
--- a/net/netfilter/nf_tables_trace.c
+++ b/net/netfilter/nf_tables_trace.c
@@ -160,6 +160,27 @@ static int nf_trace_fill_rule_info(struct sk_buff *nlskb,
NFTA_TRACE_PAD);
}
+static bool nft_trace_have_verdict_chain(struct nft_traceinfo *info)
+{
+ switch (info->type) {
+ case NFT_TRACETYPE_RETURN:
+ case NFT_TRACETYPE_RULE:
+ break;
+ default:
+ return false;
+ }
+
+ switch (info->verdict->code) {
+ case NFT_JUMP:
+ case NFT_GOTO:
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
void nft_trace_notify(struct nft_traceinfo *info)
{
const struct nft_pktinfo *pkt = info->pkt;
@@ -174,12 +195,11 @@ void nft_trace_notify(struct nft_traceinfo *info)
size = nlmsg_total_size(sizeof(struct nfgenmsg)) +
nla_total_size(strlen(info->chain->table->name)) +
- nla_total_size(NFT_CHAIN_MAXNAMELEN) +
+ nla_total_size(strlen(info->chain->name)) +
nla_total_size_64bit(sizeof(__be64)) + /* rule handle */
nla_total_size(sizeof(__be32)) + /* trace type */
nla_total_size(0) + /* VERDICT, nested */
nla_total_size(sizeof(u32)) + /* verdict code */
- nla_total_size(NFT_CHAIN_MAXNAMELEN) + /* jump target */
nla_total_size(sizeof(u32)) + /* id */
nla_total_size(NFT_TRACETYPE_LL_HSIZE) +
nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) +
@@ -192,6 +212,9 @@ void nft_trace_notify(struct nft_traceinfo *info)
nla_total_size(sizeof(u32)) + /* nfproto */
nla_total_size(sizeof(u32)); /* policy */
+ if (nft_trace_have_verdict_chain(info))
+ size += nla_total_size(strlen(info->verdict->chain->name)); /* jump target */
+
skb = nlmsg_new(size, GFP_ATOMIC);
if (!skb)
return;
--
2.30.2
More information about the Devel
mailing list