History

netfilter: nf_tables: Allow chain name of up to 255 chars

Same conversion as for table names, use NFT_NAME_MAXLEN as upper boundary as well.

Phil Sutter committed 9 years ago

Commit b7263e01 parent e46abbc4 files · +54 −13Browse files

Unified · Split

4 files
  1. include/net/netfilter/nf_tables.h +2 −2
  2. include/uapi/linux/netfilter/nf_tables.h +1 −1
  3. net/netfilter/nf_tables_api.c +26 −8
  4. net/netfilter/nf_tables_trace.c +25 −2
include/net/netfilter/nf_tables.h+2−2
@@ -859,7 +859,7 @@ struct nft_chain { · 858 unmodified lines
859859 u16 level;
860860 u8 flags:6,
861861 genmask:2;
862− char name[NFT_CHAIN_MAXNAMELEN];
862+ char *name;
863863 };
864864
865865 enum nft_chain_type {
@@ -1272,7 +1272,7 @@ struct nft_trans_set { · 406 unmodified lines
12721272
12731273 struct nft_trans_chain {
12741274 bool update;
1275− char name[NFT_CHAIN_MAXNAMELEN];
1275+ char *name;
12761276 struct nft_stats __percpu *stats;
12771277 u8 policy;
12781278 };
include/uapi/linux/netfilter/nf_tables.h+1−1
@@ -3,7 +3,7 @@ · 2 unmodified lines
33
44 #define NFT_NAME_MAXLEN 256
55 #define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN
6−#define NFT_CHAIN_MAXNAMELEN 32
6+#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN
77 #define NFT_SET_MAXNAMELEN 32
88 #define NFT_OBJ_MAXNAMELEN 32
99 #define NFT_USERDATA_MAXLEN 256
net/netfilter/nf_tables_api.c+26−8
@@ -1250,8 +1250,10 @@ static void nf_tables_chain_destroy(struct nft_chain *chain) · 1249 unmodified lines
12501250 static_branch_dec(&nft_counters_enabled);
12511251 if (basechain->ops[0].dev != NULL)
12521252 dev_put(basechain->ops[0].dev);
1253+ kfree(chain->name);
12531254 kfree(basechain);
12541255 } else {
1256+ kfree(chain->name);
12551257 kfree(chain);
12561258 }
12571259 }
@@ -1476,8 +1478,13 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, · 218 unmodified lines
14761478 nft_trans_chain_policy(trans) = -1;
14771479
14781480 if (nla[NFTA_CHAIN_HANDLE] && name) {
1479− nla_strlcpy(nft_trans_chain_name(trans), name,
1480− NFT_CHAIN_MAXNAMELEN);
1481+ nft_trans_chain_name(trans) =
1482+ nla_strdup(name, GFP_KERNEL);
1483+ if (!nft_trans_chain_name(trans)) {
1484+ kfree(trans);
1485+ free_percpu(stats);
1486+ return -ENOMEM;
1487+ }
14811488 }
14821489 list_add_tail(&trans->list, &net->nft.commit_list);
14831490 return 0;
@@ -1544,7 +1551,11 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, · 60 unmodified lines
15441551 INIT_LIST_HEAD(&chain->rules);
15451552 chain->handle = nf_tables_alloc_handle(table);
15461553 chain->table = table;
1547− nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
1554+ chain->name = nla_strdup(name, GFP_KERNEL);
1555+ if (!chain->name) {
1556+ err = -ENOMEM;
1557+ goto err1;
1558+ }
15481559
15491560 err = nf_tables_register_hooks(net, table, chain, afi->nops);
15501561 if (err < 0)
@@ -1979,7 +1990,7 @@ err: · 428 unmodified lines
19791990
19801991 struct nft_rule_dump_ctx {
19811992 char *table;
1982− char chain[NFT_CHAIN_MAXNAMELEN];
1993+ char *chain;
19831994 };
19841995
19851996 static int nf_tables_dump_rules(struct sk_buff *skb,
@@ -2047,6 +2058,7 @@ static int nf_tables_dump_rules_done(struct netlink_callback *cb) · 61 unmodified lines
20472058
20482059 if (ctx) {
20492060 kfree(ctx->table);
2061+ kfree(ctx->chain);
20502062 kfree(ctx);
20512063 }
20522064 return 0;
@@ -2088,9 +2100,15 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, · 35 unmodified lines
20882100 return -ENOMEM;
20892101 }
20902102 }
2091− if (nla[NFTA_RULE_CHAIN])
2092− nla_strlcpy(ctx->chain, nla[NFTA_RULE_CHAIN],
2093− sizeof(ctx->chain));
2103+ if (nla[NFTA_RULE_CHAIN]) {
2104+ ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
2105+ GFP_KERNEL);
2106+ if (!ctx->chain) {
2107+ kfree(ctx->table);
2108+ kfree(ctx);
2109+ return -ENOMEM;
2110+ }
2111+ }
20942112 c.data = ctx;
20952113 }
20962114
@@ -4863,7 +4881,7 @@ static void nft_chain_commit_update(struct nft_trans *trans) · 2766 unmodified lines
48634881 {
48644882 struct nft_base_chain *basechain;
48654883
4866− if (nft_trans_chain_name(trans)[0])
4884+ if (nft_trans_chain_name(trans))
48674885 strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans));
48684886
48694887 if (!nft_is_base_chain(trans->ctx.chain))
net/netfilter/nf_tables_trace.c+25−2
@@ -162,6 +162,27 @@ static int nf_trace_fill_rule_info(struct sk_buff *nlskb, · 161 unmodified lines
162162 NFTA_TRACE_PAD);
163163 }
164164
165+static bool nft_trace_have_verdict_chain(struct nft_traceinfo *info)
166+{
167+ switch (info->type) {
168+ case NFT_TRACETYPE_RETURN:
169+ case NFT_TRACETYPE_RULE:
170+ break;
171+ default:
172+ return false;
173+ }
174+
175+ switch (info->verdict->code) {
176+ case NFT_JUMP:
177+ case NFT_GOTO:
178+ break;
179+ default:
180+ return false;
181+ }
182+
183+ return true;
184+}
185+
165186 void nft_trace_notify(struct nft_traceinfo *info)
166187 {
167188 const struct nft_pktinfo *pkt = info->pkt;
@@ -176,12 +197,11 @@ void nft_trace_notify(struct nft_traceinfo *info) · 8 unmodified lines
176197
177198 size = nlmsg_total_size(sizeof(struct nfgenmsg)) +
178199 nla_total_size(strlen(info->chain->table->name)) +
179− nla_total_size(NFT_CHAIN_MAXNAMELEN) +
200+ nla_total_size(strlen(info->chain->name)) +
180201 nla_total_size_64bit(sizeof(__be64)) + /* rule handle */
181202 nla_total_size(sizeof(__be32)) + /* trace type */
182203 nla_total_size(0) + /* VERDICT, nested */
183204 nla_total_size(sizeof(u32)) + /* verdict code */
184− nla_total_size(NFT_CHAIN_MAXNAMELEN) + /* jump target */
185205 nla_total_size(sizeof(u32)) + /* id */
186206 nla_total_size(NFT_TRACETYPE_LL_HSIZE) +
187207 nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) +
@@ -194,6 +214,9 @@ void nft_trace_notify(struct nft_traceinfo *info) · 6 unmodified lines
194214 nla_total_size(sizeof(u32)) + /* nfproto */
195215 nla_total_size(sizeof(u32)); /* policy */
196216
217+ if (nft_trace_have_verdict_chain(info))
218+ size += nla_total_size(strlen(info->verdict->chain->name)); /* jump target */
219+
197220 skb = nlmsg_new(size, GFP_ATOMIC);
198221 if (!skb)
199222 return;