Alignment fixups for gethostbyname_r

Daniel Jacobowitz drow at false.org
Wed Dec 19 16:57:28 UTC 2007


MontaVista noticed that when their kernels were configured to trap
on unaligned access gethostbyname_r could mysteriously crash.  I
tracked this down to an unaligned buffer being passed to
gethostbyname_r from some other part of uClibc (afraid I don't
remember where from any more).  We have to pad the beginning of
the buffer to a pointer alignment before we store pointers in
it.

Is this patch OK?

-- 
Daniel Jacobowitz
CodeSourcery

--- libc/inet/resolv.c	(revision 189757)
+++ libc/inet/resolv.c	(local)
@@ -1534,6 +1534,15 @@ int attribute_hidden __read_etc_hosts_r(
 	char *cp, **alias;
 	int aliases, i, ret = HOST_NOT_FOUND;
 
+	/* Align to at least the size of a char * so we can put
+	   pointers in it.  */
+	i = (unsigned long) buf % sizeof(char *);
+	i = (sizeof(char *) - i) % sizeof(char *);
+	if (buflen < i)
+		return ERANGE;
+	buf+=i;
+	buflen-=i;
+
 	if (buflen < sizeof(char *)*(ALIAS_DIM))
 		return ERANGE;
 	alias = (char **)buf;
@@ -2030,6 +2039,16 @@ int gethostbyname_r(const char * name,
 	DPRINTF("Nothing found in /etc/hosts\n");
 
 	*h_errnop = NETDB_INTERNAL;
+
+	/* Align to at least the size of a char * so we can put
+	   pointers in it.  */
+	i = (unsigned long) buf % sizeof(char *);
+	i = (sizeof(char *) - i) % sizeof(char *);
+	if (buflen < i)
+		return ERANGE;
+	buf+=i;
+	buflen-=i;
+
 	if (buflen < sizeof(*in))
 		return ERANGE;
 	in = (struct in_addr*)buf;



More information about the uClibc mailing list