netfilter: nf_tables_offload: avoid excessive stack usage
authorArnd Bergmann <arnd@arndb.de>
Fri, 6 Sep 2019 15:12:30 +0000 (17:12 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 8 Sep 2019 16:16:59 +0000 (18:16 +0200)
The nft_offload_ctx structure is much too large to put on the
stack:

net/netfilter/nf_tables_offload.c:31:23: error: stack frame size of 1200 bytes in function 'nft_flow_rule_create' [-Werror,-Wframe-larger-than=]

Use dynamic allocation here, as we do elsewhere in the same
function.

Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_offload.c

index 3c2725ade61b208170b0d897d7f003046fe52a7f..fabe2997188b21e60c4181567dbed4ebb65fcece 100644 (file)
@@ -30,11 +30,7 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions)
 
 struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule)
 {
-       struct nft_offload_ctx ctx = {
-               .dep    = {
-                       .type   = NFT_OFFLOAD_DEP_UNSPEC,
-               },
-       };
+       struct nft_offload_ctx *ctx;
        struct nft_flow_rule *flow;
        int num_actions = 0, err;
        struct nft_expr *expr;
@@ -52,21 +48,31 @@ struct nft_flow_rule *nft_flow_rule_create(const struct nft_rule *rule)
                return ERR_PTR(-ENOMEM);
 
        expr = nft_expr_first(rule);
+
+       ctx = kzalloc(sizeof(struct nft_offload_ctx), GFP_KERNEL);
+       if (!ctx) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+       ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
+
        while (expr->ops && expr != nft_expr_last(rule)) {
                if (!expr->ops->offload) {
                        err = -EOPNOTSUPP;
                        goto err_out;
                }
-               err = expr->ops->offload(&ctx, flow, expr);
+               err = expr->ops->offload(ctx, flow, expr);
                if (err < 0)
                        goto err_out;
 
                expr = nft_expr_next(expr);
        }
-       flow->proto = ctx.dep.l3num;
+       flow->proto = ctx->dep.l3num;
+       kfree(ctx);
 
        return flow;
 err_out:
+       kfree(ctx);
        nft_flow_rule_destroy(flow);
 
        return ERR_PTR(err);