aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netfilter/nf_tables.h4
-rw-r--r--net/netfilter/nf_tables_api.c11
-rw-r--r--net/netfilter/nft_immediate.c3
-rw-r--r--net/netfilter/nft_lookup.c13
4 files changed, 20 insertions, 11 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 08c005ce56e9..4e82a4c49912 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -150,6 +150,7 @@ static inline void nft_data_debug(const struct nft_data *data)
150 * @portid: netlink portID of the original message 150 * @portid: netlink portID of the original message
151 * @seq: netlink sequence number 151 * @seq: netlink sequence number
152 * @family: protocol family 152 * @family: protocol family
153 * @level: depth of the chains
153 * @report: notify via unicast netlink message 154 * @report: notify via unicast netlink message
154 */ 155 */
155struct nft_ctx { 156struct nft_ctx {
@@ -160,6 +161,7 @@ struct nft_ctx {
160 u32 portid; 161 u32 portid;
161 u32 seq; 162 u32 seq;
162 u8 family; 163 u8 family;
164 u8 level;
163 bool report; 165 bool report;
164}; 166};
165 167
@@ -865,7 +867,6 @@ enum nft_chain_flags {
865 * @table: table that this chain belongs to 867 * @table: table that this chain belongs to
866 * @handle: chain handle 868 * @handle: chain handle
867 * @use: number of jump references to this chain 869 * @use: number of jump references to this chain
868 * @level: length of longest path to this chain
869 * @flags: bitmask of enum nft_chain_flags 870 * @flags: bitmask of enum nft_chain_flags
870 * @name: name of the chain 871 * @name: name of the chain
871 */ 872 */
@@ -878,7 +879,6 @@ struct nft_chain {
878 struct nft_table *table; 879 struct nft_table *table;
879 u64 handle; 880 u64 handle;
880 u32 use; 881 u32 use;
881 u16 level;
882 u8 flags:6, 882 u8 flags:6,
883 genmask:2; 883 genmask:2;
884 char *name; 884 char *name;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 896d4a36081d..d41fa2c82f14 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -75,6 +75,7 @@ static void nft_ctx_init(struct nft_ctx *ctx,
75{ 75{
76 ctx->net = net; 76 ctx->net = net;
77 ctx->family = family; 77 ctx->family = family;
78 ctx->level = 0;
78 ctx->table = table; 79 ctx->table = table;
79 ctx->chain = chain; 80 ctx->chain = chain;
80 ctx->nla = nla; 81 ctx->nla = nla;
@@ -2384,6 +2385,9 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
2384 struct nft_rule *rule; 2385 struct nft_rule *rule;
2385 int err; 2386 int err;
2386 2387
2388 if (ctx->level == NFT_JUMP_STACK_SIZE)
2389 return -EMLINK;
2390
2387 list_for_each_entry(rule, &chain->rules, list) { 2391 list_for_each_entry(rule, &chain->rules, list) {
2388 if (!nft_is_active_next(ctx->net, rule)) 2392 if (!nft_is_active_next(ctx->net, rule))
2389 continue; 2393 continue;
@@ -6837,13 +6841,6 @@ int nft_validate_register_store(const struct nft_ctx *ctx,
6837 err = nf_tables_check_loops(ctx, data->verdict.chain); 6841 err = nf_tables_check_loops(ctx, data->verdict.chain);
6838 if (err < 0) 6842 if (err < 0)
6839 return err; 6843 return err;
6840
6841 if (ctx->chain->level + 1 >
6842 data->verdict.chain->level) {
6843 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
6844 return -EMLINK;
6845 data->verdict.chain->level = ctx->chain->level + 1;
6846 }
6847 } 6844 }
6848 6845
6849 return 0; 6846 return 0;
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 15adf8ca82c3..0777a93211e2 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -98,6 +98,7 @@ static int nft_immediate_validate(const struct nft_ctx *ctx,
98 const struct nft_data **d) 98 const struct nft_data **d)
99{ 99{
100 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 100 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
101 struct nft_ctx *pctx = (struct nft_ctx *)ctx;
101 const struct nft_data *data; 102 const struct nft_data *data;
102 int err; 103 int err;
103 104
@@ -109,9 +110,11 @@ static int nft_immediate_validate(const struct nft_ctx *ctx,
109 switch (data->verdict.code) { 110 switch (data->verdict.code) {
110 case NFT_JUMP: 111 case NFT_JUMP:
111 case NFT_GOTO: 112 case NFT_GOTO:
113 pctx->level++;
112 err = nft_chain_validate(ctx, data->verdict.chain); 114 err = nft_chain_validate(ctx, data->verdict.chain);
113 if (err < 0) 115 if (err < 0)
114 return err; 116 return err;
117 pctx->level--;
115 break; 118 break;
116 default: 119 default:
117 break; 120 break;
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index 42e6fadf1417..c2a1d84cdfc4 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -155,7 +155,9 @@ static int nft_lookup_validate_setelem(const struct nft_ctx *ctx,
155 struct nft_set_elem *elem) 155 struct nft_set_elem *elem)
156{ 156{
157 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); 157 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
158 struct nft_ctx *pctx = (struct nft_ctx *)ctx;
158 const struct nft_data *data; 159 const struct nft_data *data;
160 int err;
159 161
160 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && 162 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
161 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END) 163 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
@@ -165,10 +167,17 @@ static int nft_lookup_validate_setelem(const struct nft_ctx *ctx,
165 switch (data->verdict.code) { 167 switch (data->verdict.code) {
166 case NFT_JUMP: 168 case NFT_JUMP:
167 case NFT_GOTO: 169 case NFT_GOTO:
168 return nft_chain_validate(ctx, data->verdict.chain); 170 pctx->level++;
171 err = nft_chain_validate(ctx, data->verdict.chain);
172 if (err < 0)
173 return err;
174 pctx->level--;
175 break;
169 default: 176 default:
170 return 0; 177 break;
171 } 178 }
179
180 return 0;
172} 181}
173 182
174static int nft_lookup_validate(const struct nft_ctx *ctx, 183static int nft_lookup_validate(const struct nft_ctx *ctx,