|
|
bacbc8 |
From dddf806059088efd00b90e79456c66774b1976f1 Mon Sep 17 00:00:00 2001
|
|
|
bacbc8 |
From: Florian Westphal <fw@strlen.de>
|
|
|
bacbc8 |
Date: Tue, 13 Aug 2019 22:12:44 +0200
|
|
|
bacbc8 |
Subject: [PATCH] src: fix jumps on bigendian arches
|
|
|
bacbc8 |
|
|
|
bacbc8 |
table bla {
|
|
|
bacbc8 |
chain foo { }
|
|
|
bacbc8 |
chain bar { jump foo }
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Fails to restore on big-endian platforms:
|
|
|
bacbc8 |
jump.nft:5:2-9: Error: Could not process rule: No such file or directory
|
|
|
bacbc8 |
jump foo
|
|
|
bacbc8 |
|
|
|
bacbc8 |
nft passes a 0-length name to the kernel.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
This is because when we export the value (the string), we provide
|
|
|
bacbc8 |
the size of the destination buffer.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
In earlier versions, the parser allocated the name with the same
|
|
|
bacbc8 |
fixed size and all was fine.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
After the fix, the export places the name in the wrong location
|
|
|
bacbc8 |
in the destination buffer.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
This makes tests/shell/testcases/chains/0001jumps_0 work on s390x.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
v2: convert one error check to a BUG(), it should not happen unless
|
|
|
bacbc8 |
kernel abi is broken.
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Fixes: 142350f154c78 ("src: invalid read when importing chain name")
|
|
|
bacbc8 |
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
bacbc8 |
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
bacbc8 |
(cherry picked from commit fb6d826afb1fa346bdf61c43cd6f7551caee27ba)
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Conflicts:
|
|
|
bacbc8 |
src/datatype.c
|
|
|
bacbc8 |
-> Context change due to missing commit 72931553828af
|
|
|
bacbc8 |
("src: expr: add expression etype")
|
|
|
bacbc8 |
|
|
|
bacbc8 |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
bacbc8 |
---
|
|
|
bacbc8 |
src/datatype.c | 27 ++++++++++++++++++---------
|
|
|
bacbc8 |
src/netlink.c | 16 +++++++++++++---
|
|
|
bacbc8 |
2 files changed, 31 insertions(+), 12 deletions(-)
|
|
|
bacbc8 |
|
|
|
bacbc8 |
diff --git a/src/datatype.c b/src/datatype.c
|
|
|
bacbc8 |
index 5791a6a41599e..7bea6062de9c4 100644
|
|
|
bacbc8 |
--- a/src/datatype.c
|
|
|
bacbc8 |
+++ b/src/datatype.c
|
|
|
bacbc8 |
@@ -251,10 +251,25 @@ const struct datatype invalid_type = {
|
|
|
bacbc8 |
.print = invalid_type_print,
|
|
|
bacbc8 |
};
|
|
|
bacbc8 |
|
|
|
bacbc8 |
-static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
|
|
|
bacbc8 |
+static void verdict_jump_chain_print(const char *what, const struct expr *e,
|
|
|
bacbc8 |
+ struct output_ctx *octx)
|
|
|
bacbc8 |
{
|
|
|
bacbc8 |
char chain[NFT_CHAIN_MAXNAMELEN];
|
|
|
bacbc8 |
+ unsigned int len;
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ memset(chain, 0, sizeof(chain));
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ len = e->len / BITS_PER_BYTE;
|
|
|
bacbc8 |
+ if (len >= sizeof(chain))
|
|
|
bacbc8 |
+ BUG("verdict expression length %u is too large (%lu bits max)",
|
|
|
bacbc8 |
+ e->len, (unsigned long)sizeof(chain) * BITS_PER_BYTE);
|
|
|
bacbc8 |
|
|
|
bacbc8 |
+ mpz_export_data(chain, e->value, BYTEORDER_HOST_ENDIAN, len);
|
|
|
bacbc8 |
+ nft_print(octx, "%s %s", what, chain);
|
|
|
bacbc8 |
+}
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
|
|
|
bacbc8 |
+{
|
|
|
bacbc8 |
switch (expr->verdict) {
|
|
|
bacbc8 |
case NFT_CONTINUE:
|
|
|
bacbc8 |
nft_print(octx, "continue");
|
|
|
bacbc8 |
@@ -264,10 +279,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
|
|
|
bacbc8 |
break;
|
|
|
bacbc8 |
case NFT_JUMP:
|
|
|
bacbc8 |
if (expr->chain->ops->type == EXPR_VALUE) {
|
|
|
bacbc8 |
- mpz_export_data(chain, expr->chain->value,
|
|
|
bacbc8 |
- BYTEORDER_HOST_ENDIAN,
|
|
|
bacbc8 |
- NFT_CHAIN_MAXNAMELEN);
|
|
|
bacbc8 |
- nft_print(octx, "jump %s", chain);
|
|
|
bacbc8 |
+ verdict_jump_chain_print("jump", expr->chain, octx);
|
|
|
bacbc8 |
} else {
|
|
|
bacbc8 |
nft_print(octx, "jump ");
|
|
|
bacbc8 |
expr_print(expr->chain, octx);
|
|
|
bacbc8 |
@@ -275,10 +287,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
|
|
|
bacbc8 |
break;
|
|
|
bacbc8 |
case NFT_GOTO:
|
|
|
bacbc8 |
if (expr->chain->ops->type == EXPR_VALUE) {
|
|
|
bacbc8 |
- mpz_export_data(chain, expr->chain->value,
|
|
|
bacbc8 |
- BYTEORDER_HOST_ENDIAN,
|
|
|
bacbc8 |
- NFT_CHAIN_MAXNAMELEN);
|
|
|
bacbc8 |
- nft_print(octx, "goto %s", chain);
|
|
|
bacbc8 |
+ verdict_jump_chain_print("goto", expr->chain, octx);
|
|
|
bacbc8 |
} else {
|
|
|
bacbc8 |
nft_print(octx, "goto ");
|
|
|
bacbc8 |
expr_print(expr->chain, octx);
|
|
|
bacbc8 |
diff --git a/src/netlink.c b/src/netlink.c
|
|
|
bacbc8 |
index fc310fd293d64..4ad527a02e871 100644
|
|
|
bacbc8 |
--- a/src/netlink.c
|
|
|
bacbc8 |
+++ b/src/netlink.c
|
|
|
bacbc8 |
@@ -392,17 +392,27 @@ static void netlink_gen_verdict(const struct expr *expr,
|
|
|
bacbc8 |
struct nft_data_linearize *data)
|
|
|
bacbc8 |
{
|
|
|
bacbc8 |
char chain[NFT_CHAIN_MAXNAMELEN];
|
|
|
bacbc8 |
+ unsigned int len;
|
|
|
bacbc8 |
|
|
|
bacbc8 |
data->verdict = expr->verdict;
|
|
|
bacbc8 |
|
|
|
bacbc8 |
switch (expr->verdict) {
|
|
|
bacbc8 |
case NFT_JUMP:
|
|
|
bacbc8 |
case NFT_GOTO:
|
|
|
bacbc8 |
+ len = expr->chain->len / BITS_PER_BYTE;
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ if (!len)
|
|
|
bacbc8 |
+ BUG("chain length is 0");
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ if (len > sizeof(chain))
|
|
|
bacbc8 |
+ BUG("chain is too large (%u, %u max)",
|
|
|
bacbc8 |
+ len, (unsigned int)sizeof(chain));
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
+ memset(chain, 0, sizeof(chain));
|
|
|
bacbc8 |
+
|
|
|
bacbc8 |
mpz_export_data(chain, expr->chain->value,
|
|
|
bacbc8 |
- BYTEORDER_HOST_ENDIAN,
|
|
|
bacbc8 |
- NFT_CHAIN_MAXNAMELEN);
|
|
|
bacbc8 |
+ BYTEORDER_HOST_ENDIAN, len);
|
|
|
bacbc8 |
snprintf(data->chain, NFT_CHAIN_MAXNAMELEN, "%s", chain);
|
|
|
bacbc8 |
- data->chain[NFT_CHAIN_MAXNAMELEN-1] = '\0';
|
|
|
bacbc8 |
break;
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
}
|
|
|
bacbc8 |
--
|
|
|
bacbc8 |
2.22.0
|
|
|
bacbc8 |
|