From patchwork Fri Aug 11 14:50:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 109900 Delivered-To: patch@linaro.org Received: by 10.182.109.195 with SMTP id hu3csp978579obb; Fri, 11 Aug 2017 07:54:46 -0700 (PDT) X-Received: by 10.84.136.131 with SMTP id 3mr18315286pll.149.1502463286644; Fri, 11 Aug 2017 07:54:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502463286; cv=none; d=google.com; s=arc-20160816; b=KiO9h8BVL72pMGTOkwKJpOkrC3VNKKWAuMNLAyf1X0EuPzP+R/Yct2SheV6BijhHdN nB4IxlyRwtlGXYHEZ8DcJZj4GfxGogDVg9xNm3lKRiocyAG1Inxcb8Gyrm4TI7pe1VMj OLWzfEFabltASi3hEodMxWbUpMDsyDazQ48juNgkgwjLBKAnC6pyxP+vOT3iNyaAbUiC DarBMRIH0d4nm1WIiQdgjyDaa5y47psvoCae0O364BlhOOL3jw5wCdmo1VVFxp2GE+z0 jAOO5+CfYLiZ24HNahyPvS2FATFDUQxxijSJl7OtPcg4qHEVqvz5w+zCfxbpebr5dBkx PSig== 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=8Vi/qT6LUKc6gucjp+gE4JG5KMABTwG6RM6HY9jh7B8=; b=VDdRN8uqyo8llIWebYVt6e9XexSDaLWzjp3KSUSaJFpBeJEoIwGBt/yfEdsLFlpj+E J0ZXtD0dauUjVRTQa8r8H877Ssm1BMkSxYmaSL/mru4g5WF/53BkGDMv3+Ga0gsPFGw4 DpDSpzqRNDT62mZDqQzhUD+aVSujgyAsXt6LMAUT+Sr244VBcdZw4HLBeeSrhkTV/R+E Fjpxqsjg0KU2MhU342pXNck/2nQLtihLtWifgfvlWCJ0JVT1A/nfFeIYoxnCR922q5Th 69pnmJo1sKirGnnzWkf1JCj8CSg2jw0/TIfLSaxPvf1Q88zeuANZWLodEHcvooGfEcqj GM1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=hKwggsuH; spf=pass (google.com: domain of libc-alpha-return-83042-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-83042-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 f15si621380pfj.33.2017.08.11.07.54.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Aug 2017 07:54:46 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-83042-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 header.s=default header.b=hKwggsuH; spf=pass (google.com: domain of libc-alpha-return-83042-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-83042-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=VWtAtENO5ftx01OrSQj9aGKqXK78BqG 2ImcNT9vP6g32+1n9ecX6r3p5Vt08fX8R80Ffuec2Ylw/nNBsOD21YUr8UFtlEJ6 loK0dEJ2z2dunriMNjmu0dEWnkm9Cfsv7W5QdOYIJgZF3XcJkaGQG9JhaY1rY0po iVfSCGkrwY9o= 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=f5wz5Dx/BRfYj46yIjVvug0D48k=; b=hKwgg suHjS0K//c9fhujwSJUOsrBYbOMpIXxPGM3yyb2zuu13GsSS5/xhz8RKQsxHenvO psNt0IwBZXgEipwmePmnifaQrTfzrKT4iwUt7b1nb0rlnm9fqFS4IG2JIEetA1PR ITYQ7B8QhMRqDjRCrVwz/43Kai+soJ4IaLnCDM= Received: (qmail 91773 invoked by alias); 11 Aug 2017 14:51:36 -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 80126 invoked by uid 89); 11 Aug 2017 14:51:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-27.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=Hx-languages-length:6094 X-HELO: mail-qt0-f179.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=8Vi/qT6LUKc6gucjp+gE4JG5KMABTwG6RM6HY9jh7B8=; b=ZzGnrq9fwzK6Kp7SI3M818aUqws1NFDcWsp89FrXqiYHf6j3QHIhfZE5s3U8wMr6NA G1+rWU3BmK6+KcN9BycM/s53dhHu2q6bJgXWKjJEVs1yrADt46ydG6QWlo/6Fuyp/7ID GR31Ei5VrlPvGAdjDLz6dxQ2fT489qymgtvQp/fJswltMwmwtVmlHcZCuxpnOXUCeTLX /RGMPlm8Zi4OhVc2SYLIU/1rWBdmhDF0vcE3QKDaVA2nj73d/hNrtbTQHhh+jmiMD+Nj b7bHV7B5Zfc/a9DROZSfEqMh0wG6DP36H151bIq52eku9pOJqX9kCwk2VW1tq+GKNIXb I89Q== X-Gm-Message-State: AHYfb5hT9iNiGdH7lZmhnPm8fR2QAApNxwN78CJ8rJrmu+YcHeiknYHu oX0aAzydRd5Ki6c+Hvvzmw== X-Received: by 10.200.1.204 with SMTP id b12mr20262384qtg.2.1502463072618; Fri, 11 Aug 2017 07:51:12 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 16/18] posix: More check for overflow allocation in glob Date: Fri, 11 Aug 2017 11:50:42 -0300 Message-Id: <1502463044-4042-17-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1502463044-4042-1-git-send-email-adhemerval.zanella@linaro.org> References: <1502463044-4042-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 c85342a..647334d 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -303,6 +303,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_overflow_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_overflow_size_t (size, incr1, &newsize) + || check_add_overflow_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_overflow_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. @@ -357,11 +390,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; @@ -817,10 +847,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_overflow_size_t (pglob->gl_pathc, pglob->gl_offs, + &newcount)) { nospace: free (pglob->gl_pathv); @@ -829,8 +860,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; @@ -838,9 +869,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] = '/'; @@ -978,18 +1012,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_overflow_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; @@ -1091,15 +1126,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; } } @@ -1184,7 +1220,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) @@ -1192,11 +1228,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; } @@ -1349,16 +1384,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_overflow_size_t (pglob->gl_pathc, pglob->gl_offs, &newlen) + || check_add_overflow_size_t (newlen, nfound, &newlen) + || check_add_overflow_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) {