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
next prev 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).