]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Use reallocarray(3) to fix a pontential overflow issue discovered by Coverity.
authorRoy Marples <roy@marples.name>
Tue, 3 May 2016 11:54:25 +0000 (11:54 +0000)
committerRoy Marples <roy@marples.name>
Tue, 3 May 2016 11:54:25 +0000 (11:54 +0000)
Provide a shim based on our eloop one if not available in libc.

compat/reallocarray.c [new file with mode: 0644]
compat/reallocarray.h [new file with mode: 0644]
configure
script.c

diff --git a/compat/reallocarray.c b/compat/reallocarray.c
new file mode 100644 (file)
index 0000000..2c77f08
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * reallocarray(3)
+ * Copyright (c) 2016 Roy Marples <roy@marples.name>
+ * All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "reallocarray.h"
+
+#define SQRT_SIZE_MAX (((size_t)1) << (sizeof(size_t) * CHAR_BIT / 2))
+void *
+reallocarray(void *ptr, size_t n, size_t size)
+{
+
+       if ((n | size) >= SQRT_SIZE_MAX && n > SIZE_MAX / size) {
+               errno = EOVERFLOW;
+               return NULL;
+       }
+       return realloc(ptr, n * size);
+}
diff --git a/compat/reallocarray.h b/compat/reallocarray.h
new file mode 100644 (file)
index 0000000..7d27fe2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * reallocarray(3)
+ * Copyright (c) 2016 Roy Marples <roy@marples.name>
+ * All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef REALLOCARRAY_H
+#define REALLOCARRAY_H
+
+void *reallocarray(void *, size_t, size_t);
+
+#endif
index 0090c034605c83d86ccfd0a153738e630c5c20aa..a58335ad6d7de3ab2587e748fdc222ce020c6bd0 100755 (executable)
--- a/configure
+++ b/configure
@@ -70,6 +70,7 @@ for x do
        --with-printf_m) HAVE_PRINTF_M=yes;;
        --without-printf_m) HAVE_PRINTF_M=no;;
         --without-posix_spawn) POSIX_SPAWN=no;;
+       --without-reallocarrray) REALLOCARRAY=no;;
        --without-md5) MD5=no;;
        --without-sha2) SHA2=no;;
        --without-sha256) SHA2=no;;
@@ -383,6 +384,11 @@ freebsd*|kfreebsd*)
        echo "#include          <net/if.h>" >>$CONFIG_H
        echo "#include          <net/if_var.h>" >>$CONFIG_H
        ;;
+netbsd*)
+       # reallocarray(3) is guarded by _OPENBSD_SOURCE
+       echo "CPPFLAGS+=        -D_OPENBSD_SOURCE" >>$CONFIG_MK
+       echo "DHCPCD_SRCS+=     if-bsd.c" >>$CONFIG_MK
+       ;;
 linux*)
        echo "CPPFLAGS+=        -D_GNU_SOURCE" >>$CONFIG_MK
        # Large File Support, should be fine for 32-bit systems.
@@ -890,6 +896,29 @@ else
        echo "#define HAVE_SPAWN_H" >>$CONFIG_H
 fi
 
+if [ -z "$REALLOCARRAY" ]; then
+       printf "Testing for reallocarray ... "
+       cat <<EOF >_reallocarray.c
+#include <stdlib.h>
+
+int main(void) {
+       reallocarray(NULL, 0, 0);
+       return 0;
+}
+EOF
+       if $XCC _reallocarray.c -o _reallocarray 2>&3; then
+               REALLOCARRAY=yes
+       else
+               REALLOCARRAY=no
+       fi
+       echo "$REALLOCARRAY"
+       rm -f _reallocarray.c _reallocarray
+fi
+if [ "$REALLOCARRAY" = no ]; then
+       echo "COMPAT_SRCS+=     compat/reallocarray.c" >>$CONFIG_MK
+       echo "#include          \"compat/reallocarray.h\"">>$CONFIG_H
+fi
+
 if [ -z "$POLL" ]; then
        printf "Testing for kqueue1 ... "
        cat <<EOF >_kqueue.c
index 0af7d7ecd7f009b61f69e20702ed7cf5c56aa71f..da781c7c7e840bd841cd0742d9fc019d427b6596 100644 (file)
--- a/script.c
+++ b/script.c
@@ -691,7 +691,7 @@ script_runreason(const struct interface *ifp, const char *reason)
 
        /* Resize for PATH and RC_SVCNAME */
        svcname = getenv(RC_SVCNAME);
-       ep = realloc(env, sizeof(char *) * (elen + 2 + (svcname ? 1 : 0)));
+       ep = reallocarray(env, elen + 2 + svcname ? 1 : 0, sizeof(char *));
        if (ep == NULL) {
                elen = 0;
                goto out;
@@ -778,7 +778,9 @@ out:
        while (*ep)
                free(*ep++);
        free(env);
-       if (elen == 0)
+       if (elen == 0) {
+               logger(ifp->ctx, LOG_ERR, "%s: malloc: %m", __func__);
                return -1;
+       }
        return WEXITSTATUS(status);
 }