diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/datatype.c | 27 | ||||
-rw-r--r-- | src/netlink.c | 16 |
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; } } |