diff options
-rw-r--r-- | iptables/nft-bridge.c | 10 | ||||
-rw-r--r-- | iptables/nft-bridge.h | 2 | ||||
-rw-r--r-- | iptables/nft-shared.c | 5 | ||||
-rwxr-xr-x | iptables/tests/shell/testcases/iptables/0005-delete-rules_0 | 7 | ||||
-rw-r--r-- | iptables/xtables-eb-translate.c | 24 | ||||
-rw-r--r-- | iptables/xtables-eb.c | 47 | ||||
-rw-r--r-- | libxtables/xtables.c | 18 |
7 files changed, 41 insertions, 72 deletions
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c index b4265c8a..7c390dfa 100644 --- a/iptables/nft-bridge.c +++ b/iptables/nft-bridge.c @@ -45,6 +45,16 @@ void ebt_cs_clean(struct iptables_command_state *cs) free(m); m = nm; } + + if (cs->target) { + free(cs->target->t); + cs->target->t = NULL; + + if (cs->target == cs->target->next) { + free(cs->target); + cs->target = NULL; + } + } } static void ebt_print_mac(const unsigned char *mac) diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h index de52cd71..d90066f1 100644 --- a/iptables/nft-bridge.h +++ b/iptables/nft-bridge.h @@ -32,7 +32,6 @@ int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mas */ #define EBT_TABLE_MAXNAMELEN 32 -#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN /* verdicts >0 are "branches" */ @@ -122,6 +121,5 @@ void ebt_add_match(struct xtables_match *m, void ebt_add_watcher(struct xtables_target *watcher, struct iptables_command_state *cs); int ebt_command_default(struct iptables_command_state *cs); -struct xtables_target *ebt_command_jump(const char *jumpto); #endif diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 2d4b8d55..a72d414d 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -687,6 +687,11 @@ void nft_clear_iptables_command_state(struct iptables_command_state *cs) if (cs->target) { free(cs->target->t); cs->target->t = NULL; + + if (cs->target == cs->target->next) { + free(cs->target); + cs->target = NULL; + } } } diff --git a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 index 9312fd53..5038cbce 100755 --- a/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 +++ b/iptables/tests/shell/testcases/iptables/0005-delete-rules_0 @@ -5,3 +5,10 @@ $XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j DROP $XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j REJECT [[ $? -eq 1 ]] || exit 1 + +# test incorrect deletion of rules with deviating payload +# in non-standard target + +$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j MARK --set-mark 23 +$XT_MULTI iptables -D FORWARD -i eth23 -o eth42 -j MARK --set-mark 42 +[[ $? -eq 1 ]] || exit 1 diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c index f98c3855..0fe14d2d 100644 --- a/iptables/xtables-eb-translate.c +++ b/iptables/xtables-eb-translate.c @@ -64,27 +64,6 @@ static int parse_rule_number(const char *rule) return rule_nr; } -static const char * -parse_target(const char *targetname) -{ - const char *ptr; - - if (strlen(targetname) < 1) - xtables_error(PARAMETER_PROBLEM, - "Invalid target name (too short)"); - - if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN) - xtables_error(PARAMETER_PROBLEM, - "Invalid target '%s' (%d chars max)", - targetname, EBT_CHAIN_MAXNAMELEN); - - for (ptr = targetname; *ptr; ptr++) - if (isspace(*ptr)) - xtables_error(PARAMETER_PROBLEM, - "Invalid target name `%s'", targetname); - return targetname; -} - static int get_current_chain(const char *chain) { if (strcmp(chain, "PREROUTING") == 0) @@ -411,8 +390,7 @@ print_zero: break; } else if (c == 'j') { ebt_check_option2(&flags, OPT_JUMP); - cs.jumpto = parse_target(optarg); - cs.target = ebt_command_jump(cs.jumpto); + command_jump(&cs); break; } else if (c == 's') { ebt_check_option2(&flags, OPT_SOURCE); diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c index b9d98a05..75d43963 100644 --- a/iptables/xtables-eb.c +++ b/iptables/xtables-eb.c @@ -139,27 +139,6 @@ static int parse_rule_number(const char *rule) return rule_nr; } -static const char * -parse_target(const char *targetname) -{ - const char *ptr; - - if (strlen(targetname) < 1) - xtables_error(PARAMETER_PROBLEM, - "Invalid target name (too short)"); - - if (strlen(targetname)+1 > EBT_CHAIN_MAXNAMELEN) - xtables_error(PARAMETER_PROBLEM, - "Invalid target '%s' (%d chars max)", - targetname, EBT_CHAIN_MAXNAMELEN); - - for (ptr = targetname; *ptr; ptr++) - if (isspace(*ptr)) - xtables_error(PARAMETER_PROBLEM, - "Invalid target name `%s'", targetname); - return targetname; -} - static int append_entry(struct nft_handle *h, const char *chain, @@ -365,29 +344,6 @@ static struct option *merge_options(struct option *oldopts, return merge; } -/* - * More glue code. - */ -struct xtables_target *ebt_command_jump(const char *jumpto) -{ - struct xtables_target *target; - unsigned int verdict; - - /* Standard target? */ - if (!ebt_fill_target(jumpto, &verdict)) - jumpto = "standard"; - - /* For ebtables, all targets are preloaded. Hence it is either in - * xtables_targets or a custom chain to jump to, in which case - * returning NULL is fine. */ - for (target = xtables_targets; target; target = target->next) { - if (!strcmp(target->name, jumpto)) - break; - } - - return target; -} - static void print_help(const struct xtables_target *t, const struct xtables_rule_match *m, const char *table) { @@ -1055,8 +1011,7 @@ print_zero: } else if (c == 'j') { ebt_check_option2(&flags, OPT_JUMP); if (strcmp(optarg, "CONTINUE") != 0) { - cs.jumpto = parse_target(optarg); - cs.target = ebt_command_jump(cs.jumpto); + command_jump(&cs); } break; } else if (c == 's') { diff --git a/libxtables/xtables.c b/libxtables/xtables.c index ea9bb102..895f6988 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -756,8 +756,24 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) } for (ptr = xtables_targets; ptr; ptr = ptr->next) { - if (extension_cmp(name, ptr->name, ptr->family)) + if (extension_cmp(name, ptr->name, ptr->family)) { + struct xtables_target *clone; + + /* First target of this type: */ + if (ptr->t == NULL) + break; + + /* Second and subsequent clones */ + clone = xtables_malloc(sizeof(struct xtables_target)); + memcpy(clone, ptr, sizeof(struct xtables_target)); + clone->udata = NULL; + clone->tflags = 0; + /* This is a clone: */ + clone->next = clone; + + ptr = clone; break; + } } #ifndef NO_SHARED_LIBS |