From 05f656f9ac89cb348f82d522a5fc1c19e367504a Mon Sep 17 00:00:00 2001 From: Jeremy Sowden Date: Mon, 2 Aug 2021 22:54:27 +0100 Subject: [PATCH v4 02/10] extensions: libxt_NFLOG: don't truncate log-prefix when printing and saving iptables-nft nflog targets. When parsing the rule, use a struct with a layout compatible to that of struct xt_nflog_info, but with a buffer large enough to contain the whole 128-character nft prefix. Signed-off-by: Jeremy Sowden --- iptables/nft-shared.c | 45 +++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index b5259db07723..22a1a08ed862 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -20,6 +20,7 @@ #include +#include #include #include #include @@ -598,21 +599,35 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e) static void nft_parse_log(struct nft_xt_ctx *ctx, struct nftnl_expr *e) { - __u16 group = nftnl_expr_get_u16(e, NFTNL_EXPR_LOG_GROUP); - __u16 qthreshold = nftnl_expr_get_u16(e, NFTNL_EXPR_LOG_QTHRESHOLD); - __u32 snaplen = nftnl_expr_get_u32(e, NFTNL_EXPR_LOG_SNAPLEN); - const char *prefix = nftnl_expr_get_str(e, NFTNL_EXPR_LOG_PREFIX); struct xtables_target *target; struct xt_entry_target *t; size_t target_size; - - void *data = ctx->cs; + /* + * In order to handle the longer log-prefix supported by nft, instead of + * using struct xt_nflog_info, we use a struct with a compatible layout, but + * a larger buffer for the prefix. + */ + struct xt_nflog_info_nft { + __u32 len; + __u16 group; + __u16 threshold; + __u16 flags; + __u16 pad; + char prefix[NF_LOG_PREFIXLEN]; + } info = { + .group = nftnl_expr_get_u16(e, NFTNL_EXPR_LOG_GROUP), + .threshold = nftnl_expr_get_u16(e, NFTNL_EXPR_LOG_QTHRESHOLD), + .len = nftnl_expr_get_u32(e, NFTNL_EXPR_LOG_SNAPLEN), + }; + snprintf(info.prefix, sizeof(info.prefix), "%s", + nftnl_expr_get_str(e, NFTNL_EXPR_LOG_PREFIX)); target = xtables_find_target("NFLOG", XTF_TRY_LOAD); if (target == NULL) return; - target_size = XT_ALIGN(sizeof(struct xt_entry_target)) + target->size; + target_size = XT_ALIGN(sizeof(struct xt_entry_target)) + + XT_ALIGN(sizeof(struct xt_nflog_info_nft)); t = xtables_calloc(1, target_size); t->u.target_size = target_size; @@ -621,21 +636,9 @@ static void nft_parse_log(struct nft_xt_ctx *ctx, struct nftnl_expr *e) target->t = t; - struct xt_nflog_info *info = xtables_malloc(sizeof(struct xt_nflog_info)); - info->group = group; - info->len = snaplen; - info->threshold = qthreshold; - - /* Here, because we allow 128 characters in nftables but only 64 - * characters in xtables (in xt_nflog_info specifically), we may - * end up truncating the string when parsing it. - */ - strncpy(info->prefix, prefix, sizeof(info->prefix)); - info->prefix[sizeof(info->prefix) - 1] = '\0'; - - memcpy(&target->t->data, info, target->size); + memcpy(&target->t->data, &info, sizeof(info)); - ctx->h->ops->parse_target(target, data); + ctx->h->ops->parse_target(target, ctx->cs); } static void nft_parse_lookup(struct nft_xt_ctx *ctx, struct nft_handle *h, -- 2.30.2