This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH][BZ #16072] Fix stack overflow due to large AF_INET6 requests
- From: Siddhesh Poyarekar <siddhesh at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 22 Oct 2013 18:21:04 +0530
- Subject: Re: [PATCH][BZ #16072] Fix stack overflow due to large AF_INET6 requests
- Authentication-results: sourceware.org; auth=none
- References: <20131022071550 dot GG11038 at spoyarek dot pnq dot redhat dot com>
On Tue, Oct 22, 2013 at 12:45:51PM +0530, Siddhesh Poyarekar wrote:
> Hi,
>
> This patch fixes another stack overflow in getaddrinfo when it is
> called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914,
> but the AF_INET case went undetected back then.
>
> Tested on x86_64 - same reproducer as 16071, with AF_INET6 instead of
> AF_INET. OK to commit? Also, should I add another NEWS item for this
> with this CVE number or should I post a request for another CVE?
>
> Siddhesh
>
> [BZ #16072]
> * sysdeps/posix/getaddrinfo.c (gethosts): Allocate tmpbuf on
> heap for large requests.
>
A (very) slightly improved patch - fixed alloca accounting in
gethosts.
Siddhesh
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 0f4b885..69bc97b 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
&rc, &herrno, NULL, &localcanon)); \
if (rc != ERANGE || herrno != NETDB_INTERNAL) \
break; \
- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
+ if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
+ tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
+ alloca_used); \
+ else \
+ { \
+ char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
+ 2 * tmpbuflen); \
+ if (newp == NULL) \
+ { \
+ result = -EAI_MEMORY; \
+ goto free_and_return; \
+ } \
+ tmpbuf = newp; \
+ malloc_tmpbuf = true; \
+ tmpbuflen = 2 * tmpbuflen; \
+ } \
} \
if (status == NSS_STATUS_SUCCESS && rc == 0) \
h = &th; \
@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
{ \
__set_h_errno (herrno); \
_res.options |= old_res_options & RES_USE_INET6; \
- return -EAI_SYSTEM; \
+ result = -EAI_SYSTEM; \
+ goto free_and_return; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \