Legacy ebtables-save does not use a policy string of '-' to denote user-defined chains but instead lists them with a policy of ACCEPT. In order to use ebtables_restore_parse() for ebtables-save implementation, make use of builtin table definitions to decide whether a given chain is a builtin one or not. Signed-off-by: Phil Sutter <phil@xxxxxx> --- Changes since v1: - Fix potential null-pointer dereference with malformed input --- iptables/nft.c | 4 ++-- iptables/nft.h | 2 ++ iptables/xtables-restore.c | 28 +++++++++++++++++----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/iptables/nft.c b/iptables/nft.c index ea58495be24aa..b893859d28660 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -630,7 +630,7 @@ static void nft_chain_builtin_add(struct nft_handle *h, } /* find if built-in table already exists */ -static struct builtin_table * +struct builtin_table * nft_table_builtin_find(struct nft_handle *h, const char *table) { int i; @@ -651,7 +651,7 @@ nft_table_builtin_find(struct nft_handle *h, const char *table) } /* find if built-in chain already exists */ -static struct builtin_chain * +struct builtin_chain * nft_chain_builtin_find(struct builtin_table *t, const char *chain) { int i; diff --git a/iptables/nft.h b/iptables/nft.h index 5febb9f9366e1..942cb6a06e5e5 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -68,6 +68,7 @@ bool nft_table_find(struct nft_handle *h, const char *tablename); int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list); int nft_table_flush(struct nft_handle *h, const char *table); void nft_table_new(struct nft_handle *h, const char *table); +struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table); /* * Operations with chains. @@ -84,6 +85,7 @@ int nft_chain_user_flush(struct nft_handle *h, struct nftnl_chain_list *list, const char *chain, const char *table); int nft_chain_user_rename(struct nft_handle *h, const char *chain, const char *table, const char *newname); int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose); +struct builtin_chain *nft_chain_builtin_find(struct builtin_table *t, const char *chain); /* * Operations with rule-set. diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 4e46b625d02ee..9a014ccd2baec 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -106,7 +106,7 @@ void xtables_restore_parse(struct nft_handle *h, { char buffer[10240]; int in_table = 0; - char curtable[XT_TABLE_MAXNAMELEN + 1]; + struct builtin_table *curtable = NULL; const struct xtc_ops *ops = &xtc_ops; struct nftnl_chain_list *chain_list = NULL; @@ -156,8 +156,11 @@ void xtables_restore_parse(struct nft_handle *h, xt_params->program_name, line); exit(1); } - strncpy(curtable, table, XT_TABLE_MAXNAMELEN); - curtable[XT_TABLE_MAXNAMELEN] = '\0'; + curtable = nft_table_builtin_find(h, table); + if (!curtable) + xtables_error(PARAMETER_PROBLEM, + "%s: line %u table name '%s' invalid\n", + xt_params->program_name, line, table); if (p->tablename && (strcmp(p->tablename, table) != 0)) continue; @@ -191,7 +194,7 @@ void xtables_restore_parse(struct nft_handle *h, if (noflush == 0) { if (cb->chain_del) - cb->chain_del(chain_list, curtable, + cb->chain_del(chain_list, curtable->name, chain); } else { /* Apparently -n still flushes existing user @@ -200,7 +203,7 @@ void xtables_restore_parse(struct nft_handle *h, */ if (cb->chain_user_flush) cb->chain_user_flush(h, chain_list, - curtable, chain); + curtable->name, chain); } if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) @@ -218,7 +221,7 @@ void xtables_restore_parse(struct nft_handle *h, exit(1); } - if (strcmp(policy, "-") != 0) { + if (nft_chain_builtin_find(curtable, chain)) { if (counters) { char *ctrs; ctrs = strtok(NULL, " \t\n"); @@ -230,7 +233,8 @@ void xtables_restore_parse(struct nft_handle *h, } if (cb->chain_set && - cb->chain_set(h, curtable, chain, policy, &count) < 0) { + cb->chain_set(h, curtable->name, + chain, policy, &count) < 0) { xtables_error(OTHER_PROBLEM, "Can't set policy `%s'" " on `%s' line %u: %s\n", @@ -243,7 +247,8 @@ void xtables_restore_parse(struct nft_handle *h, } else { if (cb->chain_user_add && - cb->chain_user_add(h, chain, curtable) < 0) { + cb->chain_user_add(h, chain, + curtable->name) < 0) { if (errno == EEXIST) continue; @@ -294,7 +299,7 @@ void xtables_restore_parse(struct nft_handle *h, add_argv(argv[0], 0); add_argv("-t", 0); - add_argv(curtable, 0); + add_argv(curtable->name, 0); if (counters && pcnt && bcnt) { add_argv("--set-counters", 0); @@ -305,7 +310,7 @@ void xtables_restore_parse(struct nft_handle *h, add_param_to_argv(parsestart, line); DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", - newargc, curtable); + newargc, curtable->name); for (a = 0; a < newargc; a++) DEBUGP("argv[%u]: %s\n", a, newargv[a]); @@ -328,7 +333,8 @@ void xtables_restore_parse(struct nft_handle *h, free_argv(); fflush(stdout); } - if (p->tablename && (strcmp(p->tablename, curtable) != 0)) + if (p->tablename && curtable && + (strcmp(p->tablename, curtable->name) != 0)) continue; if (!ret) { fprintf(stderr, "%s: line %u failed\n", -- 2.18.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html