Same conversion as for table names, use NFT_NAME_MAXLEN as upper boundary as well.
Unified · Split
| @@ -859,7 +859,7 @@ struct nft_chain { · 858 unmodified lines | ||
| 859 | 859 | u16 level; |
| 860 | 860 | u8 flags:6, |
| 861 | 861 | genmask:2; |
| 862 | − char name[NFT_CHAIN_MAXNAMELEN]; | |
| 862 | + char *name; | |
| 863 | 863 | }; |
| 864 | 864 | |
| 865 | 865 | enum nft_chain_type { |
| @@ -1272,7 +1272,7 @@ struct nft_trans_set { · 406 unmodified lines | ||
| 1272 | 1272 | |
| 1273 | 1273 | struct nft_trans_chain { |
| 1274 | 1274 | bool update; |
| 1275 | − char name[NFT_CHAIN_MAXNAMELEN]; | |
| 1275 | + char *name; | |
| 1276 | 1276 | struct nft_stats __percpu *stats; |
| 1277 | 1277 | u8 policy; |
| 1278 | 1278 | }; |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #define NFT_NAME_MAXLEN 256 |
| 5 | 5 | #define NFT_TABLE_MAXNAMELEN NFT_NAME_MAXLEN |
| 6 | −#define NFT_CHAIN_MAXNAMELEN 32 | |
| 6 | +#define NFT_CHAIN_MAXNAMELEN NFT_NAME_MAXLEN | |
| 7 | 7 | #define NFT_SET_MAXNAMELEN 32 |
| 8 | 8 | #define NFT_OBJ_MAXNAMELEN 32 |
| 9 | 9 | #define NFT_USERDATA_MAXLEN 256 |
| @@ -1250,8 +1250,10 @@ static void nf_tables_chain_destroy(struct nft_chain *chain) · 1249 unmodified lines | ||
| 1250 | 1250 | static_branch_dec(&nft_counters_enabled); |
| 1251 | 1251 | if (basechain->ops[0].dev != NULL) |
| 1252 | 1252 | dev_put(basechain->ops[0].dev); |
| 1253 | + kfree(chain->name); | |
| 1253 | 1254 | kfree(basechain); |
| 1254 | 1255 | } else { |
| 1256 | + kfree(chain->name); | |
| 1255 | 1257 | kfree(chain); |
| 1256 | 1258 | } |
| 1257 | 1259 | } |
| @@ -1476,8 +1478,13 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, · 218 unmodified lines | ||
| 1476 | 1478 | nft_trans_chain_policy(trans) = -1; |
| 1477 | 1479 | |
| 1478 | 1480 | 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 | + } | |
| 1481 | 1488 | } |
| 1482 | 1489 | list_add_tail(&trans->list, &net->nft.commit_list); |
| 1483 | 1490 | return 0; |
| @@ -1544,7 +1551,11 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, · 60 unmodified lines | ||
| 1544 | 1551 | INIT_LIST_HEAD(&chain->rules); |
| 1545 | 1552 | chain->handle = nf_tables_alloc_handle(table); |
| 1546 | 1553 | 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 | + } | |
| 1548 | 1559 | |
| 1549 | 1560 | err = nf_tables_register_hooks(net, table, chain, afi->nops); |
| 1550 | 1561 | if (err < 0) |
| @@ -1979,7 +1990,7 @@ err: · 428 unmodified lines | ||
| 1979 | 1990 | |
| 1980 | 1991 | struct nft_rule_dump_ctx { |
| 1981 | 1992 | char *table; |
| 1982 | − char chain[NFT_CHAIN_MAXNAMELEN]; | |
| 1993 | + char *chain; | |
| 1983 | 1994 | }; |
| 1984 | 1995 | |
| 1985 | 1996 | 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 | ||
| 2047 | 2058 | |
| 2048 | 2059 | if (ctx) { |
| 2049 | 2060 | kfree(ctx->table); |
| 2061 | + kfree(ctx->chain); | |
| 2050 | 2062 | kfree(ctx); |
| 2051 | 2063 | } |
| 2052 | 2064 | return 0; |
| @@ -2088,9 +2100,15 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk, · 35 unmodified lines | ||
| 2088 | 2100 | return -ENOMEM; |
| 2089 | 2101 | } |
| 2090 | 2102 | } |
| 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 | + } | |
| 2094 | 2112 | c.data = ctx; |
| 2095 | 2113 | } |
| 2096 | 2114 | |
| @@ -4863,7 +4881,7 @@ static void nft_chain_commit_update(struct nft_trans *trans) · 2766 unmodified lines | ||
| 4863 | 4881 | { |
| 4864 | 4882 | struct nft_base_chain *basechain; |
| 4865 | 4883 | |
| 4866 | − if (nft_trans_chain_name(trans)[0]) | |
| 4884 | + if (nft_trans_chain_name(trans)) | |
| 4867 | 4885 | strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans)); |
| 4868 | 4886 | |
| 4869 | 4887 | if (!nft_is_base_chain(trans->ctx.chain)) |
| @@ -162,6 +162,27 @@ static int nf_trace_fill_rule_info(struct sk_buff *nlskb, · 161 unmodified lines | ||
| 162 | 162 | NFTA_TRACE_PAD); |
| 163 | 163 | } |
| 164 | 164 | |
| 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 | + | |
| 165 | 186 | void nft_trace_notify(struct nft_traceinfo *info) |
| 166 | 187 | { |
| 167 | 188 | const struct nft_pktinfo *pkt = info->pkt; |
| @@ -176,12 +197,11 @@ void nft_trace_notify(struct nft_traceinfo *info) · 8 unmodified lines | ||
| 176 | 197 | |
| 177 | 198 | size = nlmsg_total_size(sizeof(struct nfgenmsg)) + |
| 178 | 199 | nla_total_size(strlen(info->chain->table->name)) + |
| 179 | − nla_total_size(NFT_CHAIN_MAXNAMELEN) + | |
| 200 | + nla_total_size(strlen(info->chain->name)) + | |
| 180 | 201 | nla_total_size_64bit(sizeof(__be64)) + /* rule handle */ |
| 181 | 202 | nla_total_size(sizeof(__be32)) + /* trace type */ |
| 182 | 203 | nla_total_size(0) + /* VERDICT, nested */ |
| 183 | 204 | nla_total_size(sizeof(u32)) + /* verdict code */ |
| 184 | − nla_total_size(NFT_CHAIN_MAXNAMELEN) + /* jump target */ | |
| 185 | 205 | nla_total_size(sizeof(u32)) + /* id */ |
| 186 | 206 | nla_total_size(NFT_TRACETYPE_LL_HSIZE) + |
| 187 | 207 | nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) + |
| @@ -194,6 +214,9 @@ void nft_trace_notify(struct nft_traceinfo *info) · 6 unmodified lines | ||
| 194 | 214 | nla_total_size(sizeof(u32)) + /* nfproto */ |
| 195 | 215 | nla_total_size(sizeof(u32)); /* policy */ |
| 196 | 216 | |
| 217 | + if (nft_trace_have_verdict_chain(info)) | |
| 218 | + size += nla_total_size(strlen(info->verdict->chain->name)); /* jump target */ | |
| 219 | + | |
| 197 | 220 | skb = nlmsg_new(size, GFP_ATOMIC); |
| 198 | 221 | if (!skb) |
| 199 | 222 | return; |