From patchwork Thu Jun 8 21:13:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 103422 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp2633217qgd; Thu, 8 Jun 2017 14:17:07 -0700 (PDT) X-Received: by 10.98.147.142 with SMTP id r14mr11486080pfk.168.1496956627862; Thu, 08 Jun 2017 14:17:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496956627; cv=none; d=google.com; s=arc-20160816; b=Onl1sKhV+kTAnu5S82r5rcEKVcpNu36V1YoLcvfdQvlamWcc20vUC230afYMcMEuxb d3WUE4zlNt8bV+vS9gd53BwothbAFyTB8JSSshLYE73c3y1kCnyth/MVX8sYSugUaPrF yr43C5r7z9YdwdN7I/q6ujWl40yl7a9DWVkALTEBgwTW8Akd9Rc/Nxss0WTrs8YtBkkS CfIsay1vWbN89Kc1M5Po7PQoKAaVJPdAg+ypTiqP5Ujm4h0FxvtSxERzntafusrPyjNN FSE81EODuR/fQ8lHwFozy0RRjkP9hy/jrEUYOMGpQEsIlDsVQfqyIVpYfZdc4zM48Xsj nqRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=vKm4bLoEFjGS2Wp1IdI4wsvyJA895uL8gXks41B1DHM=; b=w5jDFC5UzCsdBYNR7zbJQnxUBank9G534XjK4sU6MdjhBdgQ+EFWK28mamJShe74pt 4kPjmpBdySS60d2C3U6HWcbwydRqdhKm20cL2eJfxXCMexMpju9QBIZaB7Eaq/J0ZoHJ WiosFzNOup1TzxSWlpsZVHPJm4LTwqkvEn/4eK6TmGHQFdrvrSukRAI94Ke20DJ5NHVD bXGcbYhQat52yGNgiKfY2kzKb/+qD+PIrGvBMsXM4s0XLPrne/HKNeHnIOs1VGx1kKj6 fhEIEBIAGAd6YEx5fd811geMwjPXND2eF7Hhu+T7imyvJnZE2XuLLdAWcj8qCGOJMt8r f3Ig== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-80216-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80216-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id q2si5276316plk.300.2017.06.08.14.17.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Jun 2017 14:17:07 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-80216-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-80216-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80216-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=G5tD2Ff54k7mayhL6rHBkXUai7O4fMi lFDCx4kUh9RUcQAvn9yos3y/I+pVgpsozvbEjDAQiVGbtEnq8fXhzS4ZiDzxqp79 ef2UGtBtNUydqrHelQ512O6dpoveDtYM5PfYZBVs/oAoOsdxswB2AVtizTGjPBMV 5N8ofLvCbTlE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=kVKv2XxiPQMN8iKHz67Nf11CJZo=; b=dpKnP xOhu1gDoupciWnzxdEXfwQs/6wysGS1YsXpup6WViUgicXDG+/P+vemSUCcrRirl upOOL5Yul0nGcFRanZdo6zTkTAgKyXxk/nbebLnqH3f52b4+lAoITz7xy0zDYaLf dF8CskxvAnvGyrACyVDU0HZl6pO2CY8nfOVSr0= Received: (qmail 41890 invoked by alias); 8 Jun 2017 21:14:30 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 41302 invoked by uid 89); 8 Jun 2017 21:14:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=vKm4bLoEFjGS2Wp1IdI4wsvyJA895uL8gXks41B1DHM=; b=DOD34K9r/8MhigwnGOjZqwPpLMSMIU4W8bgsYpIkNKGMB9RshjD3JvR2zwolr13y1G vmYbZEUz4IRM/3U+BX68Xyu4m+Geq81CiyagTdJpXefvcuMlwnDeSPMY1fc8t6V0ueEV jZpvE5lqazyd+GhM8fvIYGxWddi+ypwL+RjyEUOZ91KDWtuLW2Iii+XWfKSEPXmATced KM0lxWXYMhwB154Kuclji/4VeawxDO9qo6W1uh7mKWMtFx7t1XW72hfBJie29F5NydUS OKoMEwvjvkQ5q/duUsv8XdILgg/nHG/AdN+Et+rJJW3dtX5xRKRXFGKFdWpTxhCCpHzY Or5A== X-Gm-Message-State: AKS2vOx9HYPcUZUY1HBCTy9Lo0EUNR1wwRGFsfr9kEiL4GAdA7Fzcrfh Jl+cmEgH7GnqJ+Ptn7O27w== X-Received: by 10.55.182.135 with SMTP id g129mr20153212qkf.111.1496956464010; Thu, 08 Jun 2017 14:14:24 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 17/17] posix: More check for overflow allocation in glob Date: Thu, 8 Jun 2017 18:13:31 -0300 Message-Id: <1496956411-25594-18-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1496956411-25594-1-git-send-email-adhemerval.zanella@linaro.org> References: <1496956411-25594-1-git-send-email-adhemerval.zanella@linaro.org> This patch adds and replace the allocation overflow based using malloc internal functions check_add_wrapv_size_t and __libc_reallocarray. Checked on x86_64-linux-gnu. * posix/glob.c (glob_malloc_incr): New function. (glob_malloc_incr2): Likewise. (glob_realloc_incr): Likewise. (glob): Use glob_{realloc,malloc}_incr{2}. --- posix/glob.c | 92 +++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 29 deletions(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index 2b11e45..0de8233 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -302,6 +302,39 @@ get_home_directory (const char *user_name, struct char_array *home_dir) return retval; } +/* Allocate '(size + incr) * typesize' bytes while for overflow on the + arithmetic operations. */ +static void * +glob_malloc_incr (size_t size, size_t incr, size_t typesize) +{ + size_t newsize; + if (check_add_wrapv_size_t (size, incr, &newsize)) + return NULL; + return __libc_reallocarray (NULL, newsize, typesize); +} + +/* Allocate '(size + incr1 + incr2) * typesize' bytes while for overflow on + the arithmetic operations. */ +static void * +glob_malloc_incr2 (size_t size, size_t incr1, size_t incr2, size_t typesize) +{ + size_t newsize; + if (check_add_wrapv_size_t (size, incr1, &newsize) + || check_add_wrapv_size_t (newsize, incr2, &newsize)) + return NULL; + return __libc_reallocarray (NULL, newsize, typesize); +} + +/* Reallocate '(size + incr1) * typesize' bytes while for overflow on the + arithmetic operations. */ +static void * +glob_realloc_incr (void *old, size_t size, size_t incr, size_t typesize) +{ + size_t newsize; + if (check_add_wrapv_size_t (size, incr, &newsize)) + return NULL; + return __libc_reallocarray (old, newsize, typesize); +} /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -356,11 +389,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { size_t i; - if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *)) - goto err_nospace; - - pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) - * sizeof (char *)); + pglob->gl_pathv = glob_malloc_incr (pglob->gl_offs, 1, + sizeof (char *)); if (pglob->gl_pathv == NULL) goto err_nospace; @@ -816,10 +846,11 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), : (__lstat64 (char_array_str (&dirname), &st64) == 0 && S_ISDIR (st64.st_mode))))) { - size_t newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; + size_t newcount; - if (newcount > SIZE_MAX / sizeof (char *) - 2) + if (check_add_wrapv_size_t (pglob->gl_pathc, pglob->gl_offs, + &newcount)) { nospace: free (pglob->gl_pathv); @@ -828,8 +859,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), goto err_nospace; } - new_gl_pathv = realloc (pglob->gl_pathv, - (newcount + 2) * sizeof (char *)); + new_gl_pathv = glob_realloc_incr (pglob->gl_pathv, newcount, 2, + sizeof (char *)); if (new_gl_pathv == NULL) goto nospace; pglob->gl_pathv = new_gl_pathv; @@ -837,9 +868,12 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (flags & GLOB_MARK) { char *p; - pglob->gl_pathv[newcount] = malloc (dirlen + 2); + + pglob->gl_pathv[newcount] = glob_malloc_incr (dirlen, 2, + sizeof (char)); if (pglob->gl_pathv[newcount] == NULL) goto nospace; + p = mempcpy (pglob->gl_pathv[newcount], char_array_str (&dirname), dirlen); p[0] = '/'; @@ -976,18 +1010,19 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* No matches. */ if (flags & GLOB_NOCHECK) { - size_t newcount = pglob->gl_pathc + pglob->gl_offs; + size_t newcount; char **new_gl_pathv; - if (newcount > SIZE_MAX / sizeof (char *) - 2) + if (check_add_wrapv_size_t (pglob->gl_pathc, pglob->gl_offs, + &newcount)) { nospace2: globfree (&dirs); goto err_nospace; } - new_gl_pathv = realloc (pglob->gl_pathv, - (newcount + 2) * sizeof (char *)); + new_gl_pathv = glob_realloc_incr (pglob->gl_pathv, newcount, 2, + sizeof (char *)); if (new_gl_pathv == NULL) goto nospace2; pglob->gl_pathv = new_gl_pathv; @@ -1089,15 +1124,16 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), : (__lstat64 (pglob->gl_pathv[i], &st64) == 0 && (S_ISDIR (st64.st_mode) || S_ISLNK (st64.st_mode))))) { - size_t len = strlen (pglob->gl_pathv[i]) + 2; - char *new = realloc (pglob->gl_pathv[i], len); + size_t len = strlen (pglob->gl_pathv[i]); + char *new = glob_realloc_incr (pglob->gl_pathv[i], len, 2, + sizeof (char)); if (new == NULL) { globfree (pglob); pglob->gl_pathc = 0; goto err_nospace; } - strcpy (&new[len - 2], "/"); + strcpy (&new[len], "/"); pglob->gl_pathv[i] = new; } } @@ -1182,7 +1218,7 @@ prefix_array (const char *dirname, char **array, size_t n) for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; - char *new = malloc (dirlen + 1 + eltlen); + char *new = glob_malloc_incr2 (dirlen, 1, eltlen, sizeof (char)); if (new == NULL) { while (i > 0) @@ -1190,11 +1226,10 @@ prefix_array (const char *dirname, char **array, size_t n) return 1; } - { - char *endp = mempcpy (new, dirname, dirlen); - *endp++ = DIRSEP_CHAR; - mempcpy (endp, array[i], eltlen); - } + char *endp = mempcpy (new, dirname, dirlen); + *endp++ = DIRSEP_CHAR; + mempcpy (endp, array[i], eltlen); + free (array[i]); array[i] = new; } @@ -1345,16 +1380,15 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (nfound != 0) { char **new_gl_pathv; + size_t newlen; result = 0; - if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc - < pglob->gl_offs + nfound + 1) + if (check_add_wrapv_size_t (pglob->gl_pathc, pglob->gl_offs, &newlen) + || check_add_wrapv_size_t (newlen, nfound, &newlen) + || check_add_wrapv_size_t (newlen, 1, &newlen)) goto memory_error; - new_gl_pathv - = realloc (pglob->gl_pathv, - (pglob->gl_pathc + pglob->gl_offs + nfound + 1) - * sizeof (char *)); + new_gl_pathv = realloc (pglob->gl_pathv, newlen * sizeof (char *)); if (new_gl_pathv == NULL) {