Hi,
I had sendmail crashes because of invalid pointers in _res.dnsrch.
I have 4 nameservers in /etc/resolv.conf, the last one is IPv6.
/usr/include/resolv.h:
#define MAXNS 3 /* max # name servers we'll track */
struct __res_state {
...
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
unsigned short id; /* current message id */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
After calling res_init(3), _res.dnsrch contained part of the IPv6
nameserver address as pointer. The reason is a missing overflow
check when filling _res.nsaddr_list.
The sendmail crashes started when I updated and recomiled my libc
today. I have no idea, why this bug did not appear before.
ok?
bluhm
Index: lib/libc/asr/res_init.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/lib/libc/asr/res_init.c,v
retrieving revision 1.6
diff -u -p -r1.6 res_init.c
--- lib/libc/asr/res_init.c 5 Oct 2015 02:57:16 -0000 1.6
+++ lib/libc/asr/res_init.c 5 Nov 2015 21:30:08 -0000
@@ -39,7 +39,7 @@ res_init(void)
{
_THREAD_PRIVATE_MUTEX(init);
struct asr_ctx *ac;
- int i;
+ int i, j;
ac = _asr_use_resolver(NULL);
@@ -58,9 +58,13 @@ res_init(void)
strlcpy(_res.lookups, ac->ac_db, sizeof(_res.lookups));
_res.nscount = ac->ac_nscount;
- for (i = 0; i < ac->ac_nscount; i++) {
- memcpy(&_res.nsaddr_list[i], ac->ac_ns[i],
+ for (i = 0, j = 0; i < ac->ac_nscount && j < MAXNS; i++) {
+ if (ac->ac_ns[i]->sa_family != AF_INET ||
+ ac->ac_ns[i]->sa_len > sizeof(_res.nsaddr_list[j]))
+ continue;
+ memcpy(&_res.nsaddr_list[j], ac->ac_ns[i],
ac->ac_ns[i]->sa_len);
+ j++;
}
_res.options |= RES_INIT;
}