]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Minor] mime_headers: avoid uninitialised bytes in rfc2047 decode
authorVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 20 May 2026 10:18:57 +0000 (11:18 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Wed, 20 May 2026 10:18:57 +0000 (11:18 +0100)
When an encoded-word fails to decode, the failure branch reset the
token length with `token->len -= tok_len`. For the base64 path that is
wrong: rspamd_cryptobox_base64_decode writes its *outlen argument
(tok_len) even on failure, so the subtraction no longer restores the
original offset and leaves token->len above pos. The bytes between the
partial decode and the grown GByteArray capacity are uninitialised and
were flushed into the decoded header value.

Reset token->len to the saved pos offset in both failure branches
instead, discarding the token cleanly.

src/libmime/mime_headers.c

index 587ba3516bed61ec69dc2bcbba9f9df72e4b3174..db68599d5f74a19aaac562a5fa6b4524d2413114 100644 (file)
@@ -728,8 +728,8 @@ rspamd_mime_header_decode(rspamd_mempool_t *pool, const char *in,
                                                                token->len = pos + r;
                                                        }
                                                        else {
-                                                               /* Cannot decode qp */
-                                                               token->len -= tok_len;
+                                                               /* Cannot decode qp: discard token, restore saved offset */
+                                                               token->len = pos;
                                                        }
                                                }
                                                else {
@@ -738,8 +738,16 @@ rspamd_mime_header_decode(rspamd_mempool_t *pool, const char *in,
                                                                token->len = pos + tok_len;
                                                        }
                                                        else {
-                                                               /* Cannot decode */
-                                                               token->len -= tok_len;
+                                                               /*
+                                                                * Cannot decode: discard this token. We must reset
+                                                                * to the saved offset rather than subtracting tok_len:
+                                                                * rspamd_cryptobox_base64_decode writes its *outlen
+                                                                * argument (tok_len) even on failure, so the value is
+                                                                * no longer the original token size. Leaving token->len
+                                                                * above pos would expose uninitialised heap bytes from
+                                                                * the freshly grown GByteArray in the decoded header.
+                                                                */
+                                                               token->len = pos;
                                                        }
                                                }