From: Jeremy Harris Date: Tue, 9 Aug 2022 09:57:56 +0000 (+0100) Subject: Filter rDNS returns for bad chars X-Git-Tag: exim-4.97-RC0~257 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/b855ee2fb3776667c8b08aa6b80453d60e4fb509 Filter rDNS returns for bad chars --- diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index b813033c1..d17370589 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -23,6 +23,9 @@ JH/05 Follow symlinks for placing a watch on TLS creds files. This means it would be the dir with the first symlink. We still do not monitor the entire path. +JH/06 Check for bad chars in rDNS for sender_host_name. The OpenBSD (at least) + dn_expand() is happy to pass them through. + Exim version 4.96 ----------------- diff --git a/src/src/globals.c b/src/src/globals.c index c95d24b47..574ee60a4 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1016,6 +1016,10 @@ uschar *keep_environment = NULL; int keep_malformed = 4*24*60*60; /* 4 days */ uschar *eldap_dn = NULL; +const uschar *letter_digit_hyphen_dot = + US"abcdefghijklmnopqrstuvwxyz" + ".-0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; #ifdef EXPERIMENTAL_ESMTP_LIMITS uschar *limits_advertise_hosts = US"*"; #endif diff --git a/src/src/globals.h b/src/src/globals.h index c9ef5e484..3f3c798b7 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -680,6 +680,7 @@ extern uschar *keep_environment; /* Whitelist for environment variables */ extern int keep_malformed; /* Time to keep malformed messages */ extern uschar *eldap_dn; /* Where LDAP DNs are left */ +extern const uschar *letter_digit_hyphen_dot; /* Legitimate DNS host name chars */ #ifdef EXPERIMENTAL_ESMTP_LIMITS extern uschar *limits_advertise_hosts; /* for banner/EHLO pipelining */ #endif diff --git a/src/src/host.c b/src/src/host.c index fed9f4b5f..b6c2ea082 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -84,13 +84,13 @@ random_number(int limit) if (limit < 1) return 0; if (random_seed == 0) - { - if (f.running_in_test_harness) random_seed = 42; else + if (f.running_in_test_harness) + random_seed = 42; + else { int p = (int)getpid(); random_seed = (int)time(NULL) ^ ((p << 16) | p); } - } random_seed = 1103515245 * random_seed + 12345; return (unsigned int)(random_seed >> 16) % limit; } @@ -1646,6 +1646,7 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR) { uschar * s = store_get(ssize, GET_TAINTED); /* names are tainted */ + unsigned slen; /* If an overlong response was received, the data will have been truncated and dn_expand may fail. */ @@ -1658,13 +1659,19 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0))) break; } - store_release_above(s + Ustrlen(s) + 1); - if (!s[0]) + store_release_above(s + (slen = Ustrlen(s)) + 1); + if (!*s) { HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " "empty name: treated as non-existent host name\n"); continue; } + if (Ustrspn(s, letter_digit_hyphen_dot) != slen) + { + HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an " + "illegal name (bad char): treated as non-existent host name\n"); + continue; + } if (!sender_host_name) sender_host_name = s; else *aptr++ = s; while (*s) { *s = tolower(*s); s++; }