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.
}
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 */
*/
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;
#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; \
_x[0] = (x); \
ret = cbor_encode_text(&ctx->encode.cbor, \
tmplog, \
- dst + maxsize, \
+ dst + maxsize - 1, \
_x, sizeof(_x)); \
if (ret == NULL) \
goto out; \
}
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;