]> git.ipfire.org Git - thirdparty/nftables.git/log
thirdparty/nftables.git
17 months agoparser: compact interval typeof rules
Florian Westphal [Tue, 27 Feb 2024 14:50:05 +0000 (15:50 +0100)] 
parser: compact interval typeof rules

There are two nearly identical blocks for typeof maps:
one with INTERVAL keyword present and one without.

Compact this into a single block.

Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agosrc: improve error reporting for destroy command
谢致邦 (XIE Zhibang) [Wed, 21 Feb 2024 15:17:09 +0000 (15:17 +0000)] 
src: improve error reporting for destroy command

Example for older kernels (<6.3):
nft destroy table ip missingtable

Before:
Error: Could not process rule: Invalid argument

After:
Error: "destroy" command is not supported, perhaps kernel support is
missing?

Fixes: e1dfd5cc4c46 ("src: add support to command "destroy"")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agoparser_json: allow 0 offsets again
Florian Westphal [Mon, 26 Feb 2024 09:34:59 +0000 (10:34 +0100)] 
parser_json: allow 0 offsets again

Its valid in case of tcp option removal:

[ {
   "reset": {
     "tcp option": {
       "base": 123,
       "len": 0,
       "offset": 0
   }

This makes nft-test.py -j pass again.

Fixes: e08627257ecf ("parser: reject raw payload expressions with 0 length")
Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agotests: shell: add more json dumps
Florian Westphal [Mon, 26 Feb 2024 09:35:16 +0000 (10:35 +0100)] 
tests: shell: add more json dumps

Those are expected to be stable, so add them.
Some are not 100% correct, as "typeof" is misprinted as "type" (json output
and input parser lack support for this), but for these files the "type"
is valid too.

This will allow better validation once proper "typeof" support is
added to json.c and json-parser.c.

Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agotests: py: add missing json.output data
Florian Westphal [Mon, 26 Feb 2024 08:45:43 +0000 (09:45 +0100)] 
tests: py: add missing json.output data

Fixes: bridge/vlan.t: WARNING: line 56: ...
Fixes: 8b9ae77598b4 ("tests: never merge across non-expression statements redux 2")
Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agotests: shell: add regression test for catchall double-delete
Florian Westphal [Sun, 18 Feb 2024 11:12:46 +0000 (12:12 +0100)] 
tests: shell: add regression test for catchall double-delete

Test case for:
 b1db244ffd04 ("netfilter: nf_tables: check if catch-all set element is active in next generation")

Reported-by: lonial con <kongln9170@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agotests: shell: permit use of host-endian constant values in set lookup keys
Florian Westphal [Wed, 14 Feb 2024 10:41:30 +0000 (11:41 +0100)] 
tests: shell: permit use of host-endian constant values in set lookup keys

extend an existing test case with the afl input to cover in/output.

A new test case is added to test linearization, delinearization and
matching

Fixes: c0080feb0d03 ("evaluate: permit use of host-endian constant values in set lookup keys")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agoexpression: missing line in describe command with invalid expression
Pablo Neira Ayuso [Tue, 13 Feb 2024 16:09:20 +0000 (17:09 +0100)] 
expression: missing line in describe command with invalid expression

Before:

 duh@testbed:~# nft describe blah
 symbol expression, datatype invalid (invalid)duh@testbed:#

After:

 duh@testbed:~# nft describe blah
 symbol expression, datatype invalid (invalid)
 duh@testbed:#

Fixes: 48aca2de80a7 ("iptopt: fix crash with invalid field/type combo")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agoevaluate: permit use of host-endian constant values in set lookup keys
Pablo Neira Ayuso [Mon, 12 Feb 2024 15:46:29 +0000 (16:46 +0100)] 
evaluate: permit use of host-endian constant values in set lookup keys

AFL found following crash:

table ip filter {
map ipsec_in {
typeof ipsec in reqid . iif : verdict
flags interval
}

chain INPUT {
type filter hook input priority filter; policy drop;
ipsec in reqid . 100 @ipsec_in
}
}

Which yields:
nft: evaluate.c:1213: expr_evaluate_unary: Assertion `!expr_is_constant(arg)' failed.

All existing test cases with constant values use big endian values, but
"iif" expects host endian values.

As raw values were not supported before, concat byteorder conversion
doesn't handle constants.

Fix this:

1. Add constant handling so that the number is converted in-place,
   without unary expression.

2. Add the inverse handling on delinearization for non-interval set
   types.
   When dissecting the concat data soup, watch for integer constants where
   the datatype indicates host endian integer.

Last, extend an existing test case with the afl input to cover
in/output.

A new test case is added to test linearization, delinearization and
matching.

Based on original patch from Florian Westphal, patch subject and
description wrote by him.

Fixes: b422b07ab2f9 ("src: permit use of constant values in set lookup keys")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agonetlink_delinearize: move concat and value postprocessing to helpers
Florian Westphal [Fri, 19 Jan 2024 12:47:08 +0000 (13:47 +0100)] 
netlink_delinearize: move concat and value postprocessing to helpers

No functional changes intended.

Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agocache: Always set NFT_CACHE_TERSE for list cmd with --terse
Phil Sutter [Thu, 8 Feb 2024 01:10:48 +0000 (02:10 +0100)] 
cache: Always set NFT_CACHE_TERSE for list cmd with --terse

This fixes at least 'nft -t list table ...' and 'nft -t list set ...'.

Note how --terse handling for 'list sets/maps' remains in place since
setting NFT_CACHE_TERSE does not fully undo NFT_CACHE_SETELEM: setting
both enables fetching of anonymous sets which is pointless for that
command.

Reported-by: anton.khazan@gmail.com
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1735
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agonetlink_linearize: add assertion to catch for buggy byteorder
Pablo Neira Ayuso [Thu, 8 Feb 2024 12:20:43 +0000 (13:20 +0100)] 
netlink_linearize: add assertion to catch for buggy byteorder

Add assertion to catch buggy bytecode where unary expression is present
with 1-byte selectors, where no byteorder conversion is required.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agoevaluate: skip byteorder conversion for selector smaller than 2 bytes
Pablo Neira Ayuso [Wed, 7 Feb 2024 22:53:32 +0000 (23:53 +0100)] 
evaluate: skip byteorder conversion for selector smaller than 2 bytes

Add unary expression to trigger byteorder conversion for host byteorder
selectors only if selectors length is larger or equal than 2 bytes.

 # cat test.nft
 table ip x {
        set test {
                type ipv4_addr . ether_addr . inet_proto
                flags interval
        }

        chain y {
                ip saddr . ether saddr . meta l4proto @test counter
        }
 }

 # nft -f test.nft
 ip x y
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ payload load 6b @ link header + 6 => reg 9 ]
  [ meta load l4proto => reg 11 ]
  [ byteorder reg 11 = hton(reg 11, 2, 1) ] <--- should not be here
  [ lookup reg 1 set test ]
  [ counter pkts 0 bytes 0 ]

Fixes: 1017d323cafa ("src: support for selectors with different byteorder with interval concatenations")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agotests/shell: no longer support unprettified ".json-nft" files
Thomas Haller [Fri, 9 Feb 2024 12:10:39 +0000 (13:10 +0100)] 
tests/shell: no longer support unprettified ".json-nft" files

By now, all ".json-nft" files are prettified and will be generated in
that form.

Drop the fallback code that accepts them in the previous form.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agotests: shell: Pretty-print all *.json-nft dumps
Phil Sutter [Thu, 8 Feb 2024 13:30:17 +0000 (14:30 +0100)] 
tests: shell: Pretty-print all *.json-nft dumps

The problem with single line output as produced by 'nft -j list ruleset'
is its incompatibility to unified diff format as any change in this
single line will produce a diff which contains the old and new lines in
total. This is not just unreadable but will blow up patches which may
exceed mailinglists' mail size limits.

Convert them all at once by feeding their contents to
tests/shell/helpers/json-pretty.sh.

Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agotests/shell: have .json-nft dumps prettified to wrap lines
Thomas Haller [Thu, 7 Dec 2023 09:08:50 +0000 (10:08 +0100)] 
tests/shell: have .json-nft dumps prettified to wrap lines

Previously, the .json-nft file in git contains the output of `nft -j
list ruleset`. This is one long line and makes diffs harder to review.

Instead, have the prettified .json-nft file committed to git.

- the diff now operates on the prettified version. That means, it
  compares essentially

     - `nft -j list ruleset | json-sanitize-ruleset.sh | json-pretty.sh`
     - `cat "$TEST.json-nft" | json-pretty.sh`

  The script "json-diff-pretty.sh" is no longer used. It is kept
  however, because it might be a useful for manual comparing files.

  Note that "json-sanitize-ruleset.sh" and "json-pretty.sh" are still
  two separate scripts and called at different times. They also do
  something different. The former mangles the JSON to account for changes
  that are not stable (in the JSON data itself), while the latter only
  pretty prints it.

- when generating a new .json-nft dump file, the file will be updated to
  use the new, prettified format, unless the file is in the old format
  and needs no update. This means, with DUMPGEN=y, old style is preserved
  unless an update becomes necessary.

This requires "json-pretty.sh" having stable output, as those files are
committed to git. This is probably fine.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agotests: shell: missing auto-merge in json output
Pablo Neira Ayuso [Wed, 7 Feb 2024 21:24:05 +0000 (22:24 +0100)] 
tests: shell: missing auto-merge in json output

Several tests reports DUMP_FAILED because it was missing the auto-merge
flag. That is, the original json dump was not correct. Update tests
accordingly now that json support provides an automerge flag.

Fixes: a4034c66b03e ("json: Support sets' auto-merge option")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agocache: Optimize caching for 'list tables' command
Phil Sutter [Tue, 6 Feb 2024 18:26:57 +0000 (19:26 +0100)] 
cache: Optimize caching for 'list tables' command

No point in fetching anything other than existing tables from kernel:
'list tables' merely prints existing table names, no contents.

Also populate filter's family field to reduce overhead when listing
tables in one family with many tables in another one. It works without
further adjustments because nftnl_nlmsg_build_hdr() will use the value
for nfgen_family.

Reported-by: anton.khazan@gmail.com
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1735
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agoMakefile.am: don't silence -Wimplicit-function-declaration
Sam James [Wed, 7 Feb 2024 02:12:35 +0000 (02:12 +0000)] 
Makefile.am: don't silence -Wimplicit-function-declaration

This becomes an error in GCC 14 and Clang 16. It's a common
misconception that these warnings are invalid or simply noise for
Bison/parser files, but even if that were true, we'd need to handle it
somehow anyway. Silencing them does nothing, so stop doing that.

Further, I don't actually get any warnings to fix with bison-3.8.2. This
mirrors changes we've done in other netfilter.org projects.

Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agoevaluate: fix check for unknown in cmd_op_to_name
谢致邦 (XIE Zhibang) [Wed, 7 Feb 2024 15:10:20 +0000 (15:10 +0000)] 
evaluate: fix check for unknown in cmd_op_to_name

Example:
nft --debug=all destroy table ip missingtable

Before:
Evaluate unknown

After:
Evaluate destroy

Fixes: e1dfd5cc4c46 ("src: add support to command "destroy"")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
17 months agoevaluate: don't assert on net/transport header conflict
Florian Westphal [Tue, 16 Jan 2024 14:21:00 +0000 (15:21 +0100)] 
evaluate: don't assert on net/transport header conflict

before:
nft: evaluate.c:467: conflict_resolution_gen_dependency: Assertion `expr->payload.base == PROTO_BASE_LL_HDR' failed.
Aborted (core dumped)

conflict_resolution_gen_dependency() can only handle linklayer
conflicts, hence the assert.

Rename it accordingly.  Also rename resolve_protocol_conflict, it doesn't
do anything for != PROTO_BASE_LL_HDR and extend the assertion to that
function too.

Callers now enforce PROTO_BASE_LL_HDR prerequisite.

after:
Error: conflicting transport layer protocols specified: comp vs. udp
 ip6 nexthdr comp udp dport 4789
                  ^^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
17 months agodatatype: display 0s time datatype
Pablo Neira Ayuso [Thu, 25 Jan 2024 16:31:45 +0000 (17:31 +0100)] 
datatype: display 0s time datatype

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agotests: shell: cover netns removal for netdev and inet/ingress basechains
Pablo Neira Ayuso [Thu, 18 Jan 2024 21:58:02 +0000 (22:58 +0100)] 
tests: shell: cover netns removal for netdev and inet/ingress basechains

Add two tests to exercise netns removal with netdev and inet/ingress
basechains.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
17 months agotests: shell: netdevice removal for inet family
Pablo Neira Ayuso [Thu, 18 Jan 2024 21:30:12 +0000 (22:30 +0100)] 
tests: shell: netdevice removal for inet family

cover netdevice removal when such netdevice belongs to basechain.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agojson: Support sets' auto-merge option
Phil Sutter [Wed, 31 Jan 2024 16:30:24 +0000 (17:30 +0100)] 
json: Support sets' auto-merge option

If enabled, list the option as additional attribute with boolean value.

Fixes: e70354f53e9f6 ("libnftables: Implement JSON output support")
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1734
Signed-off-by: Phil Sutter <phil@nwl.cc>
18 months agotests: shell: add test to cover ct offload by using nft flowtables
Yi Chen [Mon, 22 Jan 2024 16:26:40 +0000 (00:26 +0800)] 
tests: shell: add test to cover ct offload by using nft flowtables

To cover kernel patch ("netfilter: nf_tables: set transport offset from mac header for netdev/egress").

Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agotests: py: remove huge-limit test cases
Florian Westphal [Thu, 18 Jan 2024 12:24:04 +0000 (13:24 +0100)] 
tests: py: remove huge-limit test cases

These tests will fail once the kernel checks for overflow
in the internal token bucken counter, so drop them.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agorule: fix sym refcount assertion
Florian Westphal [Mon, 15 Jan 2024 13:27:15 +0000 (14:27 +0100)] 
rule: fix sym refcount assertion

Scope release must happen last.
afl provided a reproducer where policy is a define, because
scope is released too early we get:
nft: src/rule.c:559: scope_release: Assertion `sym->refcnt == 1' failed.

... because chain->policy is EXPR_SYMBOL.

Fixes: 627c451b2351 ("src: allow variables in the chain priority specification")
Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agoevaluate: error out when store needs more than one 128bit register of align fixup
Florian Westphal [Mon, 15 Jan 2024 13:11:17 +0000 (14:11 +0100)] 
evaluate: error out when store needs more than one 128bit register of align fixup

Else this gives:
nft: evaluate.c:2983: stmt_evaluate_payload: Assertion `sizeof(data) * BITS_PER_BYTE >= masklen' failed.

For loads, this is already prevented via expr_evaluate_bits() which has:

  if (masklen > NFT_REG_SIZE * BITS_PER_BYTE)
      return expr_error(ctx->msgs, expr, "mask length %u exceeds allowed maximum of %u\n",
                        masklen, NFT_REG_SIZE * BITS_PER_BYTE);

But for the store path this isn't called.
The reproducer asks to store a 128 bit integer at bit offset 1, i.e.
17 bytes would need to be munged, but we can only handle up to 16 bytes
(one pseudo-register).

Fixes: 78936d50f306 ("evaluate: add support to set IPv6 non-byte header fields")
Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agoparser: reject raw payload expressions with 0 length
Florian Westphal [Fri, 12 Jan 2024 12:27:23 +0000 (13:27 +0100)] 
parser: reject raw payload expressions with 0 length

Reject this at parser stage.  Fix up the json input side too, else
reproducer gives:
nft: src/netlink.c:243: netlink_gen_raw_data: Assertion `len > 0' failed.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agopayload: only assert if l2 header base has no length
Florian Westphal [Thu, 11 Jan 2024 12:11:22 +0000 (13:11 +0100)] 
payload: only assert if l2 header base has no length

nftables will assert in some cases because the sanity check is done even
for network and transport header bases.

However, stacked headers are only supported for the link layer.
Move the assertion around and add a test case for this.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agoevaluate: release mpz type in expr_evaluate_list() error path
Pablo Neira Ayuso [Thu, 11 Jan 2024 21:14:34 +0000 (22:14 +0100)] 
evaluate: release mpz type in expr_evaluate_list() error path

Detected when running:

 # nft -f tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
 ==383222==ERROR: LeakSanitizer: detected memory leaks

 Direct leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x7fe7b54a9e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7fe7b538b9a9 in __gmp_default_allocate (/lib/x86_64-linux-gnu/libgmp.so.10+0xc9a9)

Fixes: 3671c4897003 ("evaluate: guard against NULL basetype")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agoevaluate: release key expression in error path of implicit map with unknown datatype
Pablo Neira Ayuso [Thu, 11 Jan 2024 21:04:27 +0000 (22:04 +0100)] 
evaluate: release key expression in error path of implicit map with unknown datatype

Detected when running:

 # nft -f tests/shell/testcases/bogons/nft-f/mapping_with_invalid_datatype_crash
 ==382584==ERROR: LeakSanitizer: detected memory leaks

 Direct leak of 144 byte(s) in 1 object(s) allocated from:
    #0 0x7fde06ca9e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7fde062924af in xmalloc src/utils.c:31
    #2 0x7fde0629266c in xzalloc src/utils.c:70
    #3 0x7fde06167299 in expr_alloc src/expression.c:46
    #4 0x7fde0616b014 in constant_expr_alloc src/expression.c:420
    #5 0x7fde06128e43 in expr_evaluate_map src/evaluate.c:2027
    #6 0x7fde06137b06 in expr_evaluate src/evaluate.c:2891
    #7 0x7fde06132417 in expr_evaluate_relational src/evaluate.c:2497
    #8 0x7fde06137b36 in expr_evaluate src/evaluate.c:2895
    #9 0x7fde06137d5f in stmt_evaluate_expr src/evaluate.c:2914
    #10 0x7fde061524c8 in stmt_evaluate src/evaluate.c:4646
    #11 0x7fde0615c9ee in rule_evaluate src/evaluate.c:5202
    #12 0x7fde061600c7 in cmd_evaluate_add src/evaluate.c:5422

Fixes: 70054e6e1c87 ("evaluate: catch implicit map expressions without known datatype")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agoevaluate: bail out if anonymous concat set defines a non concat expression
Pablo Neira Ayuso [Wed, 10 Jan 2024 18:05:35 +0000 (19:05 +0100)] 
evaluate: bail out if anonymous concat set defines a non concat expression

Iterate over the element list in the anonymous set to validate that all
expressions are concatenations, otherwise bail out.

  ruleset.nft:3:46-53: Error: expression is not a concatenation
               ip protocol . th dport vmap { tcp / 22 : accept, tcp . 80 : drop}
                                             ^^^^^^^^

This is based on a patch from Florian Westphal.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agoevaluate: do not fetch next expression on runaway number of concatenation components
Pablo Neira Ayuso [Wed, 10 Jan 2024 17:20:47 +0000 (18:20 +0100)] 
evaluate: do not fetch next expression on runaway number of concatenation components

If this is the last expression, then the runaway flag is set on and
evaluation bails in the next iteration, do not fetch next list element
which refers to the list head.

I found this by code inspection, I could not trigger any crash with this
one.

Fixes: ae1d54d1343f ("evaluate: do not crash on runaway number of concatenation components")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agoevaluate: skip anonymous set optimization for concatenations
Pablo Neira Ayuso [Wed, 10 Jan 2024 17:18:50 +0000 (18:18 +0100)] 
evaluate: skip anonymous set optimization for concatenations

Concatenation is only supported with sets. Moreover, stripping of the
set leads to broken ruleset listing, therefore, skip this optimization
for the concatenations.

Fixes: fa17b17ea74a ("evaluate: revisit anonymous set with single element optimization")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agoevaluate: add missing range checks for dup,fwd and payload statements
Florian Westphal [Thu, 11 Jan 2024 17:14:16 +0000 (18:14 +0100)] 
evaluate: add missing range checks for dup,fwd and payload statements

Else we assert with:
BUG: unknown expression type range
nft: src/netlink_linearize.c:912: netlink_gen_expr: Assertion `0' failed.

While at it, condense meta and exthdr to reuse the same helper.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agoevaluate: tproxy: move range error checks after arg evaluation
Florian Westphal [Thu, 11 Jan 2024 17:14:15 +0000 (18:14 +0100)] 
evaluate: tproxy: move range error checks after arg evaluation

Testing for range before evaluation will still crash us later during
netlink linearization, prefixes turn into ranges, symbolic expression
might hide a range/prefix.

So move this after the argument has been evaluated.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agoevaluate: error out when expression has no datatype
Florian Westphal [Thu, 11 Jan 2024 15:57:28 +0000 (16:57 +0100)] 
evaluate: error out when expression has no datatype

add rule ip6 f i rt2 addr . ip6 daddr  { dead:: . dead:: }

... will cause a segmentation fault, we assume expr->dtype is always
set.

rt2 support is incomplete, the template is uninitialised.

This could be fixed up, but rt2 (a subset of the deperecated type 0),
like all other routing headers, lacks correct dependency tracking.

Currently such routing headers are always assumed to be segment routing
headers, we would need to add dependency on 'Routing Type' field in the
routing header, similar to icmp type/code.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agodoc: clarify reject is supported at prerouting stage
Quan Tian [Wed, 10 Jan 2024 04:30:59 +0000 (04:30 +0000)] 
doc: clarify reject is supported at prerouting stage

It's supported since kernel commit f53b9b0bdc59 ("netfilter: introduce
support for reject at prerouting stage").

Reported-by: Dan Winship <danwinship@redhat.com>
Signed-off-by: Quan Tian <tianquan23@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agodoc: incorrect datatype description for icmpv6_type and icmpvx_code
Pablo Neira Ayuso [Tue, 9 Jan 2024 11:42:20 +0000 (12:42 +0100)] 
doc: incorrect datatype description for icmpv6_type and icmpvx_code

Fix incorrect description in manpage:

 ICMPV6 TYPE TYPE is icmpv6_type
 ICMPVX CODE TYPE is icmpx_code

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agotests: shell: extend coverage for netdevice removal
Pablo Neira Ayuso [Thu, 4 Jan 2024 23:48:33 +0000 (00:48 +0100)] 
tests: shell: extend coverage for netdevice removal

Add two extra tests to exercise netdevice removal path.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 months agotests: add a test case for double-flush bug in pipapo
Florian Westphal [Fri, 1 Dec 2023 14:49:18 +0000 (15:49 +0100)] 
tests: add a test case for double-flush bug in pipapo

Test for
'netfilter: nft_set_pipapo: skip inactive elements during set walk'.

Reported-by: Xingyuan Mo <hdthky0@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agodatatype: do not assert when value exceeds expected width
Florian Westphal [Fri, 22 Dec 2023 14:30:09 +0000 (15:30 +0100)] 
datatype: do not assert when value exceeds expected width

Inputs:
ip protocol . th dport { tcp / 22,  }'
or
th dport . ip protocol { tcp / 22,  }'

are not rejected at this time. 'list ruleset' yields:
 ip protocol & nft: src/gmputil.c:77: mpz_get_uint8: Assertion `cnt <= 1' failed.
or
 th dport & nft: src/gmputil.c:87: mpz_get_be16: Assertion `cnt <= 1' failed.

While this should be caught at input too, the print path should be more
robust, e.g. when there are direct nfnetlink users.

After this patch, the print functions fall back to
'integer_type_print' which can handle large numbers too.

Note that the output printed this way cannot be read back by nft;
it will dump something like:

  tcp dport & 18446739675663040512 . ip protocol 0 . 0

but thats better than assert().

v2: same problem exists for service too.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agotests: shell: prefer project nft to system-wide nft
Florian Westphal [Sat, 6 Jan 2024 12:23:24 +0000 (13:23 +0100)] 
tests: shell: prefer project nft to system-wide nft

Use $NFT (src/nft, in-tree binary), not the one installed by the distro.
Else we may not find newly added bugs unless user did "make install" or
bug has propagated to release.

Signed-off-by: Florian Westphal <fw@strlen.de>
18 months agodatatype: Describe rt symbol tables
Phil Sutter [Fri, 22 Dec 2023 16:00:44 +0000 (17:00 +0100)] 
datatype: Describe rt symbol tables

Implement a symbol_table_print() wrapper for the run-time populated
rt_symbol_tables which formats output similar to expr_describe() and
includes the data source.

Since these tables reside in struct output_ctx there is no implicit
connection between data type and therefore providing callbacks for
relevant datat types which feed the data into said wrapper is a simpler
solution than extending expr_describe() itself.

Signed-off-by: Phil Sutter <phil@nwl.cc>
18 months agodatatype: Initialize rt_symbol_tables' base field
Phil Sutter [Fri, 22 Dec 2023 15:53:14 +0000 (16:53 +0100)] 
datatype: Initialize rt_symbol_tables' base field

It is unconditionally accessed in symbol_table_print() so make sure it
is initialized to either BASE_DECIMAL (arbitrary) for empty or
non-existent source files or a proper value depending on entry number
format.

Signed-off-by: Phil Sutter <phil@nwl.cc>
18 months agodatatype: rt_symbol_table_init() to search for iproute2 configs
Phil Sutter [Fri, 15 Dec 2023 20:59:44 +0000 (21:59 +0100)] 
datatype: rt_symbol_table_init() to search for iproute2 configs

There is an ongoing effort among various distributions to tidy up in
/etc. The idea is to reduce contents to just what the admin manually
inserted to customize the system, anything else shall move out to /usr
(or so). The various files in /etc/iproute2 fall in that category as
they are seldomly modified.

The crux is though that iproute2 project seems not quite sure yet where
the files should go. While v6.6.0 installs them into /usr/lib/iproute2,
current mast^Wmain branch uses /usr/share/iproute2. Assume this is going
to stay as /(usr/)lib does not seem right for such files.

Note that rt_symbol_table_init() is not just used for
iproute2-maintained configs but also for connlabel.conf - so retain the
old behaviour when passed an absolute path.

Signed-off-by: Phil Sutter <phil@nwl.cc>
19 months agoparser_bison: ensure all timeout policy names are released
Florian Westphal [Tue, 12 Dec 2023 12:32:24 +0000 (13:32 +0100)] 
parser_bison: ensure all timeout policy names are released

We need to add a custom destructor for this structure, it
contains the dynamically allocated names.

a:5:55-55: Error: syntax error, unexpected '}', expecting string
policy = { estabQisheestablished : 2m3s, cd : 2m3s, }

==562373==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 160 byte(s) in 2 object(s) allocated from:
    #1 0x5a565b in xmalloc src/utils.c:31:8
    #2 0x5a565b in xzalloc src/utils.c:70:8
    #3 0x3d9352 in nft_parse_bison_filename src/libnftables.c:520:8
[..]

Fixes: c7c94802679c ("src: add ct timeout support")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agosrc: do not allow to chain more than 16 binops
Florian Westphal [Thu, 21 Dec 2023 10:25:14 +0000 (11:25 +0100)] 
src: do not allow to chain more than 16 binops

netlink_linearize.c has never supported more than 16 chained binops.
Adding more is possible but overwrites the stack in
netlink_gen_bitwise().

Add a recursion counter to catch this at eval stage.

Its not enough to just abort once the counter hits
NFT_MAX_EXPR_RECURSION.

This is because there are valid test cases that exceed this.
For example, evaluation of 1 | 2 will merge the constans, so even
if there are a dozen recursive eval calls this will not end up
with large binop chain post-evaluation.

v2: allow more than 16 binops iff the evaluation function
    did constant-merging.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agonetlink: fix stack overflow due to erroneous rounding
Florian Westphal [Wed, 20 Dec 2023 14:40:54 +0000 (15:40 +0100)] 
netlink: fix stack overflow due to erroneous rounding

Byteorder switch in this function may undersize the conversion
buffer by one byte, this needs to use div_round_up().

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: don't crash if object map does not refer to a value
Florian Westphal [Wed, 20 Dec 2023 10:06:04 +0000 (11:06 +0100)] 
evaluate: don't crash if object map does not refer to a value

Before:
BUG: Value export of 512 bytes would overflownft: src/netlink.c:474: netlink_gen_prefix: Assertion `0' failed.

After:
66: Error: Object mapping data should be a value, not prefix
synproxy name ip saddr map { 192.168.1.0/24 : "v*" }

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: error out on duplicated type/typeof/element keywords
Florian Westphal [Tue, 19 Dec 2023 15:22:32 +0000 (16:22 +0100)] 
parser_bison: error out on duplicated type/typeof/element keywords

Otherwise nft will leak the previous definition (expressions).
Also remove the nonsensical

   datatype_set($1->key, $3->dtype);

This is a no-op, at this point: $1->key and $3 are identical.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotests: shell: add test to cover payload transport match and mangle
Pablo Neira Ayuso [Sat, 16 Dec 2023 23:15:08 +0000 (00:15 +0100)] 
tests: shell: add test to cover payload transport match and mangle

Exercise payload transport match and mangle for inet, bridge and netdev
families with IPv4 and IPv6 packets.

To cover kernel patch ("netfilter: nf_tables: set transport offset from
mac header for netdev/egress").

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agointervals: BUG on prefix expressions without value
Florian Westphal [Tue, 19 Dec 2023 11:14:37 +0000 (12:14 +0100)] 
intervals: BUG on prefix expressions without value

Its possible to end up with prefix expressions that have
a symbolic expression, e.g.:

table t {
        set s {
                type inet_service
                flags interval
                elements = { 172.16.0.0/16 }
        }

        set s {
                type inet_service
                flags interval
                elements = { 0-1024, 8080-8082, 10000-40000 }
        }
}

Without this change, nft will crash.  We end up in setelem_expr_to_range()
with prefix "/16" for the symbolic expression "172.16.0.0".

We than pass invalid mpz_t pointer into libgmp.

This isn't a real fix, but instead of blindly assuming that the attached
expression has a gmp value die with at least some info.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotcpopt: don't create exthdr expression without datatype
Florian Westphal [Fri, 15 Dec 2023 12:04:22 +0000 (13:04 +0100)] 
tcpopt: don't create exthdr expression without datatype

The reproducer crashes during concat evaluation, as the
exthdr expression lacks a datatype.

This should never happen, i->dtype must be set.

In this case the culprit is tcp option parsing, it will
wire up a non-existent template, because the "nop" option
has no length field (1 byte only).

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agointervals: set_to_range can be static
Florian Westphal [Sat, 16 Dec 2023 10:03:36 +0000 (11:03 +0100)] 
intervals: set_to_range can be static

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: fix stack overflow with huge priority string
Florian Westphal [Fri, 15 Dec 2023 09:19:02 +0000 (10:19 +0100)] 
evaluate: fix stack overflow with huge priority string

Alternative would be to refactor this and move this into the parsers
(bison, json) instead of this hidden re-parsing.

Fixes: 627c451b2351 ("src: allow variables in the chain priority specification")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agonetlink: fix stack buffer overflow with sub-reg sized prefixes
Florian Westphal [Wed, 13 Dec 2023 16:41:26 +0000 (17:41 +0100)] 
netlink: fix stack buffer overflow with sub-reg sized prefixes

The calculation of the dynamic on-stack array is incorrect,
the scratch space can be too low which gives stack corruption:

AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7ffdb454f064..
    #1 0x7fabe92aaac4 in __mpz_export_data src/gmputil.c:108
    #2 0x7fabe92d71b1 in netlink_export_pad src/netlink.c:251
    #3 0x7fabe92d91d8 in netlink_gen_prefix src/netlink.c:476

div_round_up() cannot be used here, it fails to account for register
padding.  A 16 bit prefix will need 2 registers (start, end -- 8 bytes
in total).

Remove the dynamic sizing and add an assertion in case upperlayer
ever passes invalid expr sizes down to us.

After this fix, the combination is rejected by the kernel
because of the maps' wrong data size, before the fix userspace
may crash before.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agosrc: reject large raw payload and concat expressions
Florian Westphal [Tue, 12 Dec 2023 18:13:14 +0000 (19:13 +0100)] 
src: reject large raw payload and concat expressions

The kernel will reject this too, but unfortunately nft may try
to cram the data into the underlying libnftnl expr.

This causes heap corruption or
BUG: nld buffer overflow: want to copy 132, max 64

After:

Error: Concatenation of size 544 exceeds maximum size of 512
udp length . @th,0,512 . @th,512,512 { 47-63 . 0xe373135363130 . 0x33131303735353203 }
                           ^^^^^^^^^

resp. same warning for an over-sized raw expression.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: exthdr: statement arg must be not be a range
Florian Westphal [Thu, 14 Dec 2023 16:56:59 +0000 (17:56 +0100)] 
evaluate: exthdr: statement arg must be not be a range

Else we get:
BUG: unknown expression type range
nft: src/netlink_linearize.c:909: netlink_gen_expr: Assertion `0' failed.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agonetlink: don't crash if prefix for < byte is requested
Florian Westphal [Thu, 14 Dec 2023 14:39:27 +0000 (15:39 +0100)] 
netlink: don't crash if prefix for < byte is requested

If prefix is used with a datatype that has less than 8 bits an
assertion is triggered:

src/netlink.c:243: netlink_gen_raw_data: Assertion `len > 0' failed.

This is esoteric, the alternative would be to restrict prefixes
to ipv4/ipv6 addresses.

Simpler fix is to use round_up instead of divide.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoRevert "evaluate: error out when existing set has incompatible key"
Florian Westphal [Thu, 14 Dec 2023 16:47:21 +0000 (17:47 +0100)] 
Revert "evaluate: error out when existing set has incompatible key"

This breaks existing behaviour, add a test case so this is caught in
the future.

The reverted test case will be brought back once a better fix
is available.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: fix gmp assertion with too-large reject code
Florian Westphal [Thu, 14 Dec 2023 08:39:13 +0000 (09:39 +0100)] 
evaluate: fix gmp assertion with too-large reject code

Before:
nft: gmputil.c:77: mpz_get_uint8: Assertion `cnt <= 1' failed.
After: Error: reject code must be integer in range 0-255

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agometa: fix tc classid parsing out-of-bounds access
Florian Westphal [Wed, 13 Dec 2023 16:37:11 +0000 (17:37 +0100)] 
meta: fix tc classid parsing out-of-bounds access

AddressSanitizer: heap-buffer-overflow on address 0x6020000003af ...
  #0 0x7f9a83cbb402 in tchandle_type_parse src/meta.c:89
  #1 0x7f9a83c6753f in symbol_parse src/datatype.c:138

strlen() - 1 can underflow if length was 0.

Simplify the function, there is no need to duplicate the string
while scanning it.

Expect the first strtol to stop at ':', scan for the minor number next.
The second scan is required to stop at '\0'.

Fixes: 6f2eb8548e0d ("src: meta priority support using tc classid")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: error out when existing set has incompatible key
Florian Westphal [Wed, 13 Dec 2023 16:29:50 +0000 (17:29 +0100)] 
evaluate: error out when existing set has incompatible key

Before:
BUG: invalid range expression type symbol
nft: expression.c:1494: range_expr_value_high: Assertion `0' failed.

After:
range_expr_value_high_assert:5:20-27: Error: Could not resolve protocol name
                elements = { 100-11.0.0.0, }
                                 ^^^^^^^^
range_expr_value_high_assert:7:6-7: Error: set definition has conflicting key (ipv4_addr vs inet_proto)

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: stmt_nat: set reference must point to a map
Florian Westphal [Wed, 13 Dec 2023 16:00:37 +0000 (17:00 +0100)] 
evaluate: stmt_nat: set reference must point to a map

nat_concat_map() requires a datamap, else we crash:
set->data is dereferenced.

Also update expr_evaluate_map() so that EXPR_SET_REF is checked there
too.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: fix memory leaks on hookspec error processing
Florian Westphal [Wed, 13 Dec 2023 10:18:06 +0000 (11:18 +0100)] 
parser_bison: fix memory leaks on hookspec error processing

prio_spec may contain an embedded expression, release it.
We also need to release the device expr and the hook string.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: close chain scope before chain release
Florian Westphal [Wed, 13 Dec 2023 10:09:58 +0000 (11:09 +0100)] 
parser_bison: close chain scope before chain release

cmd_alloc() will free the chain, so we must close the scope opened
in chain_block_alloc beforehand.

The included test file will cause a use-after-free because nft attempts
to search for an identifier in a scope that has been freed:

AddressSanitizer: heap-use-after-free on address 0x618000000368 at pc 0x7f1cbc0e6959 bp 0x7ffd3ccb7850 sp 0x7ffd3ccb7840
    #0 0x7f1cbc0e6958 in symbol_lookup src/rule.c:629
    #1 0x7f1cbc0e66a1 in symbol_get src/rule.c:588
    #2 0x7f1cbc120d67 in nft_parse src/parser_bison.y:4325

Fixes: a66b5ad9540d ("src: allow for updating devices on existing netdev chain")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: fix ct scope underflow if ct helper section is duplicated
Florian Westphal [Tue, 12 Dec 2023 09:22:58 +0000 (10:22 +0100)] 
parser_bison: fix ct scope underflow if ct helper section is duplicated

table inet filter {
ct helper sip-5060u {
type "sip" protocol udp
l3proto ip
}5060t {
type "sip" protocol tcp
l3pownerip
}

Will close the 'ct' scope twice, it has to be closed AFTER the separator
has been parsed.

While not strictly needed, also error out if the protocol is already
given, this provides a better error description.

Also make sure we release the string in all error branches.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: make sure obj_free releases timeout policies
Florian Westphal [Tue, 12 Dec 2023 09:44:35 +0000 (10:44 +0100)] 
parser_bison: make sure obj_free releases timeout policies

obj_free() won't release them because ->type is still 0 at this
point.

Init this to CT_TIMEOUT.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agonetlink_linearize: avoid strict-overflow warning in netlink_gen_bitwise()
Thomas Haller [Wed, 27 Sep 2023 12:23:28 +0000 (14:23 +0200)] 
netlink_linearize: avoid strict-overflow warning in netlink_gen_bitwise()

With gcc-13.2.1-1.fc38.x86_64:

  $ gcc -Iinclude -c -o tmp.o src/netlink_linearize.c -Werror -Wstrict-overflow=5 -O3
  src/netlink_linearize.c: In function ‘netlink_gen_bitwise’:
  src/netlink_linearize.c:1790:1: error: assuming signed overflow does not occur when changing X +- C1 cmp C2 to X cmp C2 -+ C1 [-Werror=strict-overflow]
   1790 | }
        | ^
  cc1: all warnings being treated as errors

It also makes more sense this way, where "n" is the hight of the
"binops" stack, and we check for a non-empty stack with "n > 0" and pop
the last element with "binops[--n]".

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: fix bogus assertion failure with boolean datatype
Florian Westphal [Fri, 8 Dec 2023 18:38:33 +0000 (19:38 +0100)] 
evaluate: fix bogus assertion failure with boolean datatype

The assertion is too strict, as found by afl++:

typeof iifname . ip saddr . meta ipsec
elements = { "eth0" . 10.1.1.2 . 1 }

meta ipsec is boolean (1 bit), but datasize of 1 is set at 8 bit.

Fixes: 22b750aa6dc9 ("src: allow use of base integer types as set keys in concatenations")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agonetlink: add and use nft_data_memcpy helper
Florian Westphal [Fri, 8 Dec 2023 14:34:29 +0000 (15:34 +0100)] 
netlink: add and use nft_data_memcpy helper

There is a stack overflow somewhere in this code, we end
up memcpy'ing a way too large expr into a fixed-size on-stack
buffer.

This is hard to diagnose, most of this code gets inlined so
the crash happens later on return from alloc_nftnl_setelem.

Condense the mempy into a helper and add a BUG so we can catch
the overflow before it occurs.

->value is too small (4, should be 16), but for normal
cases (well-formed data must fit into max reg space, i.e.
64 byte) the chain buffer that comes after value in the
structure provides a cushion.

In order to have the new BUG() not trigger on valid data,
bump value to the correct size, this is userspace so the additional
60 bytes of stack usage is no concern.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: fix memleak in meta set error handling
Florian Westphal [Fri, 8 Dec 2023 12:37:27 +0000 (13:37 +0100)] 
parser_bison: fix memleak in meta set error handling

We must release the expression here, found via afl++ and
-fsanitize-address build.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser_bison: fix objref statement corruption
Florian Westphal [Fri, 8 Dec 2023 18:41:39 +0000 (19:41 +0100)] 
parser_bison: fix objref statement corruption

Consider this:

counter_stmt            :       counter_stmt_alloc
                        |       counter_stmt_alloc      counter_args

counter_stmt_alloc      :       COUNTER { $$ = counter_stmt_alloc(&@$); }
                        |       COUNTER         NAME    stmt_expr
                        {
                                $$ = objref_stmt_alloc(&@$);
                                $$->objref.type = NFT_OBJECT_COUNTER;
                                $$->objref.expr = $3;
                        }
                        ;

counter_args            :       counter_arg { $<stmt>$        = $<stmt>0; }
                        |       counter_args    counter_arg
                        ;

counter_arg             :       PACKETS NUM { $<stmt>0->counter.packets = $2; }

[..]

This has 'counter_stmt_alloc' EITHER return counter or objref statement.
Both are the same structure but with different (union'd) trailer content.

counter_stmt permits the 'packet' and 'byte' argument.

But the 'counter_arg' directive only works with a statement
coming from counter_stmt_alloc().

afl++ came up with following input:

table inet x {
        chain y {
                counter name ip saddr bytes 1.1.1. 1024
        }
}

This clobbers $<stmt>->objref.expr pointer, we then crash when
calling expr_evaluate() on it.

Split the objref related statements into their own directive.

After this, the input will fail with:
"syntax error, unexpected bytes, expecting newline or semicolon".

Also split most of the other objref statements into their own blocks.
synproxy seems to have same problem, limit and quota appeared to be ok.

v1 added objref_stmt to stateful_stmt list, this is wrong, we will
assert when generating the 'counter' statement.
Place it in the normal statement list so netlink_gen_stmt_stateful_assert
throws the expected parser error.

Fixes: dccab4f646b4 ("parser_bison: consolidate stmt_expr rule")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: validate chain max length
Florian Westphal [Fri, 8 Dec 2023 23:37:09 +0000 (00:37 +0100)] 
evaluate: validate chain max length

The includes test files cause:
BUG: chain is too large (257, 256 max)nft: netlink.c:418: netlink_gen_chain: Assertion `0' failed.

Error out in evaluation step instead.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotests: py: missing json output in meta.t with vlan mapping
Pablo Neira Ayuso [Mon, 11 Dec 2023 11:54:35 +0000 (12:54 +0100)] 
tests: py: missing json output in meta.t with vlan mapping

Fix this warning due to missing coverage:

 tests/py/any/meta.t.json.got: WARNING: line 2: Wrote JSON equivalent for rule meta mark set vlan id map { 1 : 0x00000001, 4095 : 0x00004095 }
 ERROR: did not find JSON equivalent for rule 'meta mark set vlan id map @map1

Fixes: 8d3de823b622 ("evaluate: reset statement length context before evaluating statement")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agoevaluate: reset statement length context before evaluating statement
Pablo Neira Ayuso [Wed, 6 Dec 2023 17:48:29 +0000 (18:48 +0100)] 
evaluate: reset statement length context before evaluating statement

This patch consolidates ctx->stmt_len reset in stmt_evaluate() to avoid
this problem. Note that stmt_evaluate_meta() and stmt_evaluate_ct()
already reset it after the statement evaluation.

Moreover, statement dependency can be generated while evaluating a meta
and ct statement. Payload statement dependency already manually stashes
this before calling stmt_evaluate(). Add a new stmt_dependency_evaluate()
function to stash statement length context when evaluating a new statement
dependency and use it for all of the existing statement dependencies.

Florian also says:

'meta mark set vlan id map { 1 : 0x00000001, 4095 : 0x00004095 }' will
crash. Reason is that the l2 dependency generated here is errounously
expanded to a 32bit-one, so the evaluation path won't recognize this
as a L2 dependency.  Therefore, pctx->stacked_ll_count is 0 and
__expr_evaluate_payload() crashes with a null deref when
dereferencing pctx->stacked_ll[0].

nft-test.py gains a fugly hack to tolerate '!map typeof vlan id : meta mark'.
For more generic support we should find something more acceptable, e.g.

!map typeof( everything here is a key or data ) timeout ...

tests/py update and assert(pctx->stacked_ll_count) by Florian Westphal.

Fixes: edecd58755a8 ("evaluate: support shifts larger than the width of the left operand")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotests: py: missing json output in never merge across non-expression statements
Pablo Neira Ayuso [Wed, 6 Dec 2023 18:30:44 +0000 (19:30 +0100)] 
tests: py: missing json output in never merge across non-expression statements

Add missing json output.

Fixes: 99ab1b8feb16 ("rule: never merge across non-expression statements")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agotests: rename file to lowercase
Florian Westphal [Wed, 6 Dec 2023 22:46:22 +0000 (23:46 +0100)] 
tests: rename file to lowercase

Thanks to autocomplete i didn't notice this earlier,
make this lowercase.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoparser: tcpopt: fix tcp option parsing with NUM + length field
Florian Westphal [Tue, 5 Dec 2023 11:56:08 +0000 (12:56 +0100)] 
parser: tcpopt: fix tcp option parsing with NUM + length field

tcp option 254 length ge 4

... will segfault.
The crash bug is that tcpopt_expr_alloc() can return NULL if we cannot
find a suitable template for the requested kind + field combination,
so add the needed error handling in the bison parser.

However, we can handle this.  NOP and EOL have templates, all other
options (known or unknown) must also have a length field.

So also add a fallback template to handle both kind and length, even
if only a numeric option is given that nft doesn't recognize.

Don't bother with output, above will be printed via raw syntax, i.e.
tcp option @254,8,8 >= 4.

Fixes: 24d8da308342 ("tcpopt: allow to check for presence of any tcp option")
Reported-by: Maciej Żenczykowski <zenczykowski@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotests: shell: add test case for sets without key
Florian Westphal [Tue, 5 Dec 2023 12:59:15 +0000 (13:59 +0100)] 
tests: shell: add test case for sets without key

tests/shell/testcases/bogons/nft-f/set_definition_with_no_key_assert
BUG: unhandled key type 2
nft: src/intervals.c:59: setelem_expr_to_range: Assertion `0' failed.

[ This bug doesn't trigger anymore due to
  1949a63215b4 ("evaluate: reject set definition with no key") ]

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: reject set definition with no key
Pablo Neira Ayuso [Wed, 6 Dec 2023 12:40:22 +0000 (13:40 +0100)] 
evaluate: reject set definition with no key

 tests/shell/testcases/bogons/nft-f/set_definition_with_no_key_assert
 BUG: unhandled key type 2
 nft: src/intervals.c:59: setelem_expr_to_range: Assertion `0' failed.

This patch adds a new unit tests/shell courtesy of Florian Westphal.

Fixes: 3975430b12d9 ("src: expand table command before evaluation")
Reported-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agomonitor: add support for concatenated set ranges
Pablo Neira Ayuso [Tue, 5 Dec 2023 16:20:05 +0000 (17:20 +0100)] 
monitor: add support for concatenated set ranges

monitor is missing concatenated set ranges support.

Fixes: 8ac2f3b2fca3 ("src: Add support for concatenated set ranges")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agotests: shell: flush ruleset with -U after feature probing
Pablo Neira Ayuso [Tue, 5 Dec 2023 15:39:27 +0000 (16:39 +0100)] 
tests: shell: flush ruleset with -U after feature probing

feature probe script leaves a ruleset in place, flush it once probing is
complete.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
19 months agoevaluate: fix double free on dtype release
Florian Westphal [Tue, 5 Dec 2023 12:08:17 +0000 (13:08 +0100)] 
evaluate: fix double free on dtype release

We release ->dtype twice, will either segfault or assert
on dtype->refcount != 0 check in datatype_free().

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: catch implicit map expressions without known datatype
Florian Westphal [Mon, 4 Dec 2023 21:51:21 +0000 (22:51 +0100)] 
evaluate: catch implicit map expressions without known datatype

mapping_With_invalid_datatype_crash:1:8-65: Error: Implicit map expression without known datatype
bla to tcp dport map { 80 : 1.1.1.1 . 8001, 81 : 2.2.2.2 . 9001 } bla
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: reject attempt to update a set
Florian Westphal [Mon, 4 Dec 2023 21:00:06 +0000 (22:00 +0100)] 
evaluate: reject attempt to update a set

This will crash as set->data is NULL, so check that SET_REF is pointing
to a map:

Error: candidates_ipv4 is not a map
tcp dport 10003 ip saddr . tcp dport @candidates_ipv4 add @candidates_ipv4 { ip saddr . 10 :0004 timeout 1s }
                                     ~~~~~~~~~~~~~~~~

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: disable meta set with ranges
Florian Westphal [Mon, 4 Dec 2023 18:04:58 +0000 (19:04 +0100)] 
evaluate: disable meta set with ranges

... this will cause an assertion in netlink linearization, catch this
at eval stage instead.

before:
BUG: unknown expression type range
nft: netlink_linearize.c:908: netlink_gen_expr: Assertion `0' failed.

after:
/unknown_expr_type_range_assert:3:31-40: Error: Meta expression cannot be a range
meta mark set 0x001-3434
              ^^^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: error out if basetypes are different
Florian Westphal [Mon, 4 Dec 2023 17:30:51 +0000 (18:30 +0100)] 
evaluate: error out if basetypes are different

prefer
binop_with_different_basetype_assert:3:29-35: Error: Binary operation (<<) with different base types (string vs integer) is not supported
oifname set ip9dscp << 26 | 0x10
            ^^^^^^^~~~~~~
to assertion failure.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: guard against NULL basetype
Florian Westphal [Mon, 4 Dec 2023 17:18:07 +0000 (18:18 +0100)] 
evaluate: guard against NULL basetype

i->dtype->basetype can be NULL.

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: handle invalid mapping expressions gracefully
Florian Westphal [Mon, 4 Dec 2023 16:47:50 +0000 (17:47 +0100)] 
evaluate: handle invalid mapping expressions gracefully

Before:
BUG: invalid mapping expression binop
nft: src/evaluate.c:2027: expr_evaluate_map: Assertion `0' failed.

After:
tests/shell/testcases/bogons/nft-f/invalid_mapping_expr_binop_assert:1:22-25: Error: invalid mapping expression binop
xy mame ip saddr map h& p p
        ~~~~~~~~     ^^^^
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: turn assert into real error check
Florian Westphal [Mon, 4 Dec 2023 16:30:29 +0000 (17:30 +0100)] 
evaluate: turn assert into real error check

large '& VAL' results in:
src/evaluate.c:531: expr_evaluate_bits: Assertion `masklen <= NFT_REG_SIZE * BITS_PER_BYTE' failed.

Turn this into expr_error().

Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agotests/shell: use generated ruleset for `nft --check`
Thomas Haller [Fri, 24 Nov 2023 12:45:53 +0000 (13:45 +0100)] 
tests/shell: use generated ruleset for `nft --check`

The command `nft [-j] list ruleset | nft [-j] --check -f -` should never
fail. "test-wrapper.sh" already checks for that.

However, previously, we would run check against the .nft/.json-nft
files. In most cases, the generated ruleset and the files in git are
identical. However, when they are not, we (also) want to run the check
against the generated one.

This means, we can also run this check every time, regardless whether a
.nft/.json-nft file exists.

If the .nft/.json-nft file is different from the generated one, (because
a test was skipped or because there is a bug), then also check those
files. But this time, any output is ignored as failures are expected
to happen. We still run the check, to get additional coverage for
valgrind or santizers.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agoevaluate: prevent assert when evaluating very large shift values
Florian Westphal [Fri, 1 Dec 2023 13:16:14 +0000 (14:16 +0100)] 
evaluate: prevent assert when evaluating very large shift values

Error out instead of 'nft: gmputil.c:67: mpz_get_uint32: Assertion `cnt <= 1' failed.'.

Fixes: edecd58755a8 ("evaluate: support shifts larger than the width of the left operand")
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agomain: Refer to nft_options in nft_options_check()
Phil Sutter [Sat, 2 Dec 2023 10:10:34 +0000 (11:10 +0100)] 
main: Refer to nft_options in nft_options_check()

Consult the array when determining whether a given option is followed by
an argument or not instead of hard-coding those that do. The array holds
both short and long option name, so one extra pitfall removed.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
19 months agomain: Reduce indenting in nft_options_check()
Phil Sutter [Sat, 2 Dec 2023 10:10:33 +0000 (11:10 +0100)] 
main: Reduce indenting in nft_options_check()

No functional change intended.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
20 months agotests: shell: add missing .nodump file
Florian Westphal [Fri, 1 Dec 2023 14:41:47 +0000 (15:41 +0100)] 
tests: shell: add missing .nodump file

We don't want a dump file here, the test has elements with
timeouts, listing will differ depending on timing ("expires $random seconds").

Fixes: 4890211e188a ("tests: shell: add test case for catchall gc bug")
Signed-off-by: Florian Westphal <fw@strlen.de>
20 months agoevaluate: reject sets with no key
Florian Westphal [Thu, 30 Nov 2023 20:29:52 +0000 (21:29 +0100)] 
evaluate: reject sets with no key

nft --check -f tests/shell/testcases/bogons/nft-f/set_without_key
Segmentation fault (core dumped)

Fixes: 56c90a2dd2eb ("evaluate: expand sets and maps before evaluation")
Signed-off-by: Florian Westphal <fw@strlen.de>