summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authoreric <eric@openbsd.org>2013-04-01 07:47:26 +0000
committereric <eric@openbsd.org>2013-04-01 07:47:26 +0000
commitcd214be2c826f2ccad0f3aa1029e25d761d3ae3c (patch)
tree77066cc49d867b2872f333539b4a98e64d2f261d /lib/libc
parentupdate currency exchange rates; (diff)
downloadwireguard-openbsd-cd214be2c826f2ccad0f3aa1029e25d761d3ae3c.tar.xz
wireguard-openbsd-cd214be2c826f2ccad0f3aa1029e25d761d3ae3c.zip
fix alignment issue in the structure filled by gethostby{name,addr}()
spotted by naddy@
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/asr/gethostnamadr.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/libc/asr/gethostnamadr.c b/lib/libc/asr/gethostnamadr.c
index 219f36a1532..ae4beadb0b8 100644
--- a/lib/libc/asr/gethostnamadr.c
+++ b/lib/libc/asr/gethostnamadr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gethostnamadr.c,v 1.2 2012/11/24 15:12:48 eric Exp $ */
+/* $OpenBSD: gethostnamadr.c,v 1.3 2013/04/01 07:47:26 eric Exp $ */
/*
* Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
*
@@ -20,11 +20,16 @@
#include <errno.h>
#include <resolv.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "asr.h"
+#define PALIGN(p, l) \
+ ((char*)(p) + (((uintptr_t)(p) % (l)) ? \
+ (l) - (uintptr_t)(p) % (l) : 0))
+
static struct hostent *_gethostbyname(const char *, int);
static void _fillhostent(const struct hostent *, struct hostent *, char *buf,
size_t);
@@ -41,28 +46,32 @@ _fillhostent(const struct hostent *h, struct hostent *r, char *buf, size_t len)
size_t n, i;
int naliases, naddrs;
+ bzero(buf, len);
+ bzero(r, sizeof(*r));
+ r->h_aliases = _empty;
+ r->h_addr_list = _empty;
+
end = buf + len;
- ptr = (char**)buf; /* XXX align */
+ ptr = (char**)PALIGN(buf, sizeof(char*));
+
+ if ((char*)ptr >= end)
+ return;
for (naliases = 0; h->h_aliases[naliases]; naliases++)
;
for (naddrs = 0; h->h_addr_list[naddrs]; naddrs++)
;
+ pos = (char*)(ptr + (naliases + 1) + (naddrs + 1));
+ if (pos >= end)
+ return;
+
r->h_name = NULL;
r->h_addrtype = h->h_addrtype;
r->h_length = h->h_length;
r->h_aliases = ptr;
r->h_addr_list = ptr + naliases + 1;
- pos = (char*)(ptr + (naliases + 1) + (naddrs + 1));
- if (pos > end) {
- r->h_aliases = _empty;
- r->h_addr_list = _empty;
- return;
- }
- bzero(ptr, pos - (char*)ptr);
-
n = strlcpy(pos, h->h_name, end - pos);
if (n >= end - pos)
return;
@@ -77,6 +86,10 @@ _fillhostent(const struct hostent *h, struct hostent *r, char *buf, size_t len)
pos += n + 1;
}
+ pos = PALIGN(pos, r->h_length);
+ if (pos >= end)
+ return;
+
for (i = 0; i < naddrs; i++) {
if (r->h_length > end - pos)
return;