]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
libnftables: Move scanner object into struct nft_ctx
authorPhil Sutter <phil@nwl.cc>
Tue, 15 May 2018 09:37:56 +0000 (11:37 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 15 May 2018 10:16:42 +0000 (12:16 +0200)
The initial approach of keeping as much of lex/yacc-specific data
local to the relevant parsing routines was flawed in that input
descriptors which parsed commands' location information points at were
freed after parsing (in scanner_destroy()) although they were required
later for error reporting in case a command was rejected by the kernel.

To overcome this, keep the scanner pointer in struct nft_ctx so that it
can be kept in place until kernel communication has finished.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/nftables.h
src/libnftables.c

index f88d0530a963ec8ad0ce1dc1326ffe2d7197b3db..5e209b417d5a5d1582a9def7293c4ed4f3798aa3 100644 (file)
@@ -52,6 +52,7 @@ struct nft_ctx {
        struct nft_cache        cache;
        uint32_t                flags;
        struct parser_state     *state;
+       void                    *scanner;
 };
 
 enum nftables_exit_codes {
index d9b2c0810988e31341d2ae7276db6eca292903f2..5bc7ba0d210ab0f6ef31e4605927a2eff83a385b 100644 (file)
@@ -398,24 +398,20 @@ static int nft_parse_bison_buffer(struct nft_ctx *nft, char *buf, size_t buflen,
                                  struct list_head *msgs, struct list_head *cmds)
 {
        struct cmd *cmd;
-       void *scanner;
        int ret;
 
        parser_init(nft, nft->state, msgs, cmds);
-       scanner = scanner_init(nft->state);
-       scanner_push_buffer(scanner, &indesc_cmdline, buf);
+       nft->scanner = scanner_init(nft->state);
+       scanner_push_buffer(nft->scanner, &indesc_cmdline, buf);
+
+       ret = nft_parse(nft, nft->scanner, nft->state);
+       if (ret != 0 || nft->state->nerrs > 0)
+               return -1;
 
-       ret = nft_parse(nft, scanner, nft->state);
-       if (ret != 0 || nft->state->nerrs > 0) {
-               ret = -1;
-               goto err;
-       }
        list_for_each_entry(cmd, cmds, list)
                nft_cmd_expand(cmd);
 
-err:
-       scanner_destroy(scanner);
-       return ret;
+       return 0;
 }
 
 static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
@@ -427,22 +423,17 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename,
 
        parser_init(nft, nft->state, msgs, cmds);
        scanner = scanner_init(nft->state);
-       if (scanner_read_file(scanner, filename, &internal_location) < 0) {
-               ret = -1;
-               goto err;
-       }
+       if (scanner_read_file(scanner, filename, &internal_location) < 0)
+               return -1;
 
        ret = nft_parse(nft, scanner, nft->state);
-       if (ret != 0 || nft->state->nerrs > 0) {
-               ret = -1;
-               goto err;
-       }
+       if (ret != 0 || nft->state->nerrs > 0)
+               return -1;
+
        list_for_each_entry(cmd, cmds, list)
                nft_cmd_expand(cmd);
 
-err:
-       scanner_destroy(scanner);
-       return ret;
+       return 0;
 }
 
 int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen)
@@ -474,6 +465,10 @@ err:
        }
        erec_print_list(&nft->output, &msgs, nft->debug_mask);
        iface_cache_release();
+       if (nft->scanner) {
+               scanner_destroy(nft->scanner);
+               nft->scanner = NULL;
+       }
        free(nlbuf);
 
        return rc;
@@ -511,6 +506,10 @@ err:
        }
        erec_print_list(&nft->output, &msgs, nft->debug_mask);
        iface_cache_release();
+       if (nft->scanner) {
+               scanner_destroy(nft->scanner);
+               nft->scanner = NULL;
+       }
 
        return rc;
 }