diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | nss/nss_compat/compat-initgroups.c | 46 |
2 files changed, 27 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog index 1cafbb1882..6241a6369a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ 2018-06-25 Florian Weimer <fweimer@redhat.com> [BZ #18023] + * nss/nss_compat/compat-initgroups.c (getgrent_next_nss): Fall + back to malloc directly, without stack allocations. + +2018-06-25 Florian Weimer <fweimer@redhat.com> + + [BZ #18023] * nscd/aicache.c (addhstaiX): Use struct scratch_buffer instead of extend_alloca. diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c index 74414f4622..540eee863c 100644 --- a/nss/nss_compat/compat-initgroups.c +++ b/nss/nss_compat/compat-initgroups.c @@ -261,7 +261,6 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, overwrite the pointer with one to a bigger buffer. */ char *tmpbuf = buffer; size_t tmplen = buflen; - bool use_malloc = false; for (int i = 0; i < mystart; i++) { @@ -270,29 +269,26 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, == NSS_STATUS_TRYAGAIN && *errnop == ERANGE) { - if (__libc_use_alloca (tmplen * 2)) - { - if (tmpbuf == buffer) - { - tmplen *= 2; - tmpbuf = __alloca (tmplen); - } - else - tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2); - } - else - { - tmplen *= 2; - char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen); - - if (newbuf == NULL) - { - status = NSS_STATUS_TRYAGAIN; - goto done; - } - use_malloc = true; - tmpbuf = newbuf; - } + /* Check for overflow. */ + if (__glibc_unlikely (tmplen * 2 < tmplen)) + { + __set_errno (ENOMEM); + status = NSS_STATUS_TRYAGAIN; + goto done; + } + /* Increase the size. Make sure that we retry + with a reasonable size. */ + tmplen *= 2; + if (tmplen < 1024) + tmplen = 1024; + if (tmpbuf != buffer) + free (tmpbuf); + tmpbuf = malloc (tmplen); + if (__glibc_unlikely (tmpbuf == NULL)) + { + status = NSS_STATUS_TRYAGAIN; + goto done; + } } if (__builtin_expect (status != NSS_STATUS_NOTFOUND, 1)) @@ -320,7 +316,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user, status = NSS_STATUS_NOTFOUND; done: - if (use_malloc) + if (tmpbuf != buffer) free (tmpbuf); } |