Bug 1778883

Summary: nft parses dash in rules as an option
Product: Red Hat Enterprise Linux 8 Reporter: Tomas Dolezal <todoleza>
Component: nftablesAssignee: Phil Sutter <psutter>
Status: CLOSED ERRATA QA Contact: Jiri Peska <jpeska>
Severity: medium Docs Contact: Marc Muehlfeld <mmuehlfe>
Priority: medium    
Version: 8.2CC: jpeska, mmuehlfe, psutter, todoleza, yiche
Target Milestone: rc   
Target Release: 8.2   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: nftables-0.9.3-6.el8 Doc Type: Bug Fix
Doc Text:
.The `nft` utility no longer interprets arguments as command-line options after the first non-option argument Previously, the `nft` utility accepted options anywhere in an `nft` command. For example, admins could use options between or after non-option arguments. As a consequence, due to the leading dash, `nft` interpreted negative priority values as options, and the command failed. The `nft` utility's command-line parser has been updated to not interpret arguments that are starting with a dash after the first non-option argument has been read. As a result, admins no longer require workarounds to pass negative priority values to `nft`. Note that due to this change, you must now pass all command-options to `nft` before the first non-option argument. Before you update, verify your nftables scripts to match this new criteria to ensure that the script works as expected after you installed this update.
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-04-28 16:42:15 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Tomas Dolezal 2019-12-02 17:55:03 UTC
Description of problem:
putting negative priority on a commandline leads to interpretation following number as an option and thus leads to rule rejection.

In examples bellow in (1) the priority is prepended by a space, similarly to (2) and (3). in (4) the lone-standing '-' is not interpreted as well.
The (0) fails and needs to be fixed.

Version-Release number of selected component (if applicable):
nftables-0.9.2-4.el8.x86_64
nftables-0.9.0-14.el8.x86_64
nftables-0.9.1-2.fc30.x86_64 #fedora

How reproducible:
always

Steps to Reproduce:
(0) nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; }
nft: invalid option -- '1'

these are accepted:
(1) nft add chain ip nat prerouting { type nat hook prerouting priority \ -100 \; }
(2) nft add chain ip nat prerouting '{ type nat hook prerouting priority -100 ; }'
(3) nft -f ruleset.nft
and even
(4) nft add chain ip nat prerouting { type nat hook prerouting priority - 100 \; }

Actual results:
nft: invalid option -- '1'

Expected results:
rule is accepted.

Additional info:

Comment 3 Phil Sutter 2019-12-04 13:16:49 UTC
Hi!

Solution is to escape the dash, just like the semi-colon (and any double quotes [or even curly braces if using zsh]). For me, there are so many things to escape for, quoting the whole nft command in ticks slowly makes it into my muscle memory. Not saying it's a good solution, but fixing for these things (Pablo even tried once) is a rather futile attempt given the unfixable cases (like semi-colon).

Speaking of documentation, an introductory paragraph about the need to escape/quote things is in order and consistent quoting/escaping in examples. I guess that should clarify any open questions.

Cheers, Phil

Comment 4 Tomas Dolezal 2019-12-04 15:05:56 UTC
(In reply to Phil Sutter from comment #3)
> Hi!
> 
> Solution is to escape the dash, just like the semi-colon (and any double
> quotes [or even curly braces if using zsh]). For me, there are so many
> things to escape for, quoting the whole nft command in ticks slowly makes it
> into my muscle memory. Not saying it's a good solution, but fixing for these
> things (Pablo even tried once) is a rather futile attempt given the
> unfixable cases (like semi-colon).
> 
> Speaking of documentation, an introductory paragraph about the need to
> escape/quote things is in order and consistent quoting/escaping in examples.
> I guess that should clarify any open questions.
> 
> Cheers, Phil

Hello Phil,
escaping the dash does not help because the issue is inside nft. As stated above, the dash wont work unless something else (like a whitespace, ref comment 0 example (1)) precedes it in the argument. In other words, standalone argument of '-100' considered an option instead of a priority number in this case.
i tested this in bash and zsh

bash:
# nft add table nat
# nft add chain nat prerouting { type nat hook prerouting priority \-100 \; }
nft: invalid option -- '1'

zsh:
# nft add chain nat prerouting \{ type nat hook prerouting priority -100 \; \}
nft: invalid option -- '1'
# nft add chain nat prerouting \{ type nat hook prerouting priority \-100 \; \}
nft: invalid option -- '1'

putting whole {} into '' of course works around the issue.

Comment 5 Phil Sutter 2019-12-04 16:21:54 UTC
Hi,

(In reply to Tomas Dolezal from comment #4)
> escaping the dash does not help because the issue is inside nft. As stated
> above, the dash wont work unless something else (like a whitespace, ref
> comment 0 example (1)) precedes it in the argument. In other words,
> standalone argument of '-100' considered an option instead of a priority
> number in this case.
> i tested this in bash and zsh

Oh, you're right, sorry. So in order to "properly" escape it you have to put double dash somewhere in front of it, like so:

| nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }

Cheers, Phil

Comment 6 Tomas Dolezal 2019-12-10 15:40:26 UTC
After discussion with Phil we agreed to update documentation of the package to say explicitly that workaround from comment 5 is needed to pass in negative priority on command line unless the priority part is quoted with at least adjacent preceding part.

Comment 9 Phil Sutter 2020-01-10 14:00:33 UTC
Upstream changed its mind, options are no longer allowed after the first non-option. This should fix for negative priority values. Commits to backport are:

commit fb9cea50e8b370b6931e7b53b1a881d3b95b1c91
Author: Pablo Neira Ayuso <pablo>
Date:   Fri Dec 13 11:32:46 2019 +0100

    main: enforce options before commands
    
    This patch turns on POSIXLY_CORRECT on the getopt parser to enforce
    options before commands. Users get a hint in such a case:
    
     # nft list ruleset -a
     Error: syntax error, options must be specified before commands
     nft list ruleset -a
        ^             ~~
    
    This patch recovers 9fc71bc6b602 ("main: Fix for misleading error with
    negative chain priority").
    
    Tests have been updated.
    
    Signed-off-by: Pablo Neira Ayuso <pablo>

commit ea5af85371bd18658ea2ffa0a6c9c48e2c64684b
Author: Pablo Neira Ayuso <pablo>
Date:   Thu Jan 9 18:16:18 2020 +0100

    main: restore --debug
    
    Broken since options are mandatory before commands.
    
    Fixes: fb9cea50e8b3 ("main: enforce options before commands")
    Signed-off-by: Pablo Neira Ayuso <pablo>

Comment 15 Phil Sutter 2020-02-05 17:21:17 UTC
Doc Text is fine with me.

Comment 18 errata-xmlrpc 2020-04-28 16:42:15 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2020:1774