public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: [PATCH 16/18] posix: More check for overflow allocation in glob
Date: Fri, 11 Aug 2017 14:51:00 -0000	[thread overview]
Message-ID: <1502463044-4042-17-git-send-email-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <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(-)

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)
 	{
-- 
2.7.4

  parent reply	other threads:[~2017-08-11 14:51 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-11 14:50 [PATCH v2 00/18] posix: glob fixes and refactor Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 09/18] posix: Use char_array for internal glob dirname Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 17/18] posix: Use enum for __glob_pattern_type result Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 06/18] posix: Remove glob GET_LOGIN_NAME_MAX usage Adhemerval Zanella
2017-09-02 22:50   ` Paul Eggert
2017-08-11 14:51 ` [PATCH 02/18] posix: Adjust glob tests to libsupport Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 10/18] posix: Remove alloca usage for GLOB_BRACE on glob Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 15/18] posix: Add common function to get home directory Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 14/18] posix: Use char_array for home_dir in glob Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 07/18] posix: User LOGIN_NAME_MAX for all user names " Adhemerval Zanella
2017-08-11 14:51 ` Adhemerval Zanella [this message]
2017-08-11 14:51 ` [PATCH 03/18] posix: Consolidate glob implementation Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 01/18] posix: Sync glob with gnulib [BZ #1062] Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 12/18] posix: Use dynarray for globname in glob Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 13/18] posix: Remove all alloca usage " Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 05/18] posix: Rewrite to use struct scratch_buffer instead of extend_alloca Adhemerval Zanella
2017-09-01 23:50   ` Paul Eggert
2017-09-02 10:40   ` Paul Eggert
2017-08-11 14:51 ` [PATCH 08/18] malloc: Add specialized dynarray for C strings Adhemerval Zanella
2017-08-17 10:12   ` Florian Weimer
2017-08-17 12:39     ` Adhemerval Zanella
2017-08-17 14:48     ` Pedro Alves
2017-08-11 14:51 ` [PATCH 04/18] posix: Allow glob to match dangling symlinks [BZ #866] Adhemerval Zanella
2017-08-31 22:11   ` Paul Eggert
2017-08-11 14:51 ` [PATCH 18/18] posix: Fix glob with GLOB_NOCHECK returning modified patterns (BZ#10246) Adhemerval Zanella
2017-08-11 14:51 ` [PATCH 11/18] posix: Remove alloca usage on glob dirname Adhemerval Zanella
2017-08-17 10:19 ` [PATCH v2 00/18] posix: glob fixes and refactor Florian Weimer
2017-08-17 12:07   ` Adhemerval Zanella
2017-08-17 14:11     ` Paul Eggert
2017-08-17 17:32       ` Adhemerval Zanella
2017-08-17 18:07         ` Florian Weimer
2017-08-17 19:51         ` Paul Eggert
2017-08-17 20:05           ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1502463044-4042-17-git-send-email-adhemerval.zanella@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).