The default include path is searched for files before include paths specified via -I/--include. Search for default include path after user-specified include paths to allow users for test nftables configurations spanning multiple files without overwriting the globally installed ones. See: https://patchwork.ozlabs.org/project/netfilter-devel/patch/20220627222304.93139-1-dxld@xxxxxxxxxxxxx/ Reported-by: Daniel Gröber <dxld@xxxxxxxxxxxxx> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- src/libnftables.c | 1 - src/scanner.l | 63 ++++++++++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/libnftables.c b/src/libnftables.c index 40e37bdf8c06..af4734c05004 100644 --- a/src/libnftables.c +++ b/src/libnftables.c @@ -202,7 +202,6 @@ struct nft_ctx *nft_ctx_new(uint32_t flags) nft_init(ctx); ctx->state = xzalloc(sizeof(struct parser_state)); - nft_ctx_add_include_path(ctx, DEFAULT_INCLUDE_PATH); ctx->parser_max_errors = 10; cache_init(&ctx->cache.table_cache); ctx->top_scope = scope_alloc(); diff --git a/src/scanner.l b/src/scanner.l index 96c505bcdd48..c825fa79cfd9 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -1175,39 +1175,58 @@ static bool search_in_include_path(const char *filename) filename[0] != '/'); } +static int include_path_glob(struct nft_ctx *nft, void *scanner, + const char *include_path, const char *filename, + const struct location *loc) +{ + struct parser_state *state = yyget_extra(scanner); + struct error_record *erec; + char buf[PATH_MAX]; + int ret; + + ret = snprintf(buf, sizeof(buf), "%s/%s", include_path, filename); + if (ret < 0 || ret >= PATH_MAX) { + erec = error(loc, "Too long file path \"%s/%s\"\n", + include_path, filename); + erec_queue(erec, state->msgs); + return -1; + } + + ret = include_glob(nft, scanner, buf, loc); + + /* error was already handled */ + if (ret == -1) + return -1; + /* no wildcards and file was processed: break early. */ + if (ret == 0) + return 0; + + /* else 1 (no wildcards) or 2 (wildcards): keep + * searching. + */ + return ret; +} + int scanner_include_file(struct nft_ctx *nft, void *scanner, const char *filename, const struct location *loc) { struct parser_state *state = yyget_extra(scanner); struct error_record *erec; - char buf[PATH_MAX]; unsigned int i; int ret = -1; if (search_in_include_path(filename)) { for (i = 0; i < nft->num_include_paths; i++) { - ret = snprintf(buf, sizeof(buf), "%s/%s", - nft->include_paths[i], filename); - if (ret < 0 || ret >= PATH_MAX) { - erec = error(loc, "Too long file path \"%s/%s\"\n", - nft->include_paths[i], filename); - erec_queue(erec, state->msgs); - return -1; - } - - ret = include_glob(nft, scanner, buf, loc); - - /* error was already handled */ - if (ret == -1) - return -1; - /* no wildcards and file was processed: break early. */ - if (ret == 0) - return 0; - - /* else 1 (no wildcards) or 2 (wildcards): keep - * searching. - */ + ret = include_path_glob(nft, scanner, + nft->include_paths[i], + filename, loc); + if (ret <= 0) + return ret; } + ret = include_path_glob(nft, scanner, DEFAULT_INCLUDE_PATH, + filename, loc); + if (ret <= 0) + return ret; } else { /* an absolute path (starts with '/') */ ret = include_glob(nft, scanner, filename, loc); -- 2.30.2