From: Ingo Schwarze Date: Wed, 23 Apr 2014 21:06:41 +0000 (+0000) Subject: Audit malloc(3)/calloc(3)/realloc(3) usage. X-Git-Tag: VERSION_1_13_1~163 X-Git-Url: https://git.cameronkatri.com/mandoc.git/commitdiff_plain/c4641c1dc73700968ee90de85e04b2f32fbadc8a?ds=inline Audit malloc(3)/calloc(3)/realloc(3) usage. * 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). --- diff --git a/LICENSE b/LICENSE index d8d00fe7..35072fb2 100644 --- 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 Copyright (c) 2013 Franco Fichtner Copyright (c) 1999, 2004 Marc Espie Copyright (c) 1998, 2010 Todd C. Miller +Copyright (c) 2008 Otto Moerbeek Copyright (c) 2003 Jason McIntyre See the individual source files for information about who contributed diff --git a/Makefile b/Makefile index c9c8a844..57f3ce7f 100644 --- 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 index 00000000..e25d8374 --- /dev/null +++ b/compat_reallocarray.c @@ -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 + * + * 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 +#include +#include +#include + +#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*/ diff --git a/configure b/configure index 5a24bb58..1e4788c9 100755 --- 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 12b00e51..57cbfca1 100644 --- 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 * @@ -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; } diff --git a/mandoc_aux.c b/mandoc_aux.c index 25666a27..a4cb3c19 100644 --- a/mandoc_aux.c +++ b/mandoc_aux.c @@ -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 * Copyright (c) 2014 Ingo Schwarze @@ -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) { diff --git a/mandoc_aux.h b/mandoc_aux.h index 7cdbde2e..04f4baff 100644 --- a/mandoc_aux.h +++ b/mandoc_aux.h @@ -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 * Copyright (c) 2014 Ingo Schwarze @@ -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); diff --git a/mandocdb.c b/mandocdb.c index ddd9f165..4e4c37c6 100644 --- a/mandocdb.c +++ b/mandocdb.c @@ -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 * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -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 * diff --git a/manpath.c b/manpath.c index 01635cd8..61b2c7e0 100644 --- 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 * Copyright (c) 2011 Kristaps Dzonsons @@ -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); } diff --git a/mansearch.c b/mansearch.c index eec5ff13..f9892218 100644 --- a/mansearch.c +++ b/mansearch.c @@ -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 * Copyright (c) 2013, 2014 Ingo Schwarze @@ -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 * diff --git a/mdoc_argv.c b/mdoc_argv.c index f75b5406..e411d51a 100644 --- a/mdoc_argv.c +++ b/mdoc_argv.c @@ -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 * Copyright (c) 2012 Ingo Schwarze @@ -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); } diff --git a/mdoc_validate.c b/mdoc_validate.c index 8c394328..7cd856c6 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -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 * Copyright (c) 2010-2014 Ingo Schwarze @@ -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 b0320ea6..c6a40150 100644 --- 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 * Copyright (c) 2010-2014 Ingo Schwarze @@ -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 diff --git a/term_ps.c b/term_ps.c index f4fd7501..f274c150 100644 --- 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 * Copyright (c) 2014 Ingo Schwarze @@ -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 index 00000000..9a514e8e --- /dev/null +++ b/test-reallocarray.c @@ -0,0 +1,7 @@ +#include + +int +main(void) +{ + return( ! reallocarray(NULL, 2, 2)); +}