Maxin B. John [Thu, 25 Apr 2024 08:51:02 +0000 (10:51 +0200)]
configure: Add option to enable/disable libnfnetlink
Default behavior (autodetecting) does not change, but specifying
either option would explicitly disable or enable libnfnetlink support,
and if the library is not found in the latter case, ./configure will error
out.
Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Maxin B. John <maxin.john@intel.com> Signed-off-by: Alexander Kanavin <alex@linutronix.de> Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Tue, 9 Apr 2024 13:38:14 +0000 (15:38 +0200)]
libxtables: Attenuate effects of functions' internal static buffers
While functions returning pointers to internal static buffers have
obvious limitations, users are likely unaware how they call each other
internally and thus won't notice unsafe use. One such case is calling
both xtables_ipaddr_to_numeric() and xtables_ipmask_to_numeric() as
parameters for a single printf() call.
Defuse this trap by avoiding the internal calls to
xtables_ip{,6}addr_to_numeric() which is easily doable since callers
keep their own static buffers already.
While being at it, make use of inet_ntop() everywhere and also use
INET_ADDRSTRLEN/INET6_ADDRSTRLEN defines for correct (and annotated)
static buffer sizes.
Phil Sutter [Tue, 9 Apr 2024 11:18:12 +0000 (13:18 +0200)]
xshared: Fix parsing of empty string arg in '-c' option
Calling iptables with '-c ""' resulted in a call to strchr() with an
invalid pointer as 'optarg + 1' points to past the buffer. The most
simple fix is to drop the offset: The global optstring part specifies a
single colon after 'c', so getopt() enforces a valid pointer in optarg.
If it contains a comma at first position, packet counter value parsing
will fail so all cases are covered.
Phil Sutter [Tue, 5 Mar 2024 16:02:56 +0000 (17:02 +0100)]
xlate: libip6t_mh: Fix and simplify plain '-m mh' match
Since core xlate code now ignores '-p mh' if an mh extension is also
present in the rule, mh extension has to emit the l4proto match itself.
Therefore emit the exthdr match irrespective of '-p' argument value just
like other IPv6 extension header matches do.
Fixes: 83f60fb37d594 ("extensions: mh: Save/xlate inverted full ranges") Signed-off-by: Phil Sutter <phil@nwl.cc>
This worked by searching protocol name in loaded matches, but that
approach is flawed as the protocol name and corresponding extension may
differ ("mobility-header" vs. "mh"). Improve this by searching for all
names (cached or resolved) for a given protocol number.
Phil Sutter [Thu, 29 Feb 2024 16:55:32 +0000 (17:55 +0100)]
xtables-translate: Leverage stored protocol names
Align output of ip(6)tables-translate for --protocol arguments with that
of ip(6)tables -L/-S by calling proto_to_name() from xshared.c. The
latter will consult xtables_chain_protos list first to make sure (the
right) names are used for "common" protocol values and otherwise falls
back to getprotobynumber() which it replaces here.
Phil Sutter [Tue, 27 Feb 2024 17:47:39 +0000 (18:47 +0100)]
nft: Fix for broken recover_rule_compat()
When IPv4 rule generator was changed to emit payload instead of
meta expressions for l4proto matches, the code reinserting
NFTNL_RULE_COMPAT_* attributes into rules being reused for counter
zeroing was broken by accident.
Make rule compat recovery aware of the alternative match, basically
reinstating the effect of commit 7a373f6683afb ("nft: Fix -Z for rules
with NFTA_RULE_COMPAT") but add a test case this time to make sure
things stay intact.
Fixes: 69278f9602b43 ("nft: use payload matching for layer 4 protocol") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Wed, 10 Jan 2024 14:26:59 +0000 (15:26 +0100)]
iptables-save: Avoid /etc/protocols lookups
Instrument proto_to_name() to abort if given protocol number is not
among the well-known ones in xtables_chain_protos. Along with
xtables_parse_protocol() preferring said array for lookups as well, this
ensures reliable dump'n'restore regardless of /etc/protocols contents.
Another benefit is rule dump performance. A simple test-case dumping
100k rules matching on dccp protocol shows an 8s delta (2s vs. 10s for
legacy, 0.5s vs. 8s for nft) with this patch applied. For reference:
| for variant in nft legacy; do
| (
| echo "*filter"
| for ((i = 0; i < 100000; i++)); do
| echo "-A FORWARD -p dccp -j ACCEPT"
| done
| echo "COMMIT"
| ) | iptables-${variant}-restore
| time iptables-${variant}-save | wc -l
| iptables-${variant} -F
| done
Phil Sutter [Wed, 10 Jan 2024 22:22:32 +0000 (23:22 +0100)]
libxtables: Add dccp and ipcomp to xtables_chain_protos
There are "protocol extensions" for both just like with TCP or UDP.
Caching their values allows for implicit extension lookup after '-p'
flag, for instance:
| iptables -A FORWARD -p dccp --dport 1
| iptables -A FORWARD -p ipcomp --ipcompspi 18
The patch's original intention is not entirely clear anymore. If it was
to reduce delays involved by calling getprotobynumber() though, commit b6196c7504d4d ("xshared: Prefer xtables_chain_protos lookup over
getprotoent") avoids those if --numeric flag was given already. Also,
this numeric protocol output did not cover iptables-save which is a more
relevant candidate for such optimizations anyway.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1729 Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Fri, 26 Jan 2024 00:50:22 +0000 (01:50 +0100)]
libxtables: xtoptions: Respect min/max values when completing ranges
If an extension defines a minimum/maximum valid value for an option's
range argument, treat this as the lower/upper boundary to use when
completing (half) open ranges.
Phil Sutter [Thu, 1 Feb 2024 14:47:09 +0000 (15:47 +0100)]
extensions: esp: Save/xlate inverted full ranges
Also add a translation for plain '-m esp' match which depends on the
address family: While ip6tables-translate may emit an exthdr exists
match, iptables-translate must stick to meta l4proto.
Fixes: 6cfa723a83d45 ("extensions: libxt_esp: Add translation to nft") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Thu, 1 Feb 2024 14:42:10 +0000 (15:42 +0100)]
extensions: mh: Save/xlate inverted full ranges
Also translate '-m mh' into an exthdr exists match unless '-p mh' is
also present. The latter is converted into 'meta l4proto mh' which might
need fixing itself at a later point.
Fixes: 6d4b93485055a ("extensions: libip6t_mh: Add translation to nft") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Thu, 1 Feb 2024 14:27:03 +0000 (15:27 +0100)]
extensions: ah: Save/xlate inverted full ranges
While at it, fix xlate output for plain '-m ah' matches: With
ip6tables-translate, one should emit an extdhr exists match since
ip6t_ah.c in kernel also uses ipv6_find_hdr(). With iptables-translate,
a simple 'meta l4proto ah' was missing.
Fixes: bb498c8ba7bb3 ("extensions: libip6t_ah: Fix translation of plain '-m ah'") Fixes: b9a46ee406165 ("extensions: libipt_ah: Add translation to nft") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Wed, 24 Jan 2024 22:29:46 +0000 (23:29 +0100)]
libxtables: xtoptions: Assert ranges are monotonic increasing
Extensions commonly require the upper range value to be larger or equal
to the lower one. Performing this check in the parser is easier and
covers all extensions at once.
One notable exception is NFQUEUE which requires strict monotonicity.
Hence leave its checks in place.
Phil Sutter [Thu, 25 Jan 2024 01:12:24 +0000 (02:12 +0100)]
extensions: *.t/*.txlate: Test range corner-cases
For every extension option accepting a range, test open and half-open as
well as single element and invalid (negative) ranges.
The added tests merely reflect the status quo, not the expected outcome.
Following patches will fix results and the already existing test cases
highlight the fixes' effects.
Phil Sutter [Wed, 31 Jan 2024 21:45:07 +0000 (22:45 +0100)]
ebtables: Fix for memleak with change counters command
Just like with check command, change counters command creates a
temporary rule from rulespec on command line for a search by spec in
rule cache. It is not used anymore afterwards, so nft_cmd_free() should
free it.
Fixes: f340b7b6816be ("ebtables: Implement --change-counters command") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Wed, 31 Jan 2024 17:08:43 +0000 (18:08 +0100)]
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>
Phil Sutter [Wed, 31 Jan 2024 20:03:25 +0000 (21:03 +0100)]
xtables-eb: Eliminate 'opts' define
It is more harm than good as it hides assignments to xt_params->opts
field and does funny things if statements actually use xt_params->opts
instead of the define.
Replace it by local variables where sensible (cf. command_match() and
command_jump() in xshared.c).
Phil Sutter [Fri, 26 Jan 2024 17:43:10 +0000 (18:43 +0100)]
nft: ruleparse: Add missing braces around ternary
The expression evaluated the sum before the ternay, consequently not
adding target->size if tgsize was zero.
Identified by ASAN for a simple rule using standard target:
| # ebtables -A INPUT -s de:ad:be:ef:0:00 -j RETURN
| # ebtables -D INPUT -s de:ad:be:ef:0:00 -j RETURN
| =================================================================
| ==18925==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000120 at pc 0x7f627a4c75c5 bp 0x7ffe882b5180 sp 0x7ffe882b4928
| READ of size 8 at 0x603000000120 thread T0
| [...]
Fixes: 2a6eee89083c8 ("nft-ruleparse: Introduce nft_create_target()") Signed-off-by: Phil Sutter <phil@nwl.cc>
The simple search for the rule in save output accepted arbitrary leading
and trailing rule parts. This was partly desired as it allowed to omit
the leading '-A' flag or ignore the mandatory '-j CONTINUE' in ebtables
rules, though it could hide bugs.
Introduction of fast mode mitigated this due to the way how it searches
for multiple rules at the same time, but there are cases which fast mode
does not support yet (e.g. test cases containing variant-specific rule
output).
Given save output format will never contain the rule in first or last
line, so enclosing the searched rule in newline characters is sufficient
to make the search apply to full lines only. The only drawback is having
to add '-A' and '-j CONTINUE' parts if needed.
The hidden bugs this revealed were:
- Long --nflog-prefix strings are not cut to 64 chars with iptables-nft
- The TCPMSS rule supposed to fail with legacy only must specify an
expected save output
Phil Sutter [Thu, 21 Dec 2023 12:24:09 +0000 (13:24 +0100)]
ebtables: Default to extrapositioned negations
ebtables-nft has always supported both intra- and extrapositioned
negations but defaulted to intrapositioned when printing/saving rules.
With commit 58d364c7120b5 ("ebtables: Use do_parse() from xshared")
though, it started to warn about intrapositioned negations. So change
the default to avoid mandatory warnings when e.g. loading previously
dumped rulesets.
Also adjust test cases, help texts and ebtables-nft.8 accordingly.
Cc: Jan Engelhardt <jengelh@inai.de> Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Wed, 20 Dec 2023 01:54:07 +0000 (02:54 +0100)]
extensions: libxt_HMARK: Review HMARK_parse()
* With XTOPT_NBO support in UINT types, the manual byteorder conversion
calls are no longer needed
* Setting bits in cb->xflags is done by xtables_option_parse() already
* Since O_HMARK_* values match XT_HMARK_* ones, all but the O_HMARK_TYPE
case fold together into a single default one
Phil Sutter [Wed, 29 Nov 2023 16:35:48 +0000 (17:35 +0100)]
extensions: libebt_mark_m: Use guided option parser
Can't use XTTYPE_MARKMASK32 here because in 'val/mask', 'val' is
optional. Would have to extend xtopt_parse_markmask() to accept this,
maybe guarded by a new XTOPT_ flag to avoid unexpected changes in
behaviour?
Phil Sutter [Fri, 7 Oct 2022 20:23:59 +0000 (22:23 +0200)]
ebtables: Support for guided option parser
Adjust ebt_load_match() and ebt_command_default() to expect
x6_options/x6_parse fiels to be set instead of the traditional ones.
Much of this is c'n'p from command_default() in xshared.c, but due to
ebtables' custom match data structure (combining matches and watchers),
sharing the code is probably not feasible.
Phil Sutter [Wed, 13 Dec 2023 20:14:58 +0000 (21:14 +0100)]
libxtables: xtoptions: Treat NFPROTO_BRIDGE as IPv4
When parsing for XTTYPE_HOST(MASK), the return value of afinfo_family()
is used to indicate the expected address family.
Make guided option parser expect IPv4 by default for ebtables as this is
the more common case. The exception is libebt_ip6, which will
temporarily adjust afinfo->family while parsing.
Accept an Ethernet MAC address with optional mask in the format
xtables_parse_mac_and_mask() expects it. Does not support XTOPT_PUT (for
now) due to the lack of defined data structure.
Phil Sutter [Sun, 17 Dec 2023 12:02:36 +0000 (13:02 +0100)]
libxtables: xtoptions: Prevent XTOPT_PUT with XTTYPE_HOSTMASK
Do as the comment in xtopt_parse_hostmask() claims and omit
XTTYPE_HOSTMASK from xtopt_psize array so xtables_option_metavalidate()
will catch the incompatibility.
Phil Sutter [Mon, 18 Dec 2023 23:56:07 +0000 (00:56 +0100)]
iptables-legacy: Fix for mandatory lock waiting
Parameter 'wait' passed to xtables_lock() signals three modes of
operation, depending on its value:
0: --wait not specified, do not wait if lock is busy
-1: --wait specified without value, wait indefinitely until lock becomes
free
>0: Wait for 'wait' seconds for lock to become free, abort otherwise
Since fixed commit, the first two cases were treated the same apart from
calling alarm(0), but that is a nop if no alarm is pending. Fix the code
by requesting a non-blocking flock() in the second case. While at it,
restrict the alarm setup to the third case only.
Cc: Jethro Beekman <jethro@fortanix.com> Cc: howardjohn@google.com Cc: Antonio Ojea <antonio.ojea.garcia@gmail.com> Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1728 Fixes: 07e2107ef0cbc ("xshared: Implement xtables lock timeout using signals") Signed-off-by: Phil Sutter <phil@nwl.cc>
Jeremy Sowden [Thu, 14 Dec 2023 16:44:03 +0000 (16:44 +0000)]
build: use standard automake verbosity variables
The previous implementation ignored the default verbosity defined by
configure, and controlled by --{enable,disable}-silent-rules, and
treated V="" as V=0. Instead, follow the guide-lines given in the
automake manual.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Thu, 9 Nov 2023 15:59:51 +0000 (16:59 +0100)]
ebtables: Use do_parse() from xshared
Drop the custom commandline parsers from ebtables and
ebtables-translate, extend and use the shared one instead.
ebtables gains a few new features from doing this:
- Rule counters may be specified in the '-c N,M' syntax
- Support for --replace command
- Support for --list-rules command
- Zero individual rules
There is one known regression in this patch, namely maximum chain name
length shrinks to 28 characters (from 32). Since this limit changed for
iptables in the past as well (e.g. with commit 5429b41c2bb4a), assume
nobody really relies upon it anyway.
Phil Sutter [Fri, 24 Nov 2023 19:22:44 +0000 (20:22 +0100)]
ebtables: Make 'h' case just a call to print_help()
Move the special ebtables help parameter handling into its print_help()
function to prepare for it turning into a callback. Add new field 'argc'
to struct iptables_command_state to make this possible. It is actually
kind of consistent as it holds 'argv' already.
Phil Sutter [Wed, 22 Nov 2023 02:05:19 +0000 (03:05 +0100)]
ebtables: Change option values to avoid clashes
In order to parse input using do_parse(), distinct ebtables option's
values have to be distinct from others. Since arptables uses values 2-8
already, resort to values >10.
Phil Sutter [Fri, 24 Nov 2023 17:13:00 +0000 (18:13 +0100)]
xshared: Support for ebtables' --change-counters command
This is tricky because the short-option clashes with the --check
command. OTOH, ebtables supports --check as well (though without
short-option), so making do_parse() detect ebtables based on struct
xtables_args::family is probably still the least messy option.
Phil Sutter [Wed, 15 Nov 2023 12:09:27 +0000 (13:09 +0100)]
xshared: Support rule range deletion in do_parse()
This is a distinct ebtables feature. Introduce struct
xt_cmd_parse::rule_ranges boolean indicating support for it and bail
otherwise if a range was specified by the user.
Phil Sutter [Wed, 15 Nov 2023 15:58:15 +0000 (16:58 +0100)]
xshared: Turn command_default() into a callback
Ebtables' variant is pretty different since all extensions are loaded up
front and some targets serve as "watcher" extensions, so let variants
specify the function to call for extension parameters.
Phil Sutter [Tue, 28 Nov 2023 19:21:49 +0000 (20:21 +0100)]
libxtables: xtoptions: Fix for non-CIDR-compatible hostmasks
In order to parse the mask, xtopt_parse_hostmask() calls
xtopt_parse_plenmask() thereby limiting netmask support to prefix
lengths (alternatively specified in IP address notation).
In order to lift this impractical restriction, make
xtopt_parse_plenmask() aware of the fact that xtopt_parse_plen() may
fall back to xtopt_parse_mask() which correctly initializes val.hmask
itself and indicates non-CIDR-compatible masks by setting val.hlen to
-1.
So in order to support these odd masks, it is sufficient for
xtopt_parse_plenmask() to skip its mask building from val.hlen value and
take whatever val.hmask contains.
Fixes: 66266abd17adc ("libxtables: XTTYPE_HOSTMASK support") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Tue, 28 Nov 2023 19:11:57 +0000 (20:11 +0100)]
libxtables: xtoptions: Fix for garbage access in xtables_options_xfrm()
Allocation of the temporary array did not account for a terminating NULL
entry, causing array boundary overstepping in the called
xtables_merge_options(), causing spurious errors in extension parameter
parsing.
Fixes: ed8c3ea4015f0 ("libxtables: Combine the two extension option mergers") Signed-off-by: Phil Sutter <phil@nwl.cc>
Phil Sutter [Fri, 17 Nov 2023 16:27:56 +0000 (17:27 +0100)]
nft: Leave interface masks alone when parsing from kernel
The mask is entirely unused by nft-variants in general and legacy ones
when printing. It is relevant only when inserting a legacy rule into
kernel as it doesn't detect the '+'-suffix.
Phil Sutter [Sat, 18 Nov 2023 03:28:25 +0000 (04:28 +0100)]
xshared: Do not populate interface masks per default
These are needed by legacy variants only, so introduce a simplified
xtables_parse_interface() replacement which does not deal with them and
a small function which sets the mask based on given interface name for
use by legacy tools.
Replace the awkward inverse_for_options array with basically a few
switch() statements clearly identifying the relation between option and
inverse values and relieve callers from having to find the option flag
bit's position.
Phil Sutter [Tue, 14 Nov 2023 17:51:59 +0000 (18:51 +0100)]
xshared: Introduce xt_cmd_parse_ops::option_name
The old opt2char() function was flawed: Since not every field in
optflags contains a printable character, typical use of its return value
in print statements could lead to garbage on screen.
Replace this by a mechanism to retrieve an option's long name which
supports family-specific overrides. and get rid of optflags field
altogether and define NUMBER_OF_OPT similar to NUMBER_OF_CMD.
Phil Sutter [Fri, 3 Sep 2021 17:23:43 +0000 (19:23 +0200)]
extensions: MARK: arptables: Use guided option parser
It expects mark values in hex which is possible by setting the base
field.
The only adjustment needed to use the revision 2 parser is to fill the
mask for --set-mark: With XTTYPE_MARKMASK32, an omitted mask sets all
mask bits, XTTYPE_UINT32 leaves it uninitialized, though.
Phil Sutter [Thu, 2 Sep 2021 14:53:26 +0000 (16:53 +0200)]
extensions: libarpt_mangle: Use guided option parser
Sadly not the best conversion, struct arpt_mangle is not ideal for use
as storage backend: With MAC addresses, xtopt_parse_ethermac() refuses
to write into *_devaddr fields as they are larger than expected. With
XTTYPE_HOSTMASK OTOH, XTOPT_PUT is not supported in the first place.
As a side-effect, network names (from /etc/networks) are no longer
accepted. But earlier migrations to guided option parser had this
side-effect as well, so probably not a frequently used feature.
Phil Sutter [Wed, 22 Nov 2023 19:41:34 +0000 (20:41 +0100)]
libxtables: Introduce xtables_strtoul_base()
Semantically identical to xtables_strtoul() but accepts the base as
parameter so callers may force it irrespective of number prefix. The old
xtables_strtoul() becomes a shallow wrapper.
Phil Sutter [Thu, 2 Sep 2021 14:51:15 +0000 (16:51 +0200)]
libxtables: Fix guided option parser for use with arptables
With an unexpected value in afinfo->family, guided option parser was
rather useless when called from arptables extensions. Introduce
afinfo_family() wrapper to sanitize at least NFPROTO_ARP value.
Phil Sutter [Fri, 3 Sep 2021 21:43:41 +0000 (23:43 +0200)]
libxtables: Combine the two extension option mergers
For extending the command parser's struct option array, there is
xtables_merge_options() and xtables_options_xfrm(). Since their bodies
were almost identical, make the latter a wrapper of the former by
transforming the passed struct xt_option_entry array into a temporary
struct option one before handing over.
Phil Sutter [Tue, 21 Nov 2023 22:14:47 +0000 (23:14 +0100)]
ebtables: Implement --change-counters command
Treat it like --replace against the same rule with changed counters.
The operation is obviously not atomic, so rule counters may change in
kernel while the rule is fetched, modified and replaced.
Phil Sutter [Wed, 22 Nov 2023 02:58:18 +0000 (03:58 +0100)]
xshared: do_parse: Ignore '-j CONTINUE'
While iptables does not support his NOP, arptables man page claims it
does (although legacy arptables rejects it) and ebtables prefers to
print it instead of omitting the '-j' option.
Accept and ignore the target when parsing to at least fix for
arptables-nft and prepare for ebtables-nft using do_parse() as well.