From af34c3ff3090f01e39a9631d8a7cfeac0f35ac84 Mon Sep 17 00:00:00 2001 From: Dan Mahoney Date: Tue, 21 Jul 2026 18:58:24 -0700 Subject: [PATCH] Fix out-of-bounds read / size_t underflow in dkimf_db_datasplit() In the colon-delimited-field branch, dkimf_db_datasplit() located the next delimiter with strchr(p, ':'), which scans until it finds ':' or a NUL byte, ignoring the "remain" byte budget entirely. For the Berkeley DB backend this happened to be harmless: the destination buffer is memset to all-zero for its full length before a DB_DBT_USERMEM fetch that only ever writes up to buflen bytes, so there's always a guaranteed trailing NUL just past the data. The LMDB backend has no such guarantee: mdb_get()/mdb_cursor_get() return a pointer directly into LMDB's memory-mapped pages with no NUL-termination promise. If a stored value has no ':' within its real length, strchr() reads past the value into adjacent mapped memory, "clen = q - p" can exceed "remain", and "remain -= (clen + 1)" underflows the size_t to a huge value -- the loop then keeps running with a corrupted, out-of-bounds pointer. This affects any DataSet/SigningTable-style DB backed by LMDB that uses colon-delimited multi-field values. Fixed by using memchr(p, ':', remain) instead, which respects the "remain" window by construction and can never return a pointer past p + remain, so the subtraction can no longer underflow. --- opendkim/opendkim-db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendkim/opendkim-db.c b/opendkim/opendkim-db.c index c0b6fcd9..304f1a3a 100644 --- a/opendkim/opendkim-db.c +++ b/opendkim/opendkim-db.c @@ -807,7 +807,7 @@ dkimf_db_datasplit(char *buf, size_t buflen, { char *q; - q = strchr(p, ':'); + q = memchr(p, ':', remain); if (q != NULL) { clen = q - p;