From a2ea4416927854ce205b294019e403b14a49541e Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Mon, 14 Jun 2021 14:28:37 +0200 Subject: [PATCH] nftables-0.9.8-4.el9 - Install an improved sample config - Fix permissions of osf-related configs - rule: Fix for potential off-by-one in cmd_add_loc() - netlink_delinearize: Fix suspicious calloc() call - netlink: Avoid memleak in error path of netlink_delinearize_obj() - netlink: Avoid memleak in error path of netlink_delinearize_table() - netlink: Avoid memleak in error path of netlink_delinearize_chain() - netlink: Avoid memleak in error path of netlink_delinearize_set() - json: Drop pointless assignment in exthdr_expr_json() - evaluate: Mark fall through case in str2hooknum() - parser_json: Fix for memleak in tcp option error path - parser_bison: Fix for implicit declaration of isalnum - main: fix nft --help output fallout from 719e4427 - tests: add icmp/6 test where dependency should be left alone - payload: check icmp dependency before removing previous icmp expression Resolves: rhbz#1933117, rhbz#1938823, rhbz#1931790, rhbz#1964987, rhbz#1971600 --- ...mp-dependency-before-removing-previo.patch | 122 +++++++++++++ ...-test-where-dependency-should-be-lef.patch | 165 ++++++++++++++++++ ...ft-help-output-fallout-from-719e4427.patch | 48 +++++ ...-for-implicit-declaration-of-isalnum.patch | 30 ++++ ...for-memleak-in-tcp-option-error-path.patch | 39 +++++ ...ark-fall-through-case-in-str2hooknum.patch | 30 ++++ ...tless-assignment-in-exthdr_expr_json.patch | 30 ++++ ...mleak-in-error-path-of-netlink_delin.patch | 42 +++++ ...mleak-in-error-path-of-netlink_delin.patch | 32 ++++ ...mleak-in-error-path-of-netlink_delin.patch | 32 ++++ ...mleak-in-error-path-of-netlink_delin.patch | 32 ++++ ...linearize-Fix-suspicious-calloc-call.patch | 35 ++++ ...-potential-off-by-one-in-cmd_add_loc.patch | 32 ++++ main.nft | 64 +++++++ nat.nft | 30 ++++ nftables.conf | 25 +-- nftables.spec | 47 ++++- router.nft | 16 ++ 18 files changed, 829 insertions(+), 22 deletions(-) create mode 100644 0001-payload-check-icmp-dependency-before-removing-previo.patch create mode 100644 0002-tests-add-icmp-6-test-where-dependency-should-be-lef.patch create mode 100644 0003-main-fix-nft-help-output-fallout-from-719e4427.patch create mode 100644 0004-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch create mode 100644 0005-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch create mode 100644 0006-evaluate-Mark-fall-through-case-in-str2hooknum.patch create mode 100644 0007-json-Drop-pointless-assignment-in-exthdr_expr_json.patch create mode 100644 0008-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch create mode 100644 0009-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch create mode 100644 0010-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch create mode 100644 0011-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch create mode 100644 0012-netlink_delinearize-Fix-suspicious-calloc-call.patch create mode 100644 0013-rule-Fix-for-potential-off-by-one-in-cmd_add_loc.patch create mode 100644 main.nft create mode 100644 nat.nft create mode 100644 router.nft diff --git a/0001-payload-check-icmp-dependency-before-removing-previo.patch b/0001-payload-check-icmp-dependency-before-removing-previo.patch new file mode 100644 index 0000000..7c234c4 --- /dev/null +++ b/0001-payload-check-icmp-dependency-before-removing-previo.patch @@ -0,0 +1,122 @@ +From 9230899c6d2be8913646ff1a3b560865c330de7b Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 1 Feb 2021 22:08:54 +0100 +Subject: [PATCH] payload: check icmp dependency before removing previous icmp + expression + +nft is too greedy when removing icmp dependencies. +'icmp code 1 type 2' did remove the type when printing. + +Be more careful and check that the icmp type dependency of the +candidate expression (earlier icmp payload expression) has the same +type dependency as the new expression. + +Reported-by: Eric Garver +Reported-by: Michael Biebl +Tested-by: Eric Garver +Fixes: d0f3b9eaab8d77e ("payload: auto-remove simple icmp/icmpv6 dependency expressions") +Signed-off-by: Florian Westphal +(cherry picked from commit 533565244d88a818d8828ebabd7625e5a8a4c374) +Signed-off-by: Phil Sutter +--- + src/payload.c | 63 ++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 42 insertions(+), 21 deletions(-) + +diff --git a/src/payload.c b/src/payload.c +index 48529bcf5c514..a77ca55005509 100644 +--- a/src/payload.c ++++ b/src/payload.c +@@ -627,6 +627,40 @@ void payload_dependency_release(struct payload_dep_ctx *ctx) + ctx->pdep = NULL; + } + ++static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t) ++{ ++ switch (t) { ++ case PROTO_ICMP_ANY: ++ BUG("Invalid map for simple dependency"); ++ case PROTO_ICMP_ECHO: return ICMP_ECHO; ++ case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST; ++ case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH; ++ case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT; ++ case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG; ++ case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY; ++ case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB; ++ } ++ ++ BUG("Missing icmp type mapping"); ++} ++ ++static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct expr *expr) ++{ ++ const struct expr *dep = ctx->pdep->expr; ++ uint8_t icmp_type; ++ ++ icmp_type = expr->payload.tmpl->icmp_dep; ++ if (icmp_type == PROTO_ICMP_ANY) ++ return false; ++ ++ if (dep->left->payload.desc != expr->payload.desc) ++ return false; ++ ++ icmp_type = icmp_dep_to_type(expr->payload.tmpl->icmp_dep); ++ ++ return ctx->icmp_type == icmp_type; ++} ++ + static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx, + unsigned int family, struct expr *expr) + { +@@ -661,6 +695,14 @@ static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx, + break; + } + ++ if (expr->payload.base == PROTO_BASE_TRANSPORT_HDR && ++ dep->left->payload.base == PROTO_BASE_TRANSPORT_HDR) { ++ if (dep->left->payload.desc == &proto_icmp) ++ return payload_may_dependency_kill_icmp(ctx, expr); ++ if (dep->left->payload.desc == &proto_icmp6) ++ return payload_may_dependency_kill_icmp(ctx, expr); ++ } ++ + return true; + } + +@@ -680,10 +722,6 @@ void payload_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, + if (payload_dependency_exists(ctx, expr->payload.base) && + payload_may_dependency_kill(ctx, family, expr)) + payload_dependency_release(ctx); +- else if (ctx->icmp_type && ctx->pdep) { +- fprintf(stderr, "Did not kill \n"); +- payload_dependency_release(ctx); +- } + } + + void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, +@@ -707,23 +745,6 @@ void exthdr_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr, + } + } + +-static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t) +-{ +- switch (t) { +- case PROTO_ICMP_ANY: +- BUG("Invalid map for simple dependency"); +- case PROTO_ICMP_ECHO: return ICMP_ECHO; +- case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST; +- case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH; +- case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT; +- case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG; +- case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY; +- case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB; +- } +- +- BUG("Missing icmp type mapping"); +-} +- + /** + * payload_expr_complete - fill in type information of a raw payload expr + * +-- +2.31.1 + diff --git a/0002-tests-add-icmp-6-test-where-dependency-should-be-lef.patch b/0002-tests-add-icmp-6-test-where-dependency-should-be-lef.patch new file mode 100644 index 0000000..f412459 --- /dev/null +++ b/0002-tests-add-icmp-6-test-where-dependency-should-be-lef.patch @@ -0,0 +1,165 @@ +From bcd7ef679ca12700970e84fdd8ed38d8f58557ea Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 1 Feb 2021 22:44:25 +0100 +Subject: [PATCH] tests: add icmp/6 test where dependency should be left alone + +These tests fail: nft should leave the type as-is. + +Signed-off-by: Florian Westphal +(cherry picked from commit 3eb14fd93093c5e084d3ac1c4b0171cf80fb264f) + +Conflicts: + tests/py/ip/icmp.t.json + tests/py/ip6/icmpv6.t.json +-> Context change it seems. + +Signed-off-by: Phil Sutter +--- + tests/py/ip/icmp.t | 2 ++ + tests/py/ip/icmp.t.json | 28 ++++++++++++++++++++ + tests/py/ip/icmp.t.payload.ip | 6 +++++ + tests/py/ip6/icmpv6.t | 2 ++ + tests/py/ip6/icmpv6.t.json | 44 +++++++++++++++++++++++++++++++ + tests/py/ip6/icmpv6.t.payload.ip6 | 7 +++++ + 6 files changed, 89 insertions(+) + +diff --git a/tests/py/ip/icmp.t b/tests/py/ip/icmp.t +index c22b55eb1e3f4..11f3662e2b027 100644 +--- a/tests/py/ip/icmp.t ++++ b/tests/py/ip/icmp.t +@@ -86,3 +86,5 @@ icmp gateway != { 33-55};ok + icmp gateway != 34;ok + icmp gateway != { 333, 334};ok + ++icmp code 1 icmp type 2;ok;icmp type 2 icmp code host-unreachable ++icmp code != 1 icmp type 2 icmp mtu 5;fail +diff --git a/tests/py/ip/icmp.t.json b/tests/py/ip/icmp.t.json +index 965eb10be9edf..2ea5b1a3e5e02 100644 +--- a/tests/py/ip/icmp.t.json ++++ b/tests/py/ip/icmp.t.json +@@ -1424,3 +1424,31 @@ + } + ] + ++# icmp code 1 icmp type 2 ++[ ++ { ++ "match": { ++ "left": { ++ "payload": { ++ "field": "type", ++ "protocol": "icmp" ++ } ++ }, ++ "op": "==", ++ "right": 2 ++ } ++ }, ++ { ++ "match": { ++ "left": { ++ "payload": { ++ "field": "code", ++ "protocol": "icmp" ++ } ++ }, ++ "op": "==", ++ "right": "host-unreachable" ++ } ++ } ++] ++ +diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip +index d75d12a061252..97464a08379e3 100644 +--- a/tests/py/ip/icmp.t.payload.ip ++++ b/tests/py/ip/icmp.t.payload.ip +@@ -787,3 +787,9 @@ ip test-ip4 input + [ lookup reg 1 set __set%d ] + [ immediate reg 0 accept ] + ++# icmp code 1 icmp type 2 ++ip ++ [ meta load l4proto => reg 1 ] ++ [ cmp eq reg 1 0x00000001 ] ++ [ payload load 2b @ transport header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000102 ] +diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t +index 8b411a8bf4392..d07c34bd939dc 100644 +--- a/tests/py/ip6/icmpv6.t ++++ b/tests/py/ip6/icmpv6.t +@@ -92,3 +92,5 @@ icmpv6 max-delay {33, 55, 67, 88};ok + icmpv6 max-delay != {33, 55, 67, 88};ok + icmpv6 max-delay {33-55};ok + icmpv6 max-delay != {33-55};ok ++ ++icmpv6 type parameter-problem icmpv6 code no-route;ok +diff --git a/tests/py/ip6/icmpv6.t.json b/tests/py/ip6/icmpv6.t.json +index f6cfbf172f562..be2f1b462bb18 100644 +--- a/tests/py/ip6/icmpv6.t.json ++++ b/tests/py/ip6/icmpv6.t.json +@@ -1300,3 +1300,47 @@ + } + ] + ++# icmpv6 type packet-too-big icmpv6 mtu 1280 ++[ ++ { ++ "match": { ++ "left": { ++ "payload": { ++ "field": "mtu", ++ "protocol": "icmpv6" ++ } ++ }, ++ "op": "==", ++ "right": 1280 ++ } ++ } ++] ++ ++# icmpv6 type parameter-problem icmpv6 code no-route ++[ ++ { ++ "match": { ++ "left": { ++ "payload": { ++ "field": "type", ++ "protocol": "icmpv6" ++ } ++ }, ++ "op": "==", ++ "right": "parameter-problem" ++ } ++ }, ++ { ++ "match": { ++ "left": { ++ "payload": { ++ "field": "code", ++ "protocol": "icmpv6" ++ } ++ }, ++ "op": "==", ++ "right": "no-route" ++ } ++ } ++] ++ +diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6 +index 171b7eade6d3e..448779d16922c 100644 +--- a/tests/py/ip6/icmpv6.t.payload.ip6 ++++ b/tests/py/ip6/icmpv6.t.payload.ip6 +@@ -682,3 +682,10 @@ ip6 test-ip6 input + [ payload load 2b @ transport header + 4 => reg 1 ] + [ lookup reg 1 set __set%d 0x1 ] + ++# icmpv6 type parameter-problem icmpv6 code no-route ++ip6 ++ [ meta load l4proto => reg 1 ] ++ [ cmp eq reg 1 0x0000003a ] ++ [ payload load 2b @ transport header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ +-- +2.31.1 + diff --git a/0003-main-fix-nft-help-output-fallout-from-719e4427.patch b/0003-main-fix-nft-help-output-fallout-from-719e4427.patch new file mode 100644 index 0000000..a9293bc --- /dev/null +++ b/0003-main-fix-nft-help-output-fallout-from-719e4427.patch @@ -0,0 +1,48 @@ +From 5f91359f1bbcd73346e4469f0b5a30e04f107a06 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20N=C4=9Bmec?= +Date: Mon, 22 Feb 2021 13:03:19 +0100 +Subject: [PATCH] main: fix nft --help output fallout from 719e4427 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Long options were missing the double dash. + +Fixes: 719e44277f8e ("main: use one data-structure to initialize getopt_long(3) arguments and help.") +Cc: Jeremy Sowden +Signed-off-by: Štěpán Němec +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit b8c6dd1a9c0c6e937febc113e7ea89079aa945be) +Signed-off-by: Phil Sutter +--- + src/main.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 80cf1acf0f7f4..8c47064459ecb 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -175,16 +175,17 @@ static const struct option *get_options(void) + + static void print_option(const struct nft_opt *opt) + { +- char optbuf[33] = ""; ++ char optbuf[35] = ""; + int i; + + i = snprintf(optbuf, sizeof(optbuf), " -%c", opt->val); + if (opt->name) +- i += snprintf(optbuf + i, sizeof(optbuf) - i, ", %s", opt->name); ++ i += snprintf(optbuf + i, sizeof(optbuf) - i, ", --%s", ++ opt->name); + if (opt->arg) + i += snprintf(optbuf + i, sizeof(optbuf) - i, " %s", opt->arg); + +- printf("%-32s%s\n", optbuf, opt->help); ++ printf("%-34s%s\n", optbuf, opt->help); + } + + static void show_help(const char *name) +-- +2.31.1 + diff --git a/0004-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch b/0004-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch new file mode 100644 index 0000000..6573573 --- /dev/null +++ b/0004-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch @@ -0,0 +1,30 @@ +From f09f39704d8bfa15d236b6891aabef270ec43d73 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:03:32 +0200 +Subject: [PATCH] parser_bison: Fix for implicit declaration of isalnum + +Have to include ctype.h to make it known. + +Fixes: e76bb37940181 ("src: allow for variables in the log prefix string") +Signed-off-by: Phil Sutter +(cherry picked from commit 7c3b2a7acbdc793b822a230ec0c28086c7d0365d) +Signed-off-by: Phil Sutter +--- + src/parser_bison.y | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/parser_bison.y b/src/parser_bison.y +index 519e8efe5ab7e..8644f66106496 100644 +--- a/src/parser_bison.y ++++ b/src/parser_bison.y +@@ -10,6 +10,7 @@ + + %{ + ++#include + #include + #include + #include +-- +2.31.1 + diff --git a/0005-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch b/0005-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch new file mode 100644 index 0000000..5a4a726 --- /dev/null +++ b/0005-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch @@ -0,0 +1,39 @@ +From a79e92c0f6761a748ef3cbffd26a4f1db82b4b3e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:07:02 +0200 +Subject: [PATCH] parser_json: Fix for memleak in tcp option error path + +If 'kind' value is invalid, the function returned without freeing 'expr' +first. Fix this by performing the check before allocation. + +Fixes: cb21869649208 ("json: tcp: add raw tcp option match support") +Signed-off-by: Phil Sutter +(cherry picked from commit f7b0eef8391ae7f89a3a82f6eeecaebe199224d7) +Signed-off-by: Phil Sutter +--- + src/parser_json.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/parser_json.c b/src/parser_json.c +index f0486b77a225a..85d05ce27eef3 100644 +--- a/src/parser_json.c ++++ b/src/parser_json.c +@@ -611,12 +611,12 @@ static struct expr *json_parse_tcp_option_expr(struct json_ctx *ctx, + "base", &kind, "offset", &offset, "len", &len)) { + uint32_t flag = 0; + +- expr = tcpopt_expr_alloc(int_loc, kind, +- TCPOPT_COMMON_KIND); +- + if (kind < 0 || kind > 255) + return NULL; + ++ expr = tcpopt_expr_alloc(int_loc, kind, ++ TCPOPT_COMMON_KIND); ++ + if (offset == TCPOPT_COMMON_KIND && len == 8) + flag = NFT_EXTHDR_F_PRESENT; + +-- +2.31.1 + diff --git a/0006-evaluate-Mark-fall-through-case-in-str2hooknum.patch b/0006-evaluate-Mark-fall-through-case-in-str2hooknum.patch new file mode 100644 index 0000000..04180b5 --- /dev/null +++ b/0006-evaluate-Mark-fall-through-case-in-str2hooknum.patch @@ -0,0 +1,30 @@ +From 07ebd0fa9300176f818789fde2498422fa421090 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:19:18 +0200 +Subject: [PATCH] evaluate: Mark fall through case in str2hooknum() + +It is certainly intentional, so just mark it as such. + +Fixes: b4775dec9f80b ("src: ingress inet support") +Signed-off-by: Phil Sutter +(cherry picked from commit c2e06beef3390867901080c0d789e3b6257e2b98) +Signed-off-by: Phil Sutter +--- + src/evaluate.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/evaluate.c b/src/evaluate.c +index c830dcdbd9651..2a897f469434a 100644 +--- a/src/evaluate.c ++++ b/src/evaluate.c +@@ -4030,6 +4030,7 @@ static uint32_t str2hooknum(uint32_t family, const char *hook) + case NFPROTO_INET: + if (!strcmp(hook, "ingress")) + return NF_INET_INGRESS; ++ /* fall through */ + case NFPROTO_IPV4: + case NFPROTO_BRIDGE: + case NFPROTO_IPV6: +-- +2.31.1 + diff --git a/0007-json-Drop-pointless-assignment-in-exthdr_expr_json.patch b/0007-json-Drop-pointless-assignment-in-exthdr_expr_json.patch new file mode 100644 index 0000000..2a97351 --- /dev/null +++ b/0007-json-Drop-pointless-assignment-in-exthdr_expr_json.patch @@ -0,0 +1,30 @@ +From a7da4f45cc1c8419b38e3e9adf0e15bedb8b0257 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:23:22 +0200 +Subject: [PATCH] json: Drop pointless assignment in exthdr_expr_json() + +The updated value of 'is_exists' is no longer read at this point. + +Fixes: cb21869649208 ("json: tcp: add raw tcp option match support") +Signed-off-by: Phil Sutter +(cherry picked from commit c1616dfd1ce40bac197924c8947e1c646e915dca) +Signed-off-by: Phil Sutter +--- + src/json.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/json.c b/src/json.c +index 585d35326ac01..1fb5015124e16 100644 +--- a/src/json.c ++++ b/src/json.c +@@ -692,7 +692,6 @@ json_t *exthdr_expr_json(const struct expr *expr, struct output_ctx *octx) + "base", expr->exthdr.raw_type, + "offset", expr->exthdr.offset, + "len", expr->len); +- is_exists = false; + } + + return json_pack("{s:o}", "tcp option", root); +-- +2.31.1 + diff --git a/0008-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch b/0008-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch new file mode 100644 index 0000000..253acbf --- /dev/null +++ b/0008-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch @@ -0,0 +1,42 @@ +From 2344a35f90ef4a467b6bb9779fc687b17f4a4b51 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:43:21 +0200 +Subject: [PATCH] netlink: Avoid memleak in error path of + netlink_delinearize_set() + +Duplicate string 'comment' later when the function does not fail +anymore. + +Fixes: 0864c2d49ee8a ("src: add comment support for set declarations") +Signed-off-by: Phil Sutter +(cherry picked from commit accd7a346fd19f1ffc503b3f681323abf1157c1a) +Signed-off-by: Phil Sutter +--- + src/netlink.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/netlink.c b/src/netlink.c +index ec2dad29ace1c..5c38a9f157d38 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -840,7 +840,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx, + if (ud[NFTNL_UDATA_SET_DATA_TYPEOF]) + typeof_expr_data = set_make_key(ud[NFTNL_UDATA_SET_DATA_TYPEOF]); + if (ud[NFTNL_UDATA_SET_COMMENT]) +- comment = xstrdup(nftnl_udata_get(ud[NFTNL_UDATA_SET_COMMENT])); ++ comment = nftnl_udata_get(ud[NFTNL_UDATA_SET_COMMENT]); + } + + key = nftnl_set_get_u32(nls, NFTNL_SET_KEY_TYPE); +@@ -878,7 +878,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx, + set->handle.set.name = xstrdup(nftnl_set_get_str(nls, NFTNL_SET_NAME)); + set->automerge = automerge; + if (comment) +- set->comment = comment; ++ set->comment = xstrdup(comment); + + init_list_head(&set_parse_ctx.stmt_list); + +-- +2.31.1 + diff --git a/0009-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch b/0009-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch new file mode 100644 index 0000000..d8539ab --- /dev/null +++ b/0009-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch @@ -0,0 +1,32 @@ +From 6cbc04136a91eca237476827b57e78ac29e00aeb Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 18:32:13 +0200 +Subject: [PATCH] netlink: Avoid memleak in error path of + netlink_delinearize_chain() + +If parsing udata fails, 'chain' has to be freed before returning to +caller. + +Fixes: 702ac2b72c0e8 ("src: add comment support for chains") +Signed-off-by: Phil Sutter +(cherry picked from commit 04f7af9dd66d3a0f627f43bc4bf55bae9856efc8) +Signed-off-by: Phil Sutter +--- + src/netlink.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/netlink.c b/src/netlink.c +index 5c38a9f157d38..22140afc3fd7e 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -573,6 +573,7 @@ struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx, + udata = nftnl_chain_get_data(nlc, NFTNL_CHAIN_USERDATA, &ulen); + if (nftnl_udata_parse(udata, ulen, chain_parse_udata_cb, ud) < 0) { + netlink_io_error(ctx, NULL, "Cannot parse userdata"); ++ chain_free(chain); + return NULL; + } + if (ud[NFTNL_UDATA_CHAIN_COMMENT]) +-- +2.31.1 + diff --git a/0010-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch b/0010-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch new file mode 100644 index 0000000..67fad59 --- /dev/null +++ b/0010-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch @@ -0,0 +1,32 @@ +From c47e6d3b1ccb166b807d19fd585d6b5b3cd0b7f7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 18:33:44 +0200 +Subject: [PATCH] netlink: Avoid memleak in error path of + netlink_delinearize_table() + +If parsing udata fails, 'table' has to be freed before returning to +caller. + +Fixes: c156232a530b3 ("src: add comment support when adding tables") +Signed-off-by: Phil Sutter +(cherry picked from commit 47640634cff9932784a1a96836d6c5809cc8264d) +Signed-off-by: Phil Sutter +--- + src/netlink.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/netlink.c b/src/netlink.c +index 22140afc3fd7e..fd82b16cb9f6e 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -620,6 +620,7 @@ struct table *netlink_delinearize_table(struct netlink_ctx *ctx, + udata = nftnl_table_get_data(nlt, NFTNL_TABLE_USERDATA, &ulen); + if (nftnl_udata_parse(udata, ulen, table_parse_udata_cb, ud) < 0) { + netlink_io_error(ctx, NULL, "Cannot parse userdata"); ++ table_free(table); + return NULL; + } + if (ud[NFTNL_UDATA_TABLE_COMMENT]) +-- +2.31.1 + diff --git a/0011-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch b/0011-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch new file mode 100644 index 0000000..9b4e889 --- /dev/null +++ b/0011-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch @@ -0,0 +1,32 @@ +From 3ec01f287b0b61c0e6d885a7e96dcfa5afa800b8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 16:46:48 +0200 +Subject: [PATCH] netlink: Avoid memleak in error path of + netlink_delinearize_obj() + +If parsing udata fails, 'obj' has to be freed before returning to +caller. + +Fixes: 293c9b114faef ("src: add comment support for objects") +Signed-off-by: Phil Sutter +(cherry picked from commit 97b5d4bbcac4d3237f114c1c6a57c37968ebe0fc) +Signed-off-by: Phil Sutter +--- + src/netlink.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/netlink.c b/src/netlink.c +index fd82b16cb9f6e..4c03baeff5d66 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -1445,6 +1445,7 @@ struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx, + udata = nftnl_obj_get_data(nlo, NFTNL_OBJ_USERDATA, &ulen); + if (nftnl_udata_parse(udata, ulen, obj_parse_udata_cb, ud) < 0) { + netlink_io_error(ctx, NULL, "Cannot parse userdata"); ++ obj_free(obj); + return NULL; + } + if (ud[NFTNL_UDATA_OBJ_COMMENT]) +-- +2.31.1 + diff --git a/0012-netlink_delinearize-Fix-suspicious-calloc-call.patch b/0012-netlink_delinearize-Fix-suspicious-calloc-call.patch new file mode 100644 index 0000000..ac21f56 --- /dev/null +++ b/0012-netlink_delinearize-Fix-suspicious-calloc-call.patch @@ -0,0 +1,35 @@ +From d8322b08998a6945b659078b5cc4bd7423194f70 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 17:02:01 +0200 +Subject: [PATCH] netlink_delinearize: Fix suspicious calloc() call + +Parameter passed to sizeof() was wrong. While being at it, replace the +whole call with xmalloc_array() which takes care of error checking. + +Fixes: 913979f882d13 ("src: add expression handler hashtable") +Signed-off-by: Phil Sutter +(cherry picked from commit c4058f96c6a55e4fcd49d4380ac07b5466ec01c0) +Signed-off-by: Phil Sutter +--- + src/netlink_delinearize.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c +index 7315072284119..152b3e6cf8c65 100644 +--- a/src/netlink_delinearize.c ++++ b/src/netlink_delinearize.c +@@ -1732,9 +1732,8 @@ void expr_handler_init(void) + unsigned int i; + uint32_t hash; + +- expr_handle_ht = calloc(NFT_EXPR_HSIZE, sizeof(expr_handle_ht)); +- if (!expr_handle_ht) +- memory_allocation_error(); ++ expr_handle_ht = xmalloc_array(NFT_EXPR_HSIZE, ++ sizeof(expr_handle_ht[0])); + + for (i = 0; i < array_size(netlink_parsers); i++) { + hash = djb_hash(netlink_parsers[i].name) % NFT_EXPR_HSIZE; +-- +2.31.1 + diff --git a/0013-rule-Fix-for-potential-off-by-one-in-cmd_add_loc.patch b/0013-rule-Fix-for-potential-off-by-one-in-cmd_add_loc.patch new file mode 100644 index 0000000..ae87cde --- /dev/null +++ b/0013-rule-Fix-for-potential-off-by-one-in-cmd_add_loc.patch @@ -0,0 +1,32 @@ +From 5fbf4169fba1dfef0f461c4fe31bed70610ebce2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Jun 2021 17:08:34 +0200 +Subject: [PATCH] rule: Fix for potential off-by-one in cmd_add_loc() + +Using num_attrs as index means it must be at max one less than the +array's size at function start. + +Fixes: 27362a5bfa433 ("rule: larger number of error locations") +Signed-off-by: Phil Sutter +(cherry picked from commit 2d0a7a9adeb30708d6fbbee57476c0d4b9214dbd) +Signed-off-by: Phil Sutter +--- + src/rule.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/rule.c b/src/rule.c +index e4bb6bae276a0..03422da3a7560 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -1491,7 +1491,7 @@ struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj, + + void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc) + { +- if (cmd->num_attrs > NFT_NLATTR_LOC_MAX) ++ if (cmd->num_attrs >= NFT_NLATTR_LOC_MAX) + return; + + cmd->attr[cmd->num_attrs].offset = offset; +-- +2.31.1 + diff --git a/main.nft b/main.nft new file mode 100644 index 0000000..6460d10 --- /dev/null +++ b/main.nft @@ -0,0 +1,64 @@ +# Sample configuration for nftables service. +# Load this by calling 'nft -f /etc/nftables/main.nft'. + +# Note about base chain priorities: +# The priority values used in these sample configs are +# offset by 20 in order to avoid ambiguity when firewalld +# is also running which uses an offset of 10. This means +# that packets will traverse firewalld first and if not +# dropped/rejected there will hit the chains defined here. +# Chains created by iptables, ebtables and arptables tools +# do not use an offset, so those chains are traversed first +# in any case. + +# drop any existing nftables ruleset +flush ruleset + +# a common table for both IPv4 and IPv6 +table inet nftables_svc { + + # protocols to allow + set allowed_protocols { + type inet_proto + elements = { icmp, icmpv6 } + } + + # interfaces to accept any traffic on + set allowed_interfaces { + type ifname + elements = { "lo" } + } + + # services to allow + set allowed_tcp_dports { + type inet_service + elements = { ssh, 9090 } + } + + # this chain gathers all accept conditions + chain allow { + ct state established,related accept + + meta l4proto @allowed_protocols accept + iifname @allowed_interfaces accept + tcp dport @allowed_tcp_dports accept + } + + # base-chain for traffic to this host + chain INPUT { + type filter hook input priority filter + 20 + policy accept + + jump allow + reject with icmpx type port-unreachable + } +} + +# By default, any forwarding traffic is allowed. +# Uncomment the following line to filter it based +# on the same criteria as input traffic. +#include "/etc/nftables/router.nft" + +# Uncomment the following line to enable masquerading of +# forwarded traffic. May be used with or without router.nft. +#include "/etc/nftables/nat.nft" diff --git a/nat.nft b/nat.nft new file mode 100644 index 0000000..7079893 --- /dev/null +++ b/nat.nft @@ -0,0 +1,30 @@ +# Sample configuration snippet for nftables service. +# Meant to be included by main.nft, not for direct use. + +# dedicated table for IPv4 +table ip nftables_svc { + + # interfaces to masquerade traffic from + set masq_interfaces { + type ifname + elements = { "virbr0" } + } + + # networks to masquerade traffic from + # 'interval' flag is required to support subnets + set masq_ips { + type ipv4_addr + flags interval + elements = { 192.168.122.0/24 } + } + + # base-chain to manipulate conntrack in postrouting, + # will see packets for new or related traffic only + chain POSTROUTING { + type nat hook postrouting priority srcnat + 20 + policy accept + + iifname @masq_interfaces oifname != @masq_interfaces masquerade + ip saddr @masq_ips masquerade + } +} diff --git a/nftables.conf b/nftables.conf index b2d226d..c3d9649 100644 --- a/nftables.conf +++ b/nftables.conf @@ -1,17 +1,8 @@ -# -# This file will contain your nftables rules and -# is read by the systemd service when restarting -# -# These provide an iptables like set of filters -# (uncomment to include) -# include "/etc/nftables/arp-filter.nft" -# include "/etc/nftables/bridge-filter.nft" -# include "/etc/nftables/inet-filter.nft" -# include "/etc/nftables/ipv4-filter.nft" -# include "/etc/nftables/ipv4-mangle.nft" -# include "/etc/nftables/ipv4-nat.nft" -# include "/etc/nftables/ipv4-raw.nft" -# include "/etc/nftables/ipv6-filter.nft" -# include "/etc/nftables/ipv6-mangle.nft" -# include "/etc/nftables/ipv6-nat.nft" -# include "/etc/nftables/ipv6-raw.nft" +# Uncomment the include statement here to load the default config sample +# in /etc/nftables for nftables service. + +#include "/etc/nftables/main.nft" + +# To customize, either edit the samples in /etc/nftables, append further +# commands to the end of this file or overwrite it after first service +# start by calling: 'nft list ruleset >/etc/sysconfig/nftables.conf'. diff --git a/nftables.spec b/nftables.spec index c03ea48..116adaa 100644 --- a/nftables.spec +++ b/nftables.spec @@ -1,6 +1,6 @@ Name: nftables Version: 0.9.8 -Release: 3%{?dist} +Release: 4%{?dist} # Upstream released a 0.100 version, then 0.4. Need Epoch to get back on track. Epoch: 1 Summary: Netfilter Tables userspace utillites @@ -10,6 +10,23 @@ URL: https://netfilter.org/projects/nftables/ Source0: %{url}/files/%{name}-%{version}.tar.bz2 Source1: nftables.service Source2: nftables.conf +Source3: main.nft +Source4: router.nft +Source5: nat.nft + +Patch01: 0001-payload-check-icmp-dependency-before-removing-previo.patch +Patch02: 0002-tests-add-icmp-6-test-where-dependency-should-be-lef.patch +Patch03: 0003-main-fix-nft-help-output-fallout-from-719e4427.patch +Patch04: 0004-parser_bison-Fix-for-implicit-declaration-of-isalnum.patch +Patch05: 0005-parser_json-Fix-for-memleak-in-tcp-option-error-path.patch +Patch06: 0006-evaluate-Mark-fall-through-case-in-str2hooknum.patch +Patch07: 0007-json-Drop-pointless-assignment-in-exthdr_expr_json.patch +Patch08: 0008-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch +Patch09: 0009-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch +Patch10: 0010-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch +Patch11: 0011-netlink-Avoid-memleak-in-error-path-of-netlink_delin.patch +Patch12: 0012-netlink_delinearize-Fix-suspicious-calloc-call.patch +Patch13: 0013-rule-Fix-for-potential-off-by-one-in-cmd_add_loc.patch #BuildRequires: autogen #BuildRequires: autoconf @@ -71,11 +88,14 @@ cp -a %{SOURCE1} $RPM_BUILD_ROOT/%{_unitdir}/ mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig cp -a %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/ -chmod 600 $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/nftables.conf -mkdir -m 700 -p $RPM_BUILD_ROOT/%{_sysconfdir}/nftables -chmod 600 $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/*.nft -chmod 700 $RPM_BUILD_ROOT/%{_sysconfdir}/nftables +rm $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/*.nft +cp %{SOURCE3} %{SOURCE4} %{SOURCE5} \ + $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/ + +find $RPM_BUILD_ROOT/%{_sysconfdir} \ + \( -type d -exec chmod 0700 {} \; \) , \ + \( -type f -exec chmod 0600 {} \; \) # make nftables.py use the real library file name # to avoid nftables-devel package dependency @@ -116,6 +136,23 @@ sed -i -e 's/\(sofile=\)".*"/\1"'$sofile'"/' \ %{python3_sitelib}/nftables/ %changelog +* Mon Jun 14 2021 Phil Sutter - 1:0.9.8-4 +- Install an improved sample config +- Fix permissions of osf-related configs +- rule: Fix for potential off-by-one in cmd_add_loc() +- netlink_delinearize: Fix suspicious calloc() call +- netlink: Avoid memleak in error path of netlink_delinearize_obj() +- netlink: Avoid memleak in error path of netlink_delinearize_table() +- netlink: Avoid memleak in error path of netlink_delinearize_chain() +- netlink: Avoid memleak in error path of netlink_delinearize_set() +- json: Drop pointless assignment in exthdr_expr_json() +- evaluate: Mark fall through case in str2hooknum() +- parser_json: Fix for memleak in tcp option error path +- parser_bison: Fix for implicit declaration of isalnum +- main: fix nft --help output fallout from 719e4427 +- tests: add icmp/6 test where dependency should be left alone +- payload: check icmp dependency before removing previous icmp expression + * Fri Apr 16 2021 Mohan Boddu - 1:0.9.8-3 - Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 diff --git a/router.nft b/router.nft new file mode 100644 index 0000000..6300a55 --- /dev/null +++ b/router.nft @@ -0,0 +1,16 @@ +# Sample configuration snippet for nftables service. +# Meant to be included by main.nft, not for direct use. + +# a common table for both IPv4 and IPv6 +table inet nftables_svc { + + # base-chain for traffic forwarded by this host + # re-uses 'allow' chain from main.nft + chain FORWARD { + type filter hook forward priority filter + 20 + policy accept + + jump allow + reject with icmpx type host-unreachable + } +}