diff options
author | Phil Sutter <phil@nwl.cc> | 2024-01-31 18:08:43 +0100 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2024-02-01 14:51:30 +0100 |
commit | 933e605154c439218f73f48b028abbeed336c3c5 (patch) | |
tree | 1f48566e6378af5fbd3c11c2d2a40f51c1ea9680 /libxtables | |
parent | 3a135363c9e73dd51535c58b65afd4be65a4be64 (diff) |
xshared: Fix for memleak in option merging with ebtables
The crucial difference in ebtables is that all extensions are loaded up
front instead of while parsing -m/-j flags. Since this loading of all
extensions before every call to do_parse() is pointless overhead (cf.
ebtables-restore), other tools' mechanism of freeing all merged options
in xtables_free_opts() after handling each command and resetting
xt_params->opts at the start of the parser loop is problematic.
Fixed commit entailed a hack to defeat the xt_params->opts happening at
start of do_parse() by assigning to xt_params->orig_opts after loading
all extensions. This approach caused a memleak though since
xtables_free_opts() called from xtables_merge_options() will free the
opts pointer only if it differs from orig_opts.
Resolve this via a different approach which eliminates the
xt_params->opts reset at the start of do_parse():
Make xt_params->opts be NULL until the first extension is loaded. Option
merging in command_match() and command_jump() tolerates a NULL pointer
there after minimal adjustment. Deinit in xtables_free_opts() is already
fine as it (re)turns xt_params->opts to a NULL pointer. With do_parse()
expecting that and falling back to xt_params->orig_opts, no explicit
initialization is required anymore and thus ebtables' init is not
mangled by accident.
A critical part is that do_parse() checks xt_params->opts pointer upon
each call to getopt_long() as it may get assigned while parsing.
Fixes: 58d364c7120b5 ("ebtables: Use do_parse() from xshared")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'libxtables')
-rw-r--r-- | libxtables/xtables.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 856bfae8..ae3ff25a 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -111,10 +111,8 @@ void basic_exit_err(enum xtables_exittype status, const char *msg, ...) void xtables_free_opts(int unused) { - if (xt_params->opts != xt_params->orig_opts) { - free(xt_params->opts); - xt_params->opts = NULL; - } + free(xt_params->opts); + xt_params->opts = NULL; } struct option *xtables_merge_options(struct option *orig_opts, |