This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/2504] New: dns_getcanonname() unaligned problems
- From: "david dot mckay at st dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 3 Apr 2006 10:10:52 -0000
- Subject: [Bug libc/2504] New: dns_getcanonname() unaligned problems
- Reply-to: sourceware-bugzilla at sourceware dot org
While working on a glibc port to another processor, I came across a couple of
possible problems with the dns_getcanonname() function. The first is in
__lib_res_nquery() in resolve/res_query.c. The problem is that the
libc_res_nsend() function can reallocate the answer buffer. However on return
from this function only the original buffer is checked, not the buffer where
the answer data actually is. This results in dereferencing a uninitialised
stack location at the ntohs(hp->ancount) statement, and looking at the wrong
rcode return value.
The second problem is in the _nss_dns_getcanonname_r() function in
resolv/nss_dns/dns-canon.c. Here it assumes 16 bit alignment of data, whereas
the data is not necessarily aligned to this boundary, resulting in a misaligned
fault.
These possible bugs are present in 2.3.3 and appears to be present in the
latest CVS sources. Though I may be completely wrong in my analysis of course!
It may also be desirable to initialise these fields in res_nsend() when the
buffer is realloced, but my patch doesn't do this as I am not sure it is
needed.
Patch:
--- libc/resolv/res_query.c.orig 2006-03-30 17:24:00.000000000 +0100
+++ libc/resolv/res_query.c 2006-03-31 13:24:59.000000000 +0100
@@ -163,6 +163,8 @@
return (n);
}
+ hp = (HEADER*) (*answerp);
+
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
#ifdef DEBUG
if (statp->options & RES_DEBUG)
--- libc/resolv/nss_dns/dns-canon.c.orig 2006-03-31 17:47:39.000000000
+0100
+++ libc/resolv/nss_dns/dns-canon.c 2006-03-31 17:55:05.000000000 +0100
@@ -101,7 +101,7 @@
ptr += s;
/* Check whether type and class match. */
- unsigned int type = ntohs (*(uint16_t *) ptr);
+ unsigned int type = ntohs (ns_get16(ptr));
if (type == qtypes[i])
{
/* We found the record. */
@@ -131,14 +131,14 @@
goto unavail;
ptr += sizeof (uint16_t);
- if (*(uint16_t *) ptr != htons (ns_c_in))
+ if (ns_get16(ptr) != htons (ns_c_in))
goto unavail;
/* Also skip over the TTL. */
ptr += sizeof (uint16_t) + sizeof (uint32_t);
/* Skip over the data length and data. */
- ptr += sizeof (uint16_t) + ntohs (*(uint16_t *) ptr);
+ ptr += sizeof (uint16_t) + ntohs (ns_get16(ptr));
}
}
}
--
Summary: dns_getcanonname() unaligned problems
Product: glibc
Version: 2.3.3
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: drepper at redhat dot com
ReportedBy: david dot mckay at st dot com
CC: glibc-bugs at sources dot redhat dot com
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: st231-linux
GCC target triplet: st231-linux
http://sourceware.org/bugzilla/show_bug.cgi?id=2504
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.