summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datatype.c27
-rw-r--r--src/netlink.c16
2 files changed, 31 insertions, 12 deletions
diff --git a/src/datatype.c b/src/datatype.c
index 28f726f4..c5a01346 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -244,10 +244,25 @@ const struct datatype invalid_type = {
.print = invalid_type_print,
};
-static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
+static void verdict_jump_chain_print(const char *what, const struct expr *e,
+ struct output_ctx *octx)
{
char chain[NFT_CHAIN_MAXNAMELEN];
+ unsigned int len;
+
+ memset(chain, 0, sizeof(chain));
+ len = e->len / BITS_PER_BYTE;
+ if (len >= sizeof(chain))
+ BUG("verdict expression length %u is too large (%lu bits max)",
+ e->len, (unsigned long)sizeof(chain) * BITS_PER_BYTE);
+
+ mpz_export_data(chain, e->value, BYTEORDER_HOST_ENDIAN, len);
+ nft_print(octx, "%s %s", what, chain);
+}
+
+static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
+{
switch (expr->verdict) {
case NFT_CONTINUE:
nft_print(octx, "continue");
@@ -257,10 +272,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
break;
case NFT_JUMP:
if (expr->chain->etype == EXPR_VALUE) {
- mpz_export_data(chain, expr->chain->value,
- BYTEORDER_HOST_ENDIAN,
- NFT_CHAIN_MAXNAMELEN);
- nft_print(octx, "jump %s", chain);
+ verdict_jump_chain_print("jump", expr->chain, octx);
} else {
nft_print(octx, "jump ");
expr_print(expr->chain, octx);
@@ -268,10 +280,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx)
break;
case NFT_GOTO:
if (expr->chain->etype == EXPR_VALUE) {
- mpz_export_data(chain, expr->chain->value,
- BYTEORDER_HOST_ENDIAN,
- NFT_CHAIN_MAXNAMELEN);
- nft_print(octx, "goto %s", chain);
+ verdict_jump_chain_print("goto", expr->chain, octx);
} else {
nft_print(octx, "goto ");
expr_print(expr->chain, octx);
diff --git a/src/netlink.c b/src/netlink.c
index aeeb12ea..f8e11204 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -222,17 +222,27 @@ static void netlink_gen_verdict(const struct expr *expr,
struct nft_data_linearize *data)
{
char chain[NFT_CHAIN_MAXNAMELEN];
+ unsigned int len;
data->verdict = expr->verdict;
switch (expr->verdict) {
case NFT_JUMP:
case NFT_GOTO:
+ len = expr->chain->len / BITS_PER_BYTE;
+
+ if (!len)
+ BUG("chain length is 0");
+
+ if (len > sizeof(chain))
+ BUG("chain is too large (%u, %u max)",
+ len, (unsigned int)sizeof(chain));
+
+ memset(chain, 0, sizeof(chain));
+
mpz_export_data(chain, expr->chain->value,
- BYTEORDER_HOST_ENDIAN,
- NFT_CHAIN_MAXNAMELEN);
+ BYTEORDER_HOST_ENDIAN, len);
snprintf(data->chain, NFT_CHAIN_MAXNAMELEN, "%s", chain);
- data->chain[NFT_CHAIN_MAXNAMELEN-1] = '\0';
break;
}
}