diff --git a/CHANGES-202605.md b/CHANGES-202605.md index 400ec6d3..8c4e34aa 100644 --- a/CHANGES-202605.md +++ b/CHANGES-202605.md @@ -17,6 +17,7 @@ This document summarizes the changes merged into the `develop` branch during the - **CVE-2022-48521**: `Authentication-Results` headers were removed in forward order; removing one shifted the index of the next, allowing a crafted second forged header to survive. Fixed to remove in reverse order. The same class of off-by-one was present in the Lua `del_header()` helper and in the `KeepAuthResults` deletion path; both were corrected. (#287) - **SubDomains overlapping buffer**: `strlcpy()` was called with overlapping source and destination when updating `mctx_domain` during the subdomain walk. Undefined behavior; manifests as corrupted `d=` tags (invalid signatures) on FreeBSD. Replaced with `memmove()`. (#356) - **Header character validity check**: Always-false NULL check on `mctx_domain` (a fixed-size array) meant downstream code used a potentially empty domain string. (#343, issue #88) +- **`dkimf_db_datasplit` out-of-bounds read (LMDB backend)**: The colon-delimited-field parser used `strchr()` to find the next delimiter, ignoring the caller-supplied byte budget. Harmless against the Berkeley DB backend, which always guarantees a trailing NUL just past the real data, but the LMDB backend returns a pointer directly into memory-mapped pages with no such guarantee: a value with no `:` in its real length caused `strchr()` to read past it into adjacent mapped memory, and the resulting length could then underflow a `size_t` byte counter, corrupting the parser's cursor. Affects any DataSet/SigningTable-style DB backed by LMDB using colon-delimited multi-field values. Fixed by switching to `memchr()`, which respects the byte budget by construction. (#425) --- @@ -59,6 +60,7 @@ This document summarizes the changes merged into the `develop` branch during the - **`AuthservID` with job ID producing invalid header**: Quoting fix for job-ID-appended authserv-ids. (#308, issue #103) - **SHA1 on restricted platforms**: On systems where the OS crypto policy disables SHA1 (e.g. RHEL 9 / AlmaLinux 9 DEFAULT policy), `dkim_init()` now probes SHA1 availability at startup and stores the result. Signing returns `DKIM_STAT_SIGGEN` with a clear message; verification sets `DKIM_SIGERROR_UNSUPPORTED_A` and returns `DKIM_STAT_OK` rather than `DKIM_STAT_INTERNAL`. Works correctly for OS-packaged binaries built on permissive systems and deployed to restricted ones, and for operators who re-enable SHA1 after install (update-crypto-policies + reboot). (#365, issue #364) - **`dkim_getsighdr_d` off-by-one in tag name copy**: Loop condition `q <= end` allowed the null terminator to be written one byte past the end of the `which` buffer. Changed to `q < end`; null terminator moved outside the loop. Eliminates a `-Wstringop-overflow` GCC warning. (#400) +- **`_Bool` functions silently discarding `-1` error returns**: `dkim_sig_hdrlistok()` and `dkimf_parsehandler()` were declared to return `_Bool` but used a tri-state TRUE/FALSE/-1 contract; a `_Bool`-returning function implicitly converts any nonzero `return` value to `1` (TRUE), so `return -1;` on the error path actually returned TRUE. In `dkim_sig_hdrlistok()`, a `DKIM_MALLOC` failure was silently treated as "header list OK" instead of propagating `DKIM_STAT_NORESOURCE`. In `dkimf_parsehandler()`, an invalid value for any `On-*` config handling directive populated the error buffer but never caused config loading to fail. Both changed to return `int`; call sites updated accordingly. (#424) --- @@ -170,6 +172,7 @@ A systematic audit of memory and resource leaks (issue #272) produced fixes acro - **`stdio.h` includes**: Added missing includes in libopendkim/util.c and libvbr/vbr.c. (#320) - **Python 3 Twisted**: Replaced deprecated `defer.returnValue()` with plain `return` in contrib/repute. (#237) - **Compiler warning cleanup** (`-Wincompatible-pointer-types`, `-Wformat-truncation`): `entry_name` in the `-V` output path declared `const char *` to match `dkim_nametable_first`/`next` signatures; `snprintf` call sites in `dkim-util.c`, `opendkim.c`, and `opendkim-genzone.c` given explicit `%.*s` width bounds or larger buffers. (#360, issue #359) +- **cppcheck static analysis cleanup**: A grab-bag of small findings from a `cppcheck --enable=warning,style,performance,portability` pass: a dead `ret == -1` recheck duplicated across `libvbr/vbr.c` and `librbl/rbl.c`'s DNS query paths; a `%zd`/`%zu` format string mismatch (and a typo) in `dkim-test.c`'s key-comparison error message; a `size_t` underflow in `dkim_sign()` where `dkim_base64_decode()`'s `int` return (-1 on error) was assigned directly into the `size_t` `dkim_keylen` field; an uninitialized-looking `end` pointer in the "t"/"x" tag validation in `dkim_process_set()`; a dead `if (!first)` conditional in `dkim_getsighdr_d()`'s tag-wrapping loop; and three redundant bounds-check clauses in `dkim_base32_encode()`'s unrolled loop. (#426) ---