This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[patch] check and fix buffer alignment in _nss_dns_gethostbyaddr2_r
- From: Rafael Espindola <espindola at google dot com>
- To: libc-alpha at sourceware dot org
- Date: Wed, 31 Dec 2008 19:25:22 +0000
- Subject: [patch] check and fix buffer alignment in _nss_dns_gethostbyaddr2_r
The buffer argument to _nss_dns_gethostbyaddr2_r is a char* and need
not be 8 bytes aligned. On amd64, the host_data structure has to be 8
bytes aligned and the cast
host_data = (struct host_data *) buffer;
will cause problems if buffer is not 8 bytes aligned.
Other functions in dns-host.c (like getanswer_r) and
_nss_nis_gethostbyaddr_r in nis-hosts.c already check and fix the
buffer alignment. This patch is mostly a copy and paste of that
adjustment.
I did a "make check" on linux x86-64. Is that the normal patch test
procedure for glibc? How do I check the results? :-)
2008-12-31 Rafael Avila de Espindola <espindola@google.com>
* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyaddr2_r): Check and
adjust the buffer alignment.
Cheers,
--
Rafael Avila de Espindola
Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
? test.patch
Index: resolv/nss_dns/dns-host.c
===================================================================
RCS file: /cvs/glibc/libc/resolv/nss_dns/dns-host.c,v
retrieving revision 1.55
diff -u -r1.55 dns-host.c
--- resolv/nss_dns/dns-host.c 3 Dec 2008 07:09:26 -0000 1.55
+++ resolv/nss_dns/dns-host.c 31 Dec 2008 19:04:01 -0000
@@ -364,7 +364,7 @@
unsigned char host_addr[16]; /* IPv4 or IPv6 */
char *h_addr_ptrs[MAX_NR_ADDRS + 1];
char linebuffer[0];
- } *host_data = (struct host_data *) buffer;
+ } *host_data;
union
{
querybuf *buf;
@@ -376,6 +376,19 @@
int n, status;
int olderr = errno;
+ uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct host_data);
+ buffer += pad;
+ buflen = buflen > pad ? buflen - pad : 0;
+
+ if (__builtin_expect (buflen < sizeof(struct host_data), 0))
+ {
+ *errnop = ERANGE;
+ *h_errnop = NETDB_INTERNAL;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ host_data = (struct host_data *) buffer;
+
if (__res_maybe_init (&_res, 0) == -1)
return NSS_STATUS_UNAVAIL;