X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/3db0f5bebe1573c0609eaf1d29bf69da173a67aa..24cda181fb88542cf38db2beae5d0ddb37f59c5c:/src/src/host.c diff --git a/src/src/host.c b/src/src/host.c index fed9f4b5f..136ee8953 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or directly via the DNS. When IPv6 is supported, getipnodebyname() and @@ -84,13 +85,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; } @@ -823,9 +824,9 @@ Returns: pointer to character string */ uschar * -host_ntoa(int type, const void *arg, uschar *buffer, int *portptr) +host_ntoa(int type, const void * arg, uschar * buffer, int * portptr) { -uschar *yield; +uschar * yield; /* The new world. It is annoying that we have to fish out the address from different places in the block, depending on what kind of address it is. It @@ -911,7 +912,7 @@ Returns: the number of ints used */ int -host_aton(const uschar *address, int *bin) +host_aton(const uschar * address, int * bin) { int x[4]; int v4offset = 0; @@ -923,13 +924,10 @@ supported. */ if (Ustrchr(address, ':') != NULL) { - const uschar *p = address; - const uschar *component[8]; + const uschar * p = address; + const uschar * component[8]; BOOL ipv4_ends = FALSE; - int ci = 0; - int nulloffset = 0; - int v6count = 8; - int i; + int ci = 0, nulloffset = 0, v6count = 8, i; /* If the address starts with a colon, it will start with two colons. Just lose the first one, which will leave a null first component. */ @@ -941,7 +939,7 @@ if (Ustrchr(address, ':') != NULL) overlooked; to guard against that happening again, check here and crash if there are too many components. */ - while (*p != 0 && *p != '%') + while (*p && *p != '%') { int len = Ustrcspn(p, ":%"); if (len == 0) nulloffset = ci; @@ -1646,6 +1644,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 +1657,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++; }