From: Aurelien DARRAGON Date: Thu, 6 Aug 2026 19:15:36 +0000 (+0200) Subject: BUG/MEDIUM: log: always reserve room for trailing 0 when using CBOR encoding helpers X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=378386e14225f6aea45b9254ba00973cdaf20ff8;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: log: always reserve room for trailing 0 when using CBOR encoding helpers Logging helpers leveraged by sess_build_logline_orig() can be split in two different groups. Although they all look similar in their construction as they take pretty much the same parameters and return the address where following bytes can be appended, some will always try to append the terminating NULL byte and return the address of the terminating NULL byte, while others (which are not specifically text oriented) will simply use all available space (they don't reserve space for the terminating NULL byte) and return the address of the byte following the last byte written. But since they don't try to write the \0 themselves, they will in practise output one extra byte compared to other helpers. If no precaution is taken and they are used as drop-in replacement to text oriented ones, this can cause invalid writes later in the code because sess_build_logline_orig() will always append the terminating NULL byte (even if it is already set), thus it is mandatory that the output pointer never reaches the stopmark. Fortunately, most pitfalls were already avoided in log generation path, but recent commit c614fd3b ("MINOR: log: add +cbor encoding option") made use of several encoding helpers which were not text oriented as text oriented ones. Let's fix that by always securing 1 byte for the terminating NULL byte when calling them (even if it not used by the endpoint X format, sess_build_logline_orig() will append it not matter what, so we have to live with that). Reported-by: Claude (ANT-2026-QQ17FDX1) It should be backported up to 3.0. --- diff --git a/src/log.c b/src/log.c index c48e0a7c5..c21c21926 100644 --- a/src/log.c +++ b/src/log.c @@ -2314,7 +2314,9 @@ static char *_lf_encode_bytes(char *start, char *stop, } if (start < stop) { - stop--; /* reserve one byte for the final '\0' */ + stop--; /* reserve one byte for the final '\0' as encoding functions + * will try to use all available space + */ if ((ctx->options & LOG_OPT_ENCODE_CBOR) && !ctx->in_text) { /* start indefinite-length cbor byte string or text */ @@ -2430,7 +2432,10 @@ static inline char *_lf_text_len(char *dst, const char *src, */ len = strnlen2(src, len); - ret = cbor_encode_text(&ctx->encode.cbor, dst, dst + size, src, len); + /* cbor_encode_text() doesn't append terminating NULL + * byte, we must reserve 1 byte for that. + */ + ret = cbor_encode_text(&ctx->encode.cbor, dst, dst + size - 1, src, len); if (ret == NULL) return NULL; len = ret - dst; @@ -3546,7 +3551,7 @@ const char sess_set_cookie[] = "NPDIRU67"; /* No set-cookie, Set-cookie found an #define LOG_CBOR_BYTE(x) do { \ ret = _lf_cbor_encode_byte(&ctx->encode.cbor, \ tmplog, \ - dst + maxsize, \ + dst + maxsize - 1, \ (x)); \ if (ret == NULL) \ goto out; \ @@ -3567,7 +3572,7 @@ const char sess_set_cookie[] = "NPDIRU67"; /* No set-cookie, Set-cookie found an _x[0] = (x); \ ret = cbor_encode_text(&ctx->encode.cbor, \ tmplog, \ - dst + maxsize, \ + dst + maxsize - 1, \ _x, sizeof(_x)); \ if (ret == NULL) \ goto out; \ @@ -4139,7 +4144,7 @@ size_t sess_build_logline_orig(struct session *sess, struct stream *s, } else if (ctx->options & LOG_OPT_ENCODE_CBOR) { ret = cbor_encode_text(&ctx->encode.cbor, tmplog, - dst + maxsize, tmp->name, + dst + maxsize - 1, tmp->name, strlen(tmp->name)); if (ret == NULL) goto out;