]> git.ipfire.org Git - thirdparty/nftables.git/log
thirdparty/nftables.git
6 weeks agonetlink: Avoid crash upon missing NFTNL_OBJ_CT_TIMEOUT_ARRAY attribute
Phil Sutter [Thu, 12 Jun 2025 18:17:22 +0000 (20:17 +0200)] 
netlink: Avoid crash upon missing NFTNL_OBJ_CT_TIMEOUT_ARRAY attribute

If missing, the memcpy call ends up reading from address zero.

Fixes: c7c94802679cd ("src: add ct timeout support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agotests: py: Properly fix JSON equivalents for netdev/reject.t
Phil Sutter [Thu, 12 Jun 2025 10:59:29 +0000 (12:59 +0200)] 
tests: py: Properly fix JSON equivalents for netdev/reject.t

Revert commit d1a7b9e19fe65 ("tests: py: update netdev reject test
file"), the stored JSON equivalents were correct in that they matched
the standard syntax input.

In fact, we missed a .json.output file recording the expected deviation
in JSON output.

Fixes: d1a7b9e19fe65 ("tests: py: update netdev reject test file")
Fixes: 7ca3368cd7575 ("reject: Unify inet, netdev and bridge delinearization")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agotests: shell: Adjust to ifname-based hooks
Phil Sutter [Tue, 6 May 2025 22:06:20 +0000 (00:06 +0200)] 
tests: shell: Adjust to ifname-based hooks

Interface specs won't disappear anymore upon device removal. Drop them
manually if kernel has ifname-based hooks.

Skip transactions/0050rule_1 if kernel has name-based hooks: The test
relies upon the ruleset being rejected for non-existent interfaces,
which obviously won't happen then.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agotests: monitor: Fix for single flag array avoidance
Phil Sutter [Wed, 11 Jun 2025 15:15:22 +0000 (17:15 +0200)] 
tests: monitor: Fix for single flag array avoidance

Missed to update the JSON monitor expected output.

Fixes: 6bedb12af1658 ("json: Print single set flag as non-array")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agojson: Dump flowtable hook spec only if present
Phil Sutter [Wed, 11 Jun 2025 14:45:48 +0000 (16:45 +0200)] 
json: Dump flowtable hook spec only if present

If there is no priority.expr set, assume hook.num is bogus, too.

While this is fixing JSON output, it's hard to tell what commit this is
actually fixing: Before commit 627c451b23513 ("src: allow variables in
the chain priority specification"), there was no way to detect
flowtables missing hook specs (e.g. when printing flowtable delete
monitor event).

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agomonitor: Correctly print flowtable updates
Phil Sutter [Wed, 11 Jun 2025 12:24:37 +0000 (14:24 +0200)] 
monitor: Correctly print flowtable updates

An update deleting a hook from a flowtable was indistinguishable from a
flowtable deletion.

Fixes: 73a8adfc2432e ("monitor: Recognize flowtable add/del events")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agonetlink: Do not allocate a bogus flowtable priority expr
Phil Sutter [Wed, 11 Jun 2025 12:15:38 +0000 (14:15 +0200)] 
netlink: Do not allocate a bogus flowtable priority expr

Code accidentally treats missing NFTNL_FLOWTABLE_PRIO attribute as zero
prio value which may not be correct.

Fixes: db0697ce7f602 ("src: support for flowtable listing")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agonetlink: Fix for potential crash parsing a flowtable
Phil Sutter [Wed, 11 Jun 2025 11:12:56 +0000 (13:12 +0200)] 
netlink: Fix for potential crash parsing a flowtable

Kernel's flowtable message might not contain the
NFTA_FLOWTABLE_HOOK_DEVS attribute. In that case, nftnl_flowtable_get()
will return NULL for the respective nftnl attribute.

Fixes: db0697ce7f602 ("src: support for flowtable listing")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
7 weeks agomnl: catch bogus expressions before crashing
Florian Westphal [Thu, 5 Jun 2025 22:20:28 +0000 (00:20 +0200)] 
mnl: catch bogus expressions before crashing

We can't recover from errors here, but we can abort with a more
precise reason than 'segmentation fault', or stack corruptions
that get caught way later, or not at all.

expr->value is going to be read, we can't cope with other expression
types here.

We will copy to stack buffer of IFNAMSIZ size, abort if we would
overflow.

Check there is a NUL byte present too.
This is a preemptive patch, I've seen one crash in this area but
no reproducer yet.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
7 weeks agodoc: Basic documentation of anonymous chains
Phil Sutter [Wed, 4 Jun 2025 17:53:47 +0000 (19:53 +0200)] 
doc: Basic documentation of anonymous chains

Joint work with Folsk Pratima.

Signed-off-by: Folsk Pratima <folsk0pratima@cock.li>
Signed-off-by: Phil Sutter <phil@nwl.cc>
7 weeks agotests: shell: Add a test case for FTP helper combined with NAT.
Yi Chen [Mon, 9 Jun 2025 08:14:28 +0000 (16:14 +0800)] 
tests: shell: Add a test case for FTP helper combined with NAT.

This test verifies functionality of the FTP helper,
for both passive, active FTP modes,
and the functionality of the nf_nat_ftp module.

Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agotests: helpers: suppress mount error messages
Florian Westphal [Fri, 6 Jun 2025 12:26:14 +0000 (14:26 +0200)] 
tests: helpers: suppress mount error messages

Prevent repeated error messages from spamming the console.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agojson: work around fuzzer-induced assert crashes
Florian Westphal [Mon, 31 Mar 2025 14:47:11 +0000 (16:47 +0200)] 
json: work around fuzzer-induced assert crashes

fuzzer can cause assert failures due to json_pack() returning a NULL
value and therefore triggering the assert(out) in __json_pack macro.

All instances I saw are due to invalid UTF-8 strings, i.e., table/chain
names with non-text characters in them.

Work around this for now, replace the assert with a plaintext error
message and return NULL instead of abort().

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agojson: prevent null deref if chain->policy is not set
Florian Westphal [Mon, 2 Jun 2025 12:22:33 +0000 (14:22 +0200)] 
json: prevent null deref if chain->policy is not set

The two commits mentioned below resolved null dererence crashes when the
policy resp. priority keyword was missing in the chain/flowtable
specification.

Same issue exists in the json output path, so apply similar fix there
and extend the existing test cases.

Fixes: 5b37479b42b3 ("nftables: don't crash in 'list ruleset' if policy is not set")
Fixes: b40bebbcee36 ("rule: do not crash if to-be-printed flowtable lacks priority")
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Phil Sutter <phil@nwl.cc>
8 weeks agotests: py: fix json single-flag output for fib & synproxy
Florian Westphal [Mon, 2 Jun 2025 12:12:16 +0000 (14:12 +0200)] 
tests: py: fix json single-flag output for fib & synproxy

Blamed commits change output format but did not adjust existing tests:
  inet/fib.t: WARNING: line 16: '{"nftables": ..

Fixes: 38f99ee84fe6 ("json: Print single synproxy flags as non-array")
Fixes: dbe5c44f2b89 ("json: Print single fib flag as non-array")
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: check for features not available in 5.4
Pablo Neira Ayuso [Thu, 29 May 2025 09:49:18 +0000 (11:49 +0200)] 
tests: shell: check for features not available in 5.4

5.4 -stable kernels report failures in these tests, this kernel version
is lacking these feature.

The bitshift requirement is needed by this ruleset:

 table ip x {
        set s13 {
                typeof tcp option mptcp subtype
                elements = { mp-join, dss }
        }

        chain y {
                tcp option mptcp subtype @s13 accept
        }
 }

which uses bitshift in its bytecode.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agocache: Tolerate object deserialization failures
Phil Sutter [Fri, 16 May 2025 17:36:37 +0000 (19:36 +0200)] 
cache: Tolerate object deserialization failures

If netlink_delinearize_obj() fails, it will print an error message. Skip
this object and keep going.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agonetlink: Keep going after set element parsing failures
Phil Sutter [Fri, 16 May 2025 17:33:25 +0000 (19:33 +0200)] 
netlink: Keep going after set element parsing failures

Print an error message and try to deserialize the remaining elements
instead of calling BUG().

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agonetlink: Pass netlink_ctx to netlink_delinearize_setelem()
Phil Sutter [Fri, 16 May 2025 17:17:00 +0000 (19:17 +0200)] 
netlink: Pass netlink_ctx to netlink_delinearize_setelem()

Prepare for calling netlink_io_error() which needs the context pointer.
Trade this in for the cache pointer since no caller uses a special one.
No functional change intended.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agonetlink_delinearize: Replace some BUG()s by error messages
Phil Sutter [Fri, 16 May 2025 11:28:19 +0000 (13:28 +0200)] 
netlink_delinearize: Replace some BUG()s by error messages

Netlink parser tries to keep going despite errors. Faced with an
incompatible ruleset, this is much more user-friendly than exiting the
program upon the first obstacle. This patch fixes three more spots to
support this.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests: shell: check if kernel supports for cgroupsv2 matching
Pablo Neira Ayuso [Mon, 19 May 2025 23:59:06 +0000 (01:59 +0200)] 
tests: shell: check if kernel supports for cgroupsv2 matching

Update packetpath/cgroupv2 to skip it if kernel does not support it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests: shell: skip egress in netdev chain release path test
Pablo Neira Ayuso [Mon, 19 May 2025 23:17:39 +0000 (01:17 +0200)] 
tests: shell: skip egress in netdev chain release path test

Update test to skip egress coverage if kernel does not support it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agonetlink: Catch unknown types when deserializing objects
Phil Sutter [Fri, 16 May 2025 17:41:19 +0000 (19:41 +0200)] 
netlink: Catch unknown types when deserializing objects

Print an error message and discard the object instead of returning it to
the caller. At least when trying to print it, we would hit an assert()
in obj_type_name() anyway.

Fixes: 4756d92e517ae ("src: listing of stateful objects")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agonetlink: Avoid potential NULL-ptr deref parsing set elem expressions
Phil Sutter [Fri, 16 May 2025 18:08:05 +0000 (20:08 +0200)] 
netlink: Avoid potential NULL-ptr deref parsing set elem expressions

Since netlink_parse_set_expr() may return NULL, the following deref must
be guarded.

Fixes: e6d1d0d611958 ("src: add set element multi-statement support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: Include kernel taint value in warning
Phil Sutter [Fri, 9 May 2025 12:46:50 +0000 (14:46 +0200)] 
tests: shell: Include kernel taint value in warning

If kernel is already tainted, not all tests yield usable results.
Printing the taint cause might help users tracking down the external
cause.

If a test taints the kernel, the value is stored in rc-failed-tainted
file already.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: Add test case for JSON 'flags' arrays
Phil Sutter [Thu, 8 May 2025 15:34:18 +0000 (17:34 +0200)] 
tests: shell: Add test case for JSON 'flags' arrays

Ensure these arrays are reduced if containing just a single item and
parser interprets them correctly in any case.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agojson: Introduce json_add_array_new()
Phil Sutter [Thu, 8 May 2025 15:28:02 +0000 (17:28 +0200)] 
json: Introduce json_add_array_new()

Propagate nat_stmt_add_array() to a generic helper for use in all spots
adding an array property which may reduce to a single item or even not
exist at all.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agojson: Print single synproxy flags as non-array
Phil Sutter [Thu, 8 May 2025 14:44:39 +0000 (16:44 +0200)] 
json: Print single synproxy flags as non-array

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agojson: Print single fib flag as non-array
Phil Sutter [Thu, 8 May 2025 14:40:41 +0000 (16:40 +0200)] 
json: Print single fib flag as non-array

Check array size and reduce the array if possible.

The zero array length check is dead code here due to the surrounding 'if
(flags)' block, but it's a common idiom one could replace by a shared
routine later.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agojson: Print single set flag as non-array
Phil Sutter [Thu, 8 May 2025 14:39:24 +0000 (16:39 +0200)] 
json: Print single set flag as non-array

The code obviously intended to do this already but got the array length
check wrong.

Fixes: e70354f53e9f6 ("libnftables: Implement JSON output support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agodoc: Fix typo in nat statement 'prefix' description
Phil Sutter [Thu, 8 May 2025 14:35:47 +0000 (16:35 +0200)] 
doc: Fix typo in nat statement 'prefix' description

No point in repeating 'to map' here.

Fixes: 19d73ccdd39fa ("doc: add nat examples")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoparser_json: Introduce parse_flags_array()
Phil Sutter [Thu, 10 Apr 2025 14:42:42 +0000 (16:42 +0200)] 
parser_json: Introduce parse_flags_array()

Various objects support a 'flags' property with value usually being an
array of strings. There is a special case, when merely a single flag is
set: The value may be a string representing this flag.

Introduce a function assisting in parsing this polymorphic value. Have
callers pass a parser callback translating a single flag name into a
corresponding value. Luckily, these single flag parsers are very common
already.

As a side-effect, enable the single flag spec for set flags as well and
update the documentation accordingly.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agosrc: netlink: fix crash when ops doesn't support udata
Florian Westphal [Thu, 8 May 2025 14:29:04 +0000 (16:29 +0200)] 
src: netlink: fix crash when ops doesn't support udata

Whenever a new version adds udata support to an expression, then old
versions of nft will crash when trying to list such a ruleset generated
by a more recent version of nftables.

Fix this by falling back to 'type' format.

Fixes: 6e48df5329ea ('src: add "typeof" build/parse/print support')
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests/shell: Skip netdev_chain_dev_addremove on tainted kernels
Phil Sutter [Thu, 8 May 2025 10:08:39 +0000 (12:08 +0200)] 
tests/shell: Skip netdev_chain_dev_addremove on tainted kernels

The test checks taint state to indicate success or failure. Since this
won't work if the kernel is already tainted at start, skip the test
instead of failing it.

Fixes: 02dbf86f39410 ("tests: shell: add a test case for netdev ruleset flush + parallel link down")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agosrc: remove bogus empty file
Florian Westphal [Fri, 25 Apr 2025 06:20:19 +0000 (08:20 +0200)] 
src: remove bogus empty file

No idea how this happened, remove it.

Reported-by: Sunny73Cr <Sunny73Cr@protonmail.com>
Fixes: 058246016188 ("src: allow to map key to nfqueue number")
Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agotests: shell: Update packetpath/flowtables
Yi Chen [Wed, 16 Apr 2025 15:53:20 +0000 (23:53 +0800)] 
tests: shell: Update packetpath/flowtables

1. The socat receiver should not use the pipfile as output where the sender
   reads data from, this could create an infinite data loop.
2. Sending a packet right after establishing the connection helped uncover
   a new bug (see kernel commit
   d2d31ea8cd80, "netfilter: conntrack: fix erronous removal of offload bit").
3. Optimize test log output

Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agobuild: Bump version to 1.1.3 v1.1.3
Pablo Neira Ayuso [Tue, 22 Apr 2025 09:47:38 +0000 (11:47 +0200)] 
build: Bump version to 1.1.3

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agonetlink: bogus concatenated set ranges with netlink message overrun
Pablo Neira Ayuso [Thu, 17 Apr 2025 19:40:23 +0000 (21:40 +0200)] 
netlink: bogus concatenated set ranges with netlink message overrun

When building each component of the set element key, a late byteorder
switch is performed to ensure that all components in the interval are
represented in big endian, as required by the pipapo backend.

In case that the set element does not fit into the netlink message, the
byteorder switch happens twice, leading to inserting an element with a
bogus component with large sets, so instead:

      "lo" . 00:11:22:33:44:55 . 10.1.2.3 comment "123456789012345678901234567890"

listing reports:

  16777216 . 00:11:22:33:44:55 . 10.1.2.3 comment "123456789012345678901234567890"

Note that 16777216 is 0x1000000, which should instead be 0x00000001 to
represent "lo" as u32.

Fix this by switching the value in a temporary variable and use it to
set the set element key attribute in the netlink message.

Later, revisit this to perform this byteorder switch from evaluation
step.

Add tests/shell unit to cover for this bug.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1792
Fixes: 8ac2f3b2fca3 ("src: Add support for concatenated set ranges")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevalute: make vlan pcp updates work
Florian Westphal [Sat, 19 Apr 2025 11:44:39 +0000 (13:44 +0200)] 
evalute: make vlan pcp updates work

On kernel side, nft_payload_set_vlan() requires a 2 or 4 byte
write to the vlan header.

As-is, nft emits a 1 byte write:
  [ payload load 1b @ link header + 14 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x0000001f ) ^ 0x00000020 ]

... which the kernel doesn't support.  Expand all vlan header updates to
a 2 or 4 byte write and update the existing vlan id test case.

Reported-by: Kevin Vigouroux <ke.vigouroux@laposte.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoRevert "intervals: do not merge intervals with different timeout"
Pablo Neira Ayuso [Thu, 17 Apr 2025 11:23:10 +0000 (13:23 +0200)] 
Revert "intervals: do not merge intervals with different timeout"

This reverts commit da0bac050c8b2588242727f9915a1ea8bc48ceb2.

This results in an error when adding an interval that overlaps an
existing interval in the kernel, this defeats the purpose of the
auto-merge feature.

Reported-by: Slavko <linux@slavino.sk>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agobuild: Bump version to 1.1.2 v1.1.2
Pablo Neira Ayuso [Mon, 14 Apr 2025 16:55:15 +0000 (18:55 +0200)] 
build: Bump version to 1.1.2

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoparser_bison: add selector_expr rule to restrict typeof_expr
Pablo Neira Ayuso [Thu, 10 Apr 2025 21:23:58 +0000 (23:23 +0200)] 
parser_bison: add selector_expr rule to restrict typeof_expr

typeof_expr allows for symbol, constant and bitwise expressions,
restrict it to selector expressions.

After this patch, input generated by fuzzer is rejected upfront:

 # nft -f test.nft
 test.nft:3:53-53: Error: syntax error, unexpected number
               typeof numgen inc mod 2 : ip daddr . 0
                                                    ^
 test.nft:2:12-13: Error: set definition does not specify key
       map t2 {
           ^^
 test.nft:8:65-67: Error: No such file or directory
               meta l4proto tcp dnat ip to numgen inc mod 2 map @t2
                                                                ^^^
 test.nft:8:65-67: Error: No such file or directory
               meta l4proto tcp dnat ip to numgen inc mod 2 map @t2
                                                                ^^^

Revisit 4ab1e5e60779 ("src: allow use of 'verdict' in typeof
definitions") to handle verdict as string, later a token can be added
to the scanner and enable it via flex start conditions.

Fixes: 14357cff40ed ("parser: add typeof keyword for declarations")
Reported-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agooptimize: invalidate merge in case of duplicated key in set/map
Pablo Neira Ayuso [Wed, 9 Apr 2025 09:38:17 +0000 (11:38 +0200)] 
optimize: invalidate merge in case of duplicated key in set/map

-o/--optimize results in EEXIST error when merging two rules that lead
to ambiguous set/map, for instance:

 table ip x {
        chain v4icmp {}
        chain v4icmpc {}

        chain y {
                ip protocol icmp jump v4icmp
                ip protocol icmp goto v4icmpc
        }
 }

which is not possible because duplicated keys are not possible in
set/map. This is how it shows when running a test:

 Merging:
 testcases/sets/dumps/sets_with_ifnames.nft:56:3-30:            ip protocol icmp jump v4icmp
 testcases/sets/dumps/sets_with_ifnames.nft:57:3-31:            ip protocol icmp goto v4icmpc
 into:
       ip protocol vmap { icmp : jump v4icmp, icmp : goto v4icmpc }
 internal:0:0-0: Error: Could not process rule: File exists

Add a new step to compare rules that are candidate to be merged to
detect colissions in set/map keys in order to skip them in the next
final merging step.

Add tests/shell unit to improve coverage.

Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: bail out if ct saddr/daddr dependency cannot be inserted
Florian Westphal [Wed, 2 Apr 2025 23:09:22 +0000 (01:09 +0200)] 
evaluate: bail out if ct saddr/daddr dependency cannot be inserted

If we have an incomplete rule like "ct original saddr" in inet
family, this function generates an error because it can't determine the required protocol
dependency, hinting at missing ip/ip6 keyword.

We should not go on in this case to avoid a redundant followup error:

nft add rule inet f c ct original saddr 1.2.3.4
Error: cannot determine ip protocol version, use "ip saddr" or "ip6 saddr" instead
add rule inet f c ct original saddr 1.2.3.4
                  ^^^^^^^^^^^^^^^^^
Error: Could not parse symbolic invalid expression
add rule inet f c ct original saddr 1.2.3.4

After this change only the first error is shown.

Fixes: 2b29ea5f3c3e ("src: ct: add eval part to inject dependencies for ct saddr/daddr")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoparser_json: only allow concatenations with 2 or more expressions
Florian Westphal [Wed, 2 Apr 2025 05:18:18 +0000 (07:18 +0200)] 
parser_json: only allow concatenations with 2 or more expressions

The bison parser enforces this implicitly by grammar rules.
Because subkeys have to be conatenated via ".", notation, e.g.
"mark . ip saddr", all concatenation expressions always consist of at
least two elements.

But this doesn't apply to the json frontend which just uses an array:
it can be empty or only contain one element.

The included reproducer makes the eval stage set the "concatenation" flag
on the interval set.  This prevents the needed conversion code to turn the
element values into ranges from getting run.

The reproducer asserts with:
nft: src/intervals.c:786: setelem_to_interval: Assertion `key->etype == EXPR_RANGE_VALUE' failed.

Convert the assertion to BUG() so we can see what element type got passed
to the set interval code in case we have further issues in this area.

Reject 0-or-1-element concatenations from the json parser.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: fix crash when generating reject statement error
Florian Westphal [Mon, 31 Mar 2025 12:43:34 +0000 (14:43 +0200)] 
evaluate: fix crash when generating reject statement error

After patch, this gets rejected with:
internal:0:0-0: Error: conflicting protocols specified: ip vs ip6

Without patch, we crash with a NULL dereference: we cannot use
reject.expr->location unconditionally.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: reject: remove unused expr function argument
Florian Westphal [Mon, 31 Mar 2025 12:43:33 +0000 (14:43 +0200)] 
evaluate: reject: remove unused expr function argument

stmt_evaluate_reject passes cmd->expr argument but its never used.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agooptimize: expand expression list when merging into concatenation
Pablo Neira Ayuso [Tue, 1 Apr 2025 16:11:45 +0000 (18:11 +0200)] 
optimize: expand expression list when merging into concatenation

The following rules:

    udp dport 137 ct state new,untracked accept
    udp dport 138 ct state new,untracked accept

results in:

  nft: src/optimize.c:670: __merge_concat: Assertion `0' failed.

The logic to expand to the new,untracked list in the concatenation is
missing.

Fixes: 187c6d01d357 ("optimize: expand implicit set element when merging into concatenation")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agocache: prevent possible crash rule filter is NULL
Pablo Neira Ayuso [Tue, 1 Apr 2025 15:36:48 +0000 (17:36 +0200)] 
cache: prevent possible crash rule filter is NULL

Similar to 3f0a47f9f00c ("cache: don't crash when filter is NULL").

No real crash observed but it is good to tigthen this.

Fixes: dbff26bfba83 ("cache: consolidate reset command")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoparser_json: bail out on malformed statement in set
Pablo Neira Ayuso [Tue, 1 Apr 2025 07:57:59 +0000 (09:57 +0200)] 
parser_json: bail out on malformed statement in set

Propagate error to caller so it bails out on malformed set statements.

Fixes: 07958ec53830 ("json: add set statement list support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoparser_json: allow statement stateful statement only in set elements
Pablo Neira Ayuso [Tue, 1 Apr 2025 07:49:48 +0000 (09:49 +0200)] 
parser_json: allow statement stateful statement only in set elements

Upfront reject of non stateful statements in set elements.

Fixes: 07958ec53830 ("json: add set statement list support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoparser_json: reject empty jump/goto chain
Pablo Neira Ayuso [Mon, 31 Mar 2025 15:55:45 +0000 (17:55 +0200)] 
parser_json: reject empty jump/goto chain

When parsing a verdict map json where element jumps to chain represented
as empty string.

internal:0:0-0: Error: Parsing list expression item at index 0 failed.
internal:0:0-0: Error: Invalid set elem at index 0.
internal:0:0-0: Error: Invalid set elem expression.
internal:0:0-0: Error: Parsing command array at index 2 failed.

Fixes: 586ad210368b ("libnftables: Implement JSON parser")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agocache: don't crash when filter is NULL
Florian Westphal [Tue, 1 Apr 2025 14:29:14 +0000 (16:29 +0200)] 
cache: don't crash when filter is NULL

a delete request will cause a crash in obj_cache_dump, move the deref
into the filter block.

Fixes: dbff26bfba83 ("cache: consolidate reset command")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoexpression: incorrect assert() list_expr_to_binop
Pablo Neira Ayuso [Mon, 31 Mar 2025 22:36:27 +0000 (00:36 +0200)] 
expression: incorrect assert() list_expr_to_binop

assert() logic is reversed, all expressions in the list are handled,
including the first.

  src/expression.c:1285: list_expr_to_binop: Assertion `first' failed.

Fixes: 53d6bb992445 ("expression: initialize list of expression to silence gcc compile warning")
Reported-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agoevaluate: only allow stateful statements in set and map definitions
Florian Westphal [Mon, 31 Mar 2025 15:23:20 +0000 (17:23 +0200)] 
evaluate: only allow stateful statements in set and map definitions

The bison parser doesn't allow this to happen due to grammar
restrictions, but the json input has no such issues.

The bogon input assigns 'notrack' which triggers:
BUG: unknown stateful statement type 19
nft: src/netlink_linearize.c:1061: netlink_gen_stmt_stateful: Assertion `0' failed.

After patch, we get:
Error: map statement must be stateful

Fixes: 07958ec53830 ("json: add set statement list support")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: compact STMT_F_STATEFUL checks
Florian Westphal [Mon, 31 Mar 2025 15:23:19 +0000 (17:23 +0200)] 
evaluate: compact STMT_F_STATEFUL checks

We'll gain another F_STATEFUL check in a followup patch,
so lets condense the pattern into a helper to reduce copypaste.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoexpression: don't try to import empty string
Florian Westphal [Thu, 27 Mar 2025 15:17:11 +0000 (16:17 +0100)] 
expression: don't try to import empty string

The bogon will trigger the assertion in mpz_import_data:
src/expression.c:418: constant_expr_alloc: Assertion `(((len) + (8) - 1) / (8)) > 0' failed.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoexpression: initialize list of expression to silence gcc compile warning
Pablo Neira Ayuso [Mon, 31 Mar 2025 15:15:39 +0000 (17:15 +0200)] 
expression: initialize list of expression to silence gcc compile warning

The helper function to translate flagcmp expression to binop expression
results in the following compile warning.

  src/expression.c: In function 'list_expr_to_binop':
  src/expression.c:1286:16: warning: 'last' may be used uninitialized [-Wmaybe-uninitialized]
  1286 |         return last;

While at it, add assert() to validate the premises where this function
can be called.

Fixes: 4d5990c92c83 ("src: transform flag match expression to binop expression from parser")
Reported-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agojson: fix error propagation when parsing binop lhs/rhs
Florian Westphal [Mon, 31 Mar 2025 12:27:47 +0000 (14:27 +0200)] 
json: fix error propagation when parsing binop lhs/rhs

Malformed input returns NULL when decoding left/right side of binop.
This causes a NULL dereference in expr_evaluate_binop; left/right must
point to a valid expression.

Fix this in the parser, else would have to sprinkle NULL checks all over
the evaluation code.

After fix, loading the bogon yields:
internal:0:0-0: Error: Malformed object (too many properties): '{}'.
internal:0:0-0: Error: could not decode binop rhs, '<<'.
internal:0:0-0: Error: Invalid mangle statement value
internal:0:0-0: Error: Parsing expr array at index 1 failed.
internal:0:0-0: Error: Parsing command array at index 3 failed.

Fixes: 0ac39384fd9e ("json: Accept more than two operands in binary expressions")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agotests: shell: Fix owner/0002-persist on aarch64
Phil Sutter [Sun, 23 Mar 2025 21:46:18 +0000 (22:46 +0100)] 
tests: shell: Fix owner/0002-persist on aarch64

Not sure if arch-specific, but for some reason src/nft wrapper script
would call src/.libs/lt-nft and thus the owner appeared as 'lt-nft'
instead of the expected 'nft'. Cover for that by extracting the expected
program name from /proc.

Fixes: b5205165bd708 ("tests: shell: Extend table persist flag test a bit")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: Add socat availability feature test
Phil Sutter [Thu, 27 Mar 2025 17:44:49 +0000 (18:44 +0100)] 
tests: shell: Add socat availability feature test

Several tests did this manually and skipped if unavail, others just
implicitly depended on the tool.

Note that for the sake of simplicity, this will skip
packetpath/tcp_options test entirely when it did a partial run before.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
4 months agojson: don't BUG when asked to list synproxies
Florian Westphal [Thu, 27 Mar 2025 16:32:00 +0000 (17:32 +0100)] 
json: don't BUG when asked to list synproxies

"-j list synproxys" triggers a BUG().

Rewrite this so that all enum values are handled so the compiler can alert
us to a missing value in case there are more commands in the future.

While at it, implement a few low-hanging fruites as well.

Not-yet-supported cases are simply ignored.

v2: return EOPNOTSUPP for unsupported commands (Pablo Neira Ayuso)

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agojson: disallow empty concatenation
Pablo Neira Ayuso [Thu, 27 Mar 2025 15:32:16 +0000 (16:32 +0100)] 
json: disallow empty concatenation

Disallow empty concatenation in set declaration in json.

 internal:0:0-0: Error: Empty concatenation
 internal:0:0-0: Error: Invalid set type.
 internal:0:0-0: Error: Parsing command array at index 1 failed.

Joint work with Florian Westphal.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agosrc: remove flagcmp expression
Pablo Neira Ayuso [Wed, 26 Mar 2025 20:54:13 +0000 (21:54 +0100)] 
src: remove flagcmp expression

This expression is not used anymore, since:

 ("src: transform flag match expression to binop expression from parser")

remove it.

This completes the revert of c3d57114f119 ("parser_bison: add shortcut
syntax for matching flags without binary operations"), except the parser
chunk for backwards compatibility.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agosrc: transform flag match expression to binop expression from parser
Pablo Neira Ayuso [Wed, 26 Mar 2025 20:54:08 +0000 (21:54 +0100)] 
src: transform flag match expression to binop expression from parser

Transform flagcmp expression to a relational with binop on the left hand
side, ie.

         relational
          /      \
       binop    value
       /   \
 payload  mask

Add list_expr_to_binop() to make this transformation.

Goal is two-fold:

- Allow -o/--optimize to pick up on this representation.
- Remove the flagcmp expression in a follow up patch.

This prepare for the removal of the flagcmp expression added by:

  c3d57114f119 ("parser_bison: add shortcut syntax for matching flags without binary operations")

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agooptimize: compact bitmask matching in set/map
Pablo Neira Ayuso [Wed, 26 Mar 2025 20:54:06 +0000 (21:54 +0100)] 
optimize: compact bitmask matching in set/map

Check if right hand side of relational is a bitmask, ie.

     relational
       /   \
    ...     or
           /  \
       value   or
              /  \
         value    value

then, if left hand side is a binop expression, compare left and right
hand sides (not only left hand of this binop expression) to check for
redundant matches in consecutive rules, ie.

        relational
          /   \
       and     ...
      /   \
 payload  value

before this patch, only payload in the binop expression was compared.

This allows to compact several rules matching tcp flags in a set/map, eg.

 # nft -c -o -f ruleset.nft
 Merging:
 ruleset.nft:7:17-76:                 tcp flags & (fin | syn | rst | ack | urg) == fin | ack | urg
 ruleset.nft:8:17-70:                 tcp flags & (fin | syn | rst | ack | urg) == fin | ack
 ruleset.nft:9:17-64:                 tcp flags & (fin | syn | rst | ack | urg) == fin
 ruleset.nft:10:17-70:                 tcp flags & (fin | syn | rst | ack | urg) == syn | ack
 ruleset.nft:11:17-64:                 tcp flags & (fin | syn | rst | ack | urg) == syn
 ruleset.nft:12:17-70:                 tcp flags & (fin | syn | rst | ack | urg) == rst | ack
 ruleset.nft:13:17-64:                 tcp flags & (fin | syn | rst | ack | urg) == rst
 ruleset.nft:14:17-70:                 tcp flags & (fin | syn | rst | ack | urg) == ack | urg
 ruleset.nft:15:17-64:                 tcp flags & (fin | syn | rst | ack | urg) == ack
 into:
        tcp flags & (fin | syn | rst | ack | urg) == { fin | ack | urg, fin | ack, fin, syn | ack, syn, rst | ack, rst, ack | urg, ack }
 Merging:
 ruleset.nft:17:17-61:                 tcp flags & (ack | urg) == ack jump ack_chain
 ruleset.bft:18:17-61:                 tcp flags & (ack | urg) == urg jump urg_chain
 into:
        tcp flags & (ack | urg) vmap { ack : jump ack_chain, urg : jump urg_chain }

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agooptimize: incorrect comparison for reject statement
Pablo Neira Ayuso [Wed, 26 Mar 2025 20:54:04 +0000 (21:54 +0100)] 
optimize: incorrect comparison for reject statement

Logic is reverse, this should returns false if the compared reject
expressions are not the same.

Fixes: 38d48fe57fff ("optimize: fix reject statement")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoexpression: add __EXPR_MAX and use it to define EXPR_MAX
Pablo Neira Ayuso [Wed, 26 Mar 2025 20:54:01 +0000 (21:54 +0100)] 
expression: add __EXPR_MAX and use it to define EXPR_MAX

EXPR_MAX was never updated to the newest expression, add __EXPR_MAX and
use it to define EXPR_MAX.

Add case to expr_ops() other gcc complains with a warning on the
__EXPR_MAX case is not handled.

Fixes: 347039f64509 ("src: add symbol range expression to further compact intervals")
Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agojson: return error if table does not exist
Florian Westphal [Thu, 27 Mar 2025 08:07:52 +0000 (09:07 +0100)] 
json: return error if table does not exist

Identical bug and thus same fix as
853d3a2d3cbd ("rule: return error if table does not exist"),
but this time for json.

Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: missing ct count elements in new set_stmt test
Pablo Neira Ayuso [Sat, 22 Mar 2025 20:43:26 +0000 (21:43 +0100)] 
tests: shell: missing ct count elements in new set_stmt test

Add missing entries to dump file.

Reported-by: Florian Westphal <fw@strlen.de>
Fixes: 1f3d0b9cf9cc ("tests: shell: extend coverage for set element statements")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agoevaluate: don't update cache for anonymous chains
Florian Westphal [Wed, 19 Mar 2025 20:05:53 +0000 (21:05 +0100)] 
evaluate: don't update cache for anonymous chains

Chain lookup needs a name, not a numerical id.
After patch, loading bogon gives following errors:

Error: No symbol type information a b index 1 10.1.26.a

v2: Don't return an error, just make it a no-op (Pablo Neira Ayuso)

Fixes: c330152b7f77 ("src: support for implicit chain bindings")
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agojson: make sure timeout list is initialised
Florian Westphal [Fri, 21 Mar 2025 11:53:40 +0000 (12:53 +0100)] 
json: make sure timeout list is initialised

On parser error, obj_free will iterate this list.
Included json bogon crashes due to null deref because
list head initialisation did not yet happen.

Fixes: c82a26ebf7e9 ("json: Add ct timeout support")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agotests: shell: extend coverage for set element statements
Pablo Neira Ayuso [Fri, 21 Mar 2025 10:00:40 +0000 (11:00 +0100)] 
tests: shell: extend coverage for set element statements

Add a test to cover the existing set element statements.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: consolidate connlimit grammar rule for set elements
Pablo Neira Ayuso [Thu, 20 Mar 2025 11:45:54 +0000 (12:45 +0100)] 
parser_bison: consolidate connlimit grammar rule for set elements

Define ct_limit_stmt_alloc and ct_limit_args to follow similar idiom
that is used for counters.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: consolidate last grammar rule for set elements
Pablo Neira Ayuso [Thu, 20 Mar 2025 10:28:57 +0000 (11:28 +0100)] 
parser_bison: consolidate last grammar rule for set elements

Define last_stmt_alloc and last_args to follow similar idiom that is
used for counters.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: consolidate quota grammar rule for set elements
Pablo Neira Ayuso [Thu, 20 Mar 2025 09:53:00 +0000 (10:53 +0100)] 
parser_bison: consolidate quota grammar rule for set elements

Define quota_stmt_alloc and quota_args to follow similar idiom that is
used for counters.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: consolidate limit grammar rule for set elements
Pablo Neira Ayuso [Thu, 20 Mar 2025 11:43:51 +0000 (12:43 +0100)] 
parser_bison: consolidate limit grammar rule for set elements

Define limit_stmt_alloc and limit_args to follow similar idiom that is
used for counters.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: consolidate counter grammar rule for set elements
Pablo Neira Ayuso [Thu, 20 Mar 2025 09:43:42 +0000 (10:43 +0100)] 
parser_bison: consolidate counter grammar rule for set elements

Use existing grammar rules to parse counters to simplify parser.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: fix assertion failure with malformed map definitions
Florian Westphal [Thu, 20 Mar 2025 13:33:05 +0000 (14:33 +0100)] 
evaluate: fix assertion failure with malformed map definitions

Included bogon triggers:
nft: src/evaluate.c:2267: expr_evaluate_mapping: Assertion `set->data != NULL' failed.

After this fix, following errors will be shown:
Error: unqualified type invalid specified in map definition. Try "typeof expression" instead of "type datatype".
map m {
    ^
map m {
    ^
Error: map has no mapping data

Fixes: 343a51702656 ("src: store expr, not dtype to track data in sets")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agorule: return error if table does not exist
Florian Westphal [Thu, 20 Mar 2025 13:31:42 +0000 (14:31 +0100)] 
rule: return error if table does not exist

The bogon triggers segfault due to NULL dereference.  Error out and set
errno to ENOENT; caller uses strerror() in the errmsg.

After fix, loading reproducer results in:
/tmp/A:2:1-18: Error: Could not process rule: No such file or directory
list table inet p
^^^^^^^^^^^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: don't allow nat map with specified protocol
Florian Westphal [Thu, 20 Mar 2025 08:39:20 +0000 (09:39 +0100)] 
evaluate: don't allow nat map with specified protocol

Included bogon asserts:
src/netlink_linearize.c:1305: netlink_gen_nat_stmt: Assertion `stmt->nat.proto == NULL' failed.

The comment right above the assertion says:
  nat_stmt evaluation step doesn't allow
  STMT_NAT_F_CONCAT && stmt->nat.proto.

... except it does allow it.  Disable this.

Fixes: c68314dd4263 ("src: infer NAT mapping with concatenation from set")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoexpression: tolerate named set protocol dependency
Florian Westphal [Thu, 20 Mar 2025 08:34:45 +0000 (09:34 +0100)] 
expression: tolerate named set protocol dependency

Included test will fail with:
/dev/stdin:8:38-52: Error: Transparent proxy support requires transport protocol match
   meta l4proto @protos tproxy to :1088
                        ^^^^^^^^^^^^^^^
Tolerate a set reference too.  Because the set can be empty (or there
can be removals later), add a fake 0-rhs value.

This will make pctx_update assign proto_unknown as the transport protocol
in use, Thats enough to avoid 'requires transport protocol' error.

v2: restrict it to meta lhs for now (Pablo Neira Ayuso)

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1686
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agonetlink_delinerize: add more restrictions on meta nfproto removal
Florian Westphal [Sun, 16 Mar 2025 13:10:26 +0000 (14:10 +0100)] 
netlink_delinerize: add more restrictions on meta nfproto removal

We can't remove 'meta nfproto' dependencies for all cases.
Its removed for ip/ip6 families, this works fine.

But for others, e.g. inet, removal is not as simple.
For example

   meta nfproto ipv4 ct protocol tcp

is listed as 'ct protocol tcp', even when this is uses in the inet
table.

Meta L4PROTO removal checks were correct, but refactor this
into a helper function to split meta/ct checks from the common
calling function.

Ct check was lacking, we need to examine ct keys more closely
to figure out if they need to retain the network protocol depenency
or not.  Elide for NFT_CT_SRC/DST and its variants, as those imply
the network protocol to use, all others must keep it as-is.

Also extend test coverage for this.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1783
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoparser_bison: reject non-serializeable typeof expressions
Florian Westphal [Sun, 16 Mar 2025 21:39:10 +0000 (22:39 +0100)] 
parser_bison: reject non-serializeable typeof expressions

Included bogon asserts with:
BUG: unhandled key type 13
nft: src/intervals.c:73: setelem_expr_to_range: Assertion `0' failed.

This should be rejected at parser stage, but the check for udata
support was only done on the first item in a concatenation.

After fix, parser rejects this with:
Error: primary expression type 'symbol' lacks typeof serialization

Fixes: 6e48df5329ea ("src: add "typeof" build/parse/print support")
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: py: remove unknown fields
Pablo Neira Ayuso [Wed, 19 Mar 2025 15:22:55 +0000 (16:22 +0100)] 
tests: py: remove unknown fields

Amend tests/py after libnftnl fixes:

 a7dfa49d34c7 ("expr: ct: print key name of id field")
 dba1b687a9a7 ("expr: payload: print tunnel header")

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agonetlink: fix stack buffer overrun when emitting ranged expressions
Florian Westphal [Fri, 14 Mar 2025 06:50:54 +0000 (07:50 +0100)] 
netlink: fix stack buffer overrun when emitting ranged expressions

Included bogon input generates following Sanitizer splat:

AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7...
WRITE of size 2 at 0x7fffffffcbe4 thread T0
    #0 0x0000003a68b8 in __asan_memset (src/nft+0x3a68b8) (BuildId: 3678ff51a5405c77e3e0492b9a985910efee73b8)
    #1 0x0000004eb603 in __mpz_export_data src/gmputil.c:108:2
    #2 0x0000004eb603 in netlink_export_pad src/netlink.c:256:2
    #3 0x0000004eb603 in netlink_gen_range src/netlink.c:471:2
    #4 0x0000004ea250 in __netlink_gen_data src/netlink.c:523:10
    #5 0x0000004e8ee3 in alloc_nftnl_setelem src/netlink.c:205:3
    #6 0x0000004d4541 in mnl_nft_setelem_batch src/mnl.c:1816:11

Problem is that the range end is emitted to the buffer at the *padded*
location (rounded up to next register size), but buffer sizing is
based of the expression length, not the padded length.

Also extend the test script: Capture stderr and if we see
AddressSanitizer warning, make it fail.

Same bug as the one fixed in 600b84631410 ("netlink: fix stack buffer overflow with sub-reg sized prefixes"),
just in a different function.

Apply same fix: no dynamic array + add a range check.

Joint work with Pablo Neira Ayuso.

Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agosrc: replace struct stmt_ops by type field in struct stmt
Pablo Neira Ayuso [Mon, 17 Mar 2025 22:19:49 +0000 (23:19 +0100)] 
src: replace struct stmt_ops by type field in struct stmt

Shrink struct stmt in 8 bytes.

__stmt_ops_by_type() provides an operation for STMT_INVALID since this
is required by -o/--optimize.

There are many checks for stmt->ops->type, which is the most accessed
field, that can be trivially replaced.

BUG() uses statement type enum instead of name.

Similar to:

 68e76238749f ("src: expr: add and use expr_name helper").
 72931553828a ("src: expr: add expression etype")
 2cc91e6198e7 ("src: expr: add and use internal expr_ops helper")

Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agosrc: print set element with multi-word description in single one line
Pablo Neira Ayuso [Thu, 13 Mar 2025 21:28:27 +0000 (22:28 +0100)] 
src: print set element with multi-word description in single one line

If the set element:

- represents a mapping
- has a timeout
- has a comment
- has counter/quota/limit
- concatenation (already printed in a single line before this patch)

ie. if the set element requires several words, then print it in one
single line.

Before this patch:

 table ip x {
      set y {
            typeof ip saddr
            counter
            elements = { 192.168.10.35 counter packets 0 bytes 0, 192.168.10.101 counter packets 0 bytes 0,
                         192.168.10.135 counter packets 0 bytes 0 }
      }
 }

After this patch:

 table ip x {
      set y {
            typeof ip saddr
            counter
            elements = { 192.168.10.35 counter packets 0 bytes 0,
 192.168.10.101 counter packets 0 bytes 0,
                         192.168.10.135 counter packets 0 bytes 0 }
      }
 }

Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: move interval flag compat check after set key evaluation
Florian Westphal [Mon, 17 Mar 2025 11:56:36 +0000 (12:56 +0100)] 
evaluate: move interval flag compat check after set key evaluation

Without this, included bogon asserts with:
BUG: unhandled key type 13
nft: src/intervals.c:73: setelem_expr_to_range: Assertion `0' failed.

... because we no longer evaluate set->key/data.

Move the check to the tail of the function, right before assiging
set->existing_set, so that set->key has been evaluated.

Fixes: ceab53cee499 ("evaluate: don't allow merging interval set/map with non-interval one")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: don't allow merging interval set/map with non-interval one
Florian Westphal [Thu, 13 Mar 2025 09:38:25 +0000 (10:38 +0100)] 
evaluate: don't allow merging interval set/map with non-interval one

Included bogon asserts with:
BUG: invalid data expression type range_value

Pablo says: "Reject because flags interval is lacking".
Make it so.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: fix expression data corruption
Florian Westphal [Tue, 11 Mar 2025 13:07:03 +0000 (14:07 +0100)] 
evaluate: fix expression data corruption

Sometimes nftables will segfault when doing error-unwind of the included
afl-generated bogon.

The problem is the unconditional write access to expr->set_flags in
expr_evaluate_map():

   mappings->set_flags |= NFT_SET_MAP;

... but mappings can point to EXPR_VARIABLE (legal), where this will flip
a bit in unused, but allocated memory (i.e., has no effect).

In case of the bogon, mapping is EXPR_RANGE_SYMBOL, and the store can flip
a bit in identifier_range[1], this causes crash when the pointer is freed.

We can't use expr->set_flags unconditionally, so rework this to pass
set_flags as argument and place all read and write accesses in places where
we've made sure we are dealing with EXPR_SET.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agotests: shell: skip interval size tests on kernel that lack rbtree size fix
Florian Westphal [Mon, 10 Mar 2025 12:42:29 +0000 (13:42 +0100)] 
tests: shell: skip interval size tests on kernel that lack rbtree size fix

Skip these tests for older kernels.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agonetlink_linearize: reduce register waste with non-constant binop expressions
Pablo Neira Ayuso [Mon, 10 Mar 2025 19:11:44 +0000 (20:11 +0100)] 
netlink_linearize: reduce register waste with non-constant binop expressions

Register use is not good with bitwise operations that involve three or
more selectors, eg.

 mark set ip dscp and 0x3 or ct mark or meta mark
  [ payload load 1b @ network header + 1 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
  [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
  [ bitwise reg 1 = ( reg 1 & 0x00000003 ) ^ 0x00000000 ]
  [ ct load mark => reg 2 ]
  [ bitwise reg 1 = ( reg 1 | reg 2 ) ]
  [ meta load mark => reg 3 ]   <--- this could use register 2 instead!
  [ bitwise reg 1 = ( reg 1 | reg 3 ) ]
  [ meta set mark with reg 1 ]

register 3 is used to store meta mark, however, register 2 can be
already use since register 1 already stores the partial result of the
bitwise operation for this expression.

After this fix:

  [ payload load 1b @ network header + 1 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
  [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
  [ bitwise reg 1 = ( reg 1 & 0x00000003 ) ^ 0x00000000 ]
  [ ct load mark => reg 2 ]
  [ bitwise reg 1 = ( reg 1 | reg 2 ) ]
  [ meta load mark => reg 2 ]            <--- recycle register 2
  [ bitwise reg 1 = ( reg 1 | reg 2 ) ]
  [ meta set mark with reg 1 ]

Release source register in bitwise operation given destination register
already stores the partial result of the expression.

Extend tests/py to cover this.

Fixes: 54bfc38c522b ("src: allow binop expressions with variable right-hand operands")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: don't crash if range has same start and end interval
Florian Westphal [Mon, 10 Mar 2025 07:29:37 +0000 (08:29 +0100)] 
evaluate: don't crash if range has same start and end interval

In this case, evaluation step replaces the range expression with a
single value and we'd crash as range->left/right contain garbage
values.

Simply replace the input expression with the evaluation result.

Also add a test case modeled on the afl reproducer.

Fixes: fe6cc0ad29cd ("evaluate: consolidate evaluation of symbol range expression")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agotests: extend reset test case to cover interval set and map type
Florian Westphal [Thu, 6 Mar 2025 13:23:31 +0000 (14:23 +0100)] 
tests: extend reset test case to cover interval set and map type

Make sure segtree processing doesn't drop associated stateful elements.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agosegtree: incomplete output in get element command with maps
Pablo Neira Ayuso [Thu, 6 Mar 2025 17:49:21 +0000 (18:49 +0100)] 
segtree: incomplete output in get element command with maps

get element command displays an incomplete range.

Using this simple test ruleset:

 table ip x {
        map y {
                typeof ip saddr : meta mark
                counter
                flags interval,timeout
                elements = { 1.1.1.1-1.1.1.10 timeout 10m : 20, 2.2.2.2-2.2.2.5 timeout 10m : 30}
        }

then, invoking the get element command:

 # nft get element x y { 1.1.1.2 }

results in, before (incomplete output):

 table ip x {
        map y {
                type ipv4_addr : mark
                flags interval,timeout
                elements = { 1.1.1.1 counter packets 0 bytes 0 timeout 10m expires 1m24s160ms : 0x00000014 }
        }
 }

Note that it displays 1.1.1.1, instead of 1.1.1.1-1.1.1.10.

After this fix:

 table ip x {
        map y {
                type ipv4_addr : mark
                flags interval,timeout
                elements = { 1.1.1.1-1.1.1.10 counter packets 0 bytes 0 timeout 10m expires 1m24s160ms : 0x00000014 }
        }
 }

Fixes: a43cc8d53096 ("src: support for get element command")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agosrc: fix reset element support for interval set type
Florian Westphal [Thu, 6 Mar 2025 13:23:30 +0000 (14:23 +0100)] 
src: fix reset element support for interval set type

Running reset command yields on an interval (rbtree) set yields:
nft reset element inet filter rbtreeset {1.2.3.4}
BUG: unhandled op 8

This is easy to fix, CMD_RESET doesn't add or remove so it should be
treated like CMD_GET.

Unfortunately, this still doesn't work properly:

nft get element inet filter rbset {1.2.3.4}
returns:
 ... elements = { 1.2.3.4 }

but its expected that "get" and "reset" also return stateful objects
associated with the element.  This works for other set types, but for
rbtree, the list of statements gets lost during segtree processing.

After fix, get/reset returns:
  elements = { 1.2.3.4 counter packets 10 ...

A follow up patch will add a test case.

Fixes: 83e0f4402fb7 ("Implement 'reset {set,map,element}' commands")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agonetlink_delinearize: support for bitfield payload statement with binary operation
Pablo Neira Ayuso [Fri, 28 Feb 2025 15:18:43 +0000 (16:18 +0100)] 
netlink_delinearize: support for bitfield payload statement with binary operation

Add a new function to deal with payload statement delinearization with
binop expression.

Infer the payload offset from the mask, then walk the template list to
determine if estimated offset falls within a matching header field. If
so, then validate that this is not a raw expression but an actual
bitfield matching. Finally, trim the payload expression length
accordingly and adjust the payload offset.

instead of:

@nh,8,5 set 0x0

it displays:

ip dscp and 0x1

Update tests/py to cover for this enhancement.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: support for bitfield payload statement with binary operation
Pablo Neira Ayuso [Thu, 27 Feb 2025 17:36:16 +0000 (18:36 +0100)] 
evaluate: support for bitfield payload statement with binary operation

Update bitfield payload statement support to allow for bitwise
and/or/xor updates. Adjust payload expression to fetch 16-bits for
mangling while leaving unmodified bits intact.

 # nft --debug=netlink add rule x y ip dscp set ip dscp or 0x1
 ip x y
   [ payload load 2b @ network header + 0 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x0000fbff ) ^ 0x00000400 ]
   [ payload write reg 1 => 2b @ network header + 0 csum_type 1 csum_off 10 csum_flags 0x0 ]

Skip expr_evaluate_bits() transformation since these are only useful
for payload matching and set lookups.

Listing still shows a raw expression:

  # nft list ruleset
    ...
                    @nh,8,5 set 0x0

The follow up patch completes it:

  ("netlink_delinearize: support for bitfield payload statement with binary operation")

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1698
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agoevaluate: reject unsupported expressions in payload statement for bitfields
Pablo Neira Ayuso [Fri, 28 Feb 2025 14:57:18 +0000 (15:57 +0100)] 
evaluate: reject unsupported expressions in payload statement for bitfields

The payload statement evaluation pretends that it can handle any
expression for bitfields, but the existing evaluation code only knows
how to handle value expression.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>