diff options
-rw-r--r-- | include/net/netfilter/nf_tables.h | 4 | ||||
-rw-r--r-- | net/netfilter/nf_tables_api.c | 11 | ||||
-rw-r--r-- | net/netfilter/nft_immediate.c | 3 | ||||
-rw-r--r-- | net/netfilter/nft_lookup.c | 13 |
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 | */ |
155 | struct nft_ctx { | 156 | struct 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 | ||
174 | static int nft_lookup_validate(const struct nft_ctx *ctx, | 183 | static int nft_lookup_validate(const struct nft_ctx *ctx, |