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.
}
}
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 */