diff options
author | Andreas Schwab <schwab@suse.de> | 2014-03-24 11:06:30 +0100 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2014-03-24 16:05:13 +0100 |
commit | 44152e4b05fcc8bae5628cdb37342d9b7bd5ac3c (patch) | |
tree | 0c1a902077c00afe9c0c90a549d04a193f015f77 | |
parent | b376a11a19aa7b64107081e4eed2327c25a131be (diff) | |
download | glibc-44152e4b05fcc8bae5628cdb37342d9b7bd5ac3c.zip glibc-44152e4b05fcc8bae5628cdb37342d9b7bd5ac3c.tar.gz glibc-44152e4b05fcc8bae5628cdb37342d9b7bd5ac3c.tar.bz2 |
Account for alloca use when collecting interface addresses (bug 16002)
To reproduce:
# ip li add name dummy0 type dummy
# site_id=$(head -c6 /dev/urandom | od -tx2 -An | tr ' ' ':')
# for ((i = 0; i < 65536; i++)) do
> ip ad ad $(printf fd80$site_id::%04x $i)/128 dev dummy0
> done
# (ulimit -s 900; getent ahosts localhost)
# ip li de dummy0
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/check_pf.c | 32 |
3 files changed, 37 insertions, 7 deletions
@@ -1,3 +1,9 @@ +2014-03-24 Andreas Schwab <schwab@suse.de> + + [BZ #16002] + * sysdeps/unix/sysv/linux/check_pf.c (make_request): Use + alloca_account and account alloca use for struct in6ailist. + 2014-03-24 Joseph Myers <joseph@codesourcery.com> [BZ #16284] @@ -9,9 +9,9 @@ Version 2.20 * The following bugs are resolved with this release: - 15347, 15804, 15894, 16284, 16447, 16532, 16545, 16574, 16600, 16609, - 16610, 16611, 16613, 16623, 16632, 16639, 16642, 16649, 16670, 16674, - 16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16731. + 15347, 15804, 15894, 16002, 16284, 16447, 16532, 16545, 16574, 16600, + 16609, 16610, 16611, 16613, 16623, 16632, 16639, 16642, 16649, 16670, + 16674, 16677, 16680, 16683, 16689, 16695, 16701, 16706, 16707, 16731. * Running the testsuite no longer terminates as soon as a test fails. Instead, a file tests.sum (xtests.sum from "make xcheck") is generated, diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c index 5c8e75a..6d8468d 100644 --- a/sysdeps/unix/sysv/linux/check_pf.c +++ b/sysdeps/unix/sysv/linux/check_pf.c @@ -139,9 +139,10 @@ make_request (int fd, pid_t pid) #endif bool use_malloc = false; char *buf; + size_t alloca_used = 0; if (__libc_use_alloca (buf_size)) - buf = alloca (buf_size); + buf = alloca_account (buf_size, alloca_used); else { buf = malloc (buf_size); @@ -163,6 +164,7 @@ make_request (int fd, pid_t pid) { struct in6addrinfo info; struct in6ailist *next; + bool use_malloc; } *in6ailist = NULL; size_t in6ailistlen = 0; bool seen_ipv4 = false; @@ -239,7 +241,19 @@ make_request (int fd, pid_t pid) } } - struct in6ailist *newp = alloca (sizeof (*newp)); + struct in6ailist *newp; + if (__libc_use_alloca (alloca_used + sizeof (*newp))) + { + newp = alloca_account (sizeof (*newp), alloca_used); + newp->use_malloc = false; + } + else + { + newp = malloc (sizeof (*newp)); + if (newp == NULL) + goto out_fail; + newp->use_malloc = true; + } newp->info.flags = (((ifam->ifa_flags & (IFA_F_DEPRECATED | IFA_F_OPTIMISTIC)) @@ -286,7 +300,10 @@ make_request (int fd, pid_t pid) do { result->in6ai[--in6ailistlen] = in6ailist->info; - in6ailist = in6ailist->next; + struct in6ailist *next = in6ailist->next; + if (in6ailist->use_malloc) + free (in6ailist); + in6ailist = next; } while (in6ailist != NULL); } @@ -302,7 +319,14 @@ make_request (int fd, pid_t pid) free (buf); return result; -out_fail: + out_fail: + while (in6ailist != NULL) + { + struct in6ailist *next = in6ailist->next; + if (in6ailist->use_malloc) + free (in6ailist); + in6ailist = next; + } if (use_malloc) free (buf); return NULL; |