From: Vsevolod Stakhov Date: Wed, 20 May 2026 12:08:40 +0000 (+0100) Subject: [Minor] spf: fix over-read on a bare "spf2." sender-id record X-Git-Tag: 4.1.0~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=59f1ff841584ec8aa720da346e1016d1531a40fa;p=thirdparty%2Frspamd.git [Minor] spf: fix over-read on a bare "spf2." sender-id record start_spf_parse validated only the "spf2." prefix (sizeof - 1) but then advanced begin by the full sizeof, skipping one unvalidated byte. A TXT record consisting of exactly "spf2." made the following '/' check read past the logical end of the string, and could chain into parse_spf_scopes walking past the allocation. Advance past the validated prefix only, then check the version digit and '/' with short-circuiting so neither read goes past the terminator. --- diff --git a/src/libserver/spf.c b/src/libserver/spf.c index e33b0f18d7..2beec32fdb 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -2538,14 +2538,14 @@ start_spf_parse(struct spf_record *rec, struct spf_resolved_element *resolved, } } else if (g_ascii_strncasecmp(begin, SPF_VER2_STR, sizeof(SPF_VER2_STR) - 1) == 0) { - /* Skip one number of record, so no we are here spf2.0/ */ - begin += sizeof(SPF_VER2_STR); - if (*begin != '/') { + /* Skip the validated "spf2." prefix, then the version digit and '/' */ + begin += sizeof(SPF_VER2_STR) - 1; + if (begin[0] == '\0' || begin[1] != '/') { msg_notice_spf("spf error for domain %s: sender id is invalid", rec->sender_domain); } else { - begin++; + begin += 2; parse_spf_scopes(rec, &begin); } /* Now common spf record */