]> git.cameronkatri.com Git - mandoc.git/commitdiff
Audit malloc(3)/calloc(3)/realloc(3) usage.
authorIngo Schwarze <schwarze@openbsd.org>
Wed, 23 Apr 2014 21:06:41 +0000 (21:06 +0000)
committerIngo Schwarze <schwarze@openbsd.org>
Wed, 23 Apr 2014 21:06:41 +0000 (21:06 +0000)
* Change eight reallocs to reallocarray to be safe from overflows.
* Change one malloc to reallocarray to be safe from overflows.
* Change one calloc to reallocarray, no zeroing needed.
* Change the order of arguments of three callocs (aesthetical).

15 files changed:
LICENSE
Makefile
compat_reallocarray.c [new file with mode: 0644]
configure
eqn.c
mandoc_aux.c
mandoc_aux.h
mandocdb.c
manpath.c
mansearch.c
mdoc_argv.c
mdoc_validate.c
term.c
term_ps.c
test-reallocarray.c [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
index d8d00fe78166cd959f8c014d4aad46b2ef01d96e..35072fb2d1bac89bdb4b3d25d818c07e69c0ca53 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-$Id: LICENSE,v 1.1 2014/04/22 22:03:22 schwarze Exp $
+$Id: LICENSE,v 1.2 2014/04/23 21:06:41 schwarze Exp $
 
 With the exceptions noted below, all code and documentation
 contained in the mdocml toolkit is protected by the Copyright
@@ -10,6 +10,7 @@ Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
 Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
 Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
 Copyright (c) 1998, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
+Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
 Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
 
 See the individual source files for information about who contributed
index c9c8a844b004bd4930bbba27cf982c1358b05b72..57f3ce7f635ee36597d842e80965ffa4e060916c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,7 @@ TESTSRCS       = test-fgetln.c \
                   test-getsubopt.c \
                   test-mmap.c \
                   test-ohash.c \
+                  test-reallocarray.c \
                   test-strlcat.c \
                   test-strlcpy.c \
                   test-strnlen.c \
@@ -86,6 +87,7 @@ SRCS           = LICENSE \
                   compat_getsubopt.c \
                   compat_ohash.c \
                   compat_ohash.h \
+                  compat_reallocarray.c \
                   compat_strcasestr.c \
                   compat_strlcat.c \
                   compat_strlcpy.c \
@@ -213,6 +215,7 @@ LIBMANDOC_OBJS       = $(LIBMAN_OBJS) \
 COMPAT_OBJS     = compat_fgetln.o \
                   compat_getsubopt.o \
                   compat_ohash.o \
+                  compat_reallocarray.o \
                   compat_strcasestr.o \
                   compat_strlcat.o \
                   compat_strlcpy.o \
diff --git a/compat_reallocarray.c b/compat_reallocarray.c
new file mode 100644 (file)
index 0000000..e25d837
--- /dev/null
@@ -0,0 +1,45 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_REALLOCARRAY
+
+int dummy;
+
+#else
+
+/*     $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $       */
+/*
+ * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <sys/types.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
+
+void *
+reallocarray(void *optr, size_t nmemb, size_t size)
+{
+       if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+           nmemb > 0 && SIZE_MAX / nmemb < size) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       return realloc(optr, size * nmemb);
+}
+
+#endif /*!HAVE_REALLOCARRAY*/
index 5a24bb585062b3541189a1e77a2b8d3ecc3665c9..1e4788c9d775c6fe5fa568e97246bf59e48696fc 100755 (executable)
--- a/configure
+++ b/configure
@@ -34,6 +34,7 @@ runtest fgetln FGETLN
 runtest getsubopt GETSUBOPT
 runtest mmap MMAP
 runtest ohash OHASH
+runtest reallocarray REALLOCARRAY
 runtest strcasestr STRCASESTR
 runtest strlcat STRLCAT
 runtest strlcpy STRLCPY
diff --git a/eqn.c b/eqn.c
index 12b00e5168eb6d12dd93dac4789d8350c77f576c..57cbfca185b4a6071cf77c4cdcbbae90b3d1681f 100644 (file)
--- a/eqn.c
+++ b/eqn.c
@@ -1,4 +1,4 @@
-/*     $Id: eqn.c,v 1.41 2014/04/20 19:40:13 schwarze Exp $ */
+/*     $Id: eqn.c,v 1.42 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  *
@@ -864,8 +864,8 @@ eqn_do_define(struct eqn_node *ep)
 
                if (i == (int)ep->defsz) {
                        ep->defsz++;
-                       ep->defs = mandoc_realloc(ep->defs,
-                           ep->defsz * sizeof(struct eqn_def));
+                       ep->defs = mandoc_reallocarray(ep->defs,
+                           ep->defsz, sizeof(struct eqn_def));
                        ep->defs[i].key = ep->defs[i].val = NULL;
                }
 
index 25666a275ddb402dd03c962759c628b19e02660c..a4cb3c194673d149c58ada4929534a63d2e55331 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mandoc_aux.c,v 1.1 2014/03/23 11:59:17 schwarze Exp $ */
+/*     $Id: mandoc_aux.c,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -80,6 +80,18 @@ mandoc_realloc(void *ptr, size_t size)
        return(ptr);
 }
 
+void *
+mandoc_reallocarray(void *ptr, size_t num, size_t size)
+{
+
+       ptr = reallocarray(ptr, num, size);
+       if (NULL == ptr) {
+               perror(NULL);
+               exit((int)MANDOCLEVEL_SYSERR);
+       }
+       return(ptr);
+}
+
 char *
 mandoc_strdup(const char *ptr)
 {
index 7cdbde2ee552615671c346c1faaf84a11967640d..04f4baff6065dcb170d04705fbb6683aecfca5dc 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mandoc_aux.h,v 1.1 2014/03/23 11:59:17 schwarze Exp $ */
+/*     $Id: mandoc_aux.h,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -24,6 +24,7 @@ int             mandoc_asprintf(char **, const char *, ...);
 void            *mandoc_calloc(size_t, size_t);
 void            *mandoc_malloc(size_t);
 void            *mandoc_realloc(void *, size_t);
+void            *mandoc_reallocarray(void *, size_t, size_t);
 char            *mandoc_strdup(const char *);
 char            *mandoc_strndup(const char *, size_t);
 
index ddd9f1651d1880f5d6df088faa8ee07c984b62b5..4e4c37c67e22d969fc895922b19a257bcb080a71 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mandocdb.c,v 1.143 2014/04/23 19:09:16 schwarze Exp $ */
+/*     $Id: mandocdb.c,v 1.144 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -471,8 +471,8 @@ main(int argc, char *argv[])
                 * manpath_parse() wants to do it.
                 */
                if (argc > 0) {
-                       dirs.paths = mandoc_calloc(argc,
-                           sizeof(char *));
+                       dirs.paths = mandoc_reallocarray(NULL,
+                           argc, sizeof(char *));
                        dirs.sz = (size_t)argc;
                        for (i = 0; i < argc; i++)
                                dirs.paths[i] = mandoc_strdup(argv[i]);
@@ -1784,7 +1784,7 @@ putkeys(const struct mpage *mpage,
                s->mask |= v;
                return;
        } else if (NULL == s) {
-               s = mandoc_calloc(sizeof(struct str) + sz + 1, 1);
+               s = mandoc_calloc(1, sizeof(struct str) + sz + 1);
                memcpy(s->key, cp, sz);
                ohash_insert(htab, slot, s);
        }
@@ -2314,7 +2314,7 @@ static void *
 hash_halloc(size_t sz, void *arg)
 {
 
-       return(mandoc_calloc(sz, 1));
+       return(mandoc_calloc(1, sz));
 }
 
 static void *
index 01635cd803fa0b3275824e6ac344763679a2fa57..61b2c7e05077435ad7f6467071f43b17748269d8 100644 (file)
--- a/manpath.c
+++ b/manpath.c
@@ -1,4 +1,4 @@
-/*     $Id: manpath.c,v 1.14 2014/04/20 16:46:05 schwarze Exp $ */
+/*     $Id: manpath.c,v 1.15 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -169,8 +169,8 @@ manpath_add(struct manpaths *dirs, const char *dir)
                if (0 == strcmp(dirs->paths[i], dir))
                        return;
 
-       dirs->paths = mandoc_realloc(dirs->paths,
-           (dirs->sz + 1) * sizeof(char *));
+       dirs->paths = mandoc_reallocarray(dirs->paths,
+           dirs->sz + 1, sizeof(char *));
 
        dirs->paths[dirs->sz++] = mandoc_strdup(cp);
 }
index eec5ff132be318febfdfbdaecf00a22bbb777c59..f9892218fb6f3da292eef02c37c34ac7e917f5ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mansearch.c,v 1.35 2014/04/23 16:34:50 schwarze Exp $ */
+/*     $Id: mansearch.c,v 1.36 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -328,8 +328,8 @@ mansearch(const struct mansearch *search,
                                mp = ohash_next(&htab, &idx)) {
                        if (cur + 1 > maxres) {
                                maxres += 1024;
-                               *res = mandoc_realloc(*res,
-                                   maxres * sizeof(struct manpage));
+                               *res = mandoc_reallocarray(*res,
+                                   maxres, sizeof(struct manpage));
                        }
                        mpage = *res + cur;
                        mpage->form = mp->form;
@@ -793,7 +793,7 @@ static void *
 hash_halloc(size_t sz, void *arg)
 {
 
-       return(mandoc_calloc(sz, 1));
+       return(mandoc_calloc(1, sz));
 }
 
 static void *
index f75b540683b5b85c5da1a53667f1d789ab9f2a34..e411d51abbb2a6e25fc40c12594e08d1697345c7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_argv.c,v 1.92 2014/04/20 16:46:05 schwarze Exp $ */
+/*     $Id: mdoc_argv.c,v 1.93 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2012 Ingo Schwarze <schwarze@openbsd.org>
@@ -359,8 +359,8 @@ mdoc_argv(struct mdoc *mdoc, int line, enum mdoct tok,
                arg = *v = mandoc_calloc(1, sizeof(struct mdoc_arg));
 
        arg->argc++;
-       arg->argv = mandoc_realloc(arg->argv,
-           arg->argc * sizeof(struct mdoc_argv));
+       arg->argv = mandoc_reallocarray(arg->argv,
+           arg->argc, sizeof(struct mdoc_argv));
 
        memcpy(&arg->argv[(int)arg->argc - 1], &tmp,
            sizeof(struct mdoc_argv));
@@ -667,8 +667,8 @@ argv_multi(struct mdoc *mdoc, int line,
                        break;
 
                if (0 == v->sz % MULTI_STEP)
-                       v->value = mandoc_realloc(v->value,
-                           (v->sz + MULTI_STEP) * sizeof(char *));
+                       v->value = mandoc_reallocarray(v->value,
+                           v->sz + MULTI_STEP, sizeof(char *));
 
                v->value[(int)v->sz] = mandoc_strdup(p);
        }
index 8c394328ab3048b13ea1c134778e3ceed620ca81..7cd856c661f71442f93032c8f3423b2c861e73fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: mdoc_validate.c,v 1.213 2014/04/23 16:08:33 schwarze Exp $ */
+/*     $Id: mdoc_validate.c,v 1.214 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -1460,8 +1460,8 @@ post_bl_block_tag(POST_ARGS)
        assert(n->args);
        i = (int)(n->args->argc)++;
 
-       n->args->argv = mandoc_realloc(n->args->argv,
-           n->args->argc * sizeof(struct mdoc_argv));
+       n->args->argv = mandoc_reallocarray(n->args->argv,
+           n->args->argc, sizeof(struct mdoc_argv));
 
        n->args->argv[i].arg = MDOC_Width;
        n->args->argv[i].line = n->line;
@@ -1521,8 +1521,8 @@ post_bl_head(POST_ARGS)
         */
 
        np->args->argv[j].sz = (size_t)mdoc->last->nchild;
-       np->args->argv[j].value = mandoc_malloc(
-           (size_t)mdoc->last->nchild * sizeof(char *));
+       np->args->argv[j].value = mandoc_reallocarray(NULL,
+           (size_t)mdoc->last->nchild, sizeof(char *));
 
        mdoc->last->norm->Bl.ncols = np->args->argv[j].sz;
        mdoc->last->norm->Bl.cols = (void *)np->args->argv[j].value;
diff --git a/term.c b/term.c
index b0320ea6380335520c54a8af542cfe97d4c3b975..c6a4015019c2fc6ffcd68203d15b6f883ea5dd82 100644 (file)
--- a/term.c
+++ b/term.c
@@ -1,4 +1,4 @@
-/*     $Id: term.c,v 1.222 2014/04/20 16:46:05 schwarze Exp $ */
+/*     $Id: term.c,v 1.223 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -522,7 +522,7 @@ adjbuf(struct termp *p, size_t sz)
        while (sz >= p->maxcols)
                p->maxcols <<= 2;
 
-       p->buf = mandoc_realloc(p->buf, sizeof(int) * p->maxcols);
+       p->buf = mandoc_reallocarray(p->buf, p->maxcols, sizeof(int));
 }
 
 static void
index f4fd75016c526d1f87222c67d279a5654451228b..f274c1503b463decf3956de393fea994ae937039 100644 (file)
--- a/term_ps.c
+++ b/term_ps.c
@@ -1,4 +1,4 @@
-/*     $Id: term_ps.c,v 1.59 2014/04/20 16:46:05 schwarze Exp $ */
+/*     $Id: term_ps.c,v 1.60 2014/04/23 21:06:41 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -628,12 +628,8 @@ pdf_obj(struct termp *p, size_t obj)
 
        if ((obj - 1) >= p->ps->pdfobjsz) {
                p->ps->pdfobjsz = obj + 128;
-               p->ps->pdfobjs = realloc(p->ps->pdfobjs,
-                   p->ps->pdfobjsz * sizeof(size_t));
-               if (NULL == p->ps->pdfobjs) {
-                       perror(NULL);
-                       exit((int)MANDOCLEVEL_SYSERR);
-               }
+               p->ps->pdfobjs = mandoc_reallocarray(p->ps->pdfobjs,
+                   p->ps->pdfobjsz, sizeof(size_t));
        }
 
        p->ps->pdfobjs[(int)obj - 1] = p->ps->pdfbytes;
@@ -1169,7 +1165,5 @@ ps_growbuf(struct termp *p, size_t sz)
                sz = PS_BUFSLOP;
 
        p->ps->psmargsz += sz;
-
-       p->ps->psmarg = mandoc_realloc
-               (p->ps->psmarg, p->ps->psmargsz);
+       p->ps->psmarg = mandoc_realloc(p->ps->psmarg, p->ps->psmargsz);
 }
diff --git a/test-reallocarray.c b/test-reallocarray.c
new file mode 100644 (file)
index 0000000..9a514e8
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdlib.h>
+
+int
+main(void)
+{
+       return( ! reallocarray(NULL, 2, 2));
+}