]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2845] Harden memory allocation in ntpd
authorJuergen Perlinger <perlinger@ntp.org>
Tue, 9 Jun 2015 21:58:56 +0000 (23:58 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Tue, 9 Jun 2015 21:58:56 +0000 (23:58 +0200)
 implement and use 'eallocarray(...)' where appropriate

bk: 557761a0USeVPFgg6Fs6jOyVeUmzvA

ChangeLog
include/ntp_stdlib.h
libntp/emalloc.c
ntpd/ntp_config.c
ntpd/ntp_crypto.c
ntpd/ntp_monitor.c
ntpq/ntpq-subs.c
sntp/kod_management.c

index 97d1605aae0d4d06913b45f5f2040481776fa3bd..eb8a2e8be48ba30d866b643ac8ec405b49a614f2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 ---
 
+* [Bug 2845] Harden memory allocation in ntpd
 * [Bug 2824] Convert update-leap to perl. (also see 2769)
 * [Bug 2830] ntpd doesn't always transfer the correct TAI offset via autokey
    NTPD transfers the current TAI (instead of an announcement) now.
index 38180f0d78f255a3902acd213113b17b3a53aa5f..bad2697d06fd7875126ff469b68db60c7bbbf986 100644 (file)
@@ -102,26 +102,35 @@ extern    u_int32 addr2refid      (sockaddr_u *);
 /* emalloc.c */
 #ifndef EREALLOC_CALLSITE      /* ntp_malloc.h defines */
 extern void *  ereallocz       (void *, size_t, size_t, int);
-#define        erealloczsite(p, n, o, z, f, l) ereallocz(p, n, o, (z))
-#define        emalloc(n)              ereallocz(NULL, n, 0, FALSE)
+extern void *  oreallocarray   (void *optr, size_t nmemb, size_t size);
+#define        erealloczsite(p, n, o, z, f, l) ereallocz((p), (n), (o), (z))
+#define        emalloc(n)              ereallocz(NULL, (n), 0, FALSE)
 #define        emalloc_zero(c)         ereallocz(NULL, (c), 0, TRUE)
-#define        erealloc(p, c)          ereallocz(p, (c), 0, FALSE)
-#define erealloc_zero(p, n, o) ereallocz(p, n, (o), TRUE)
-extern char *  estrdup_impl    (const char *);
+#define        erealloc(p, c)          ereallocz((p), (c), 0, FALSE)
+#define erealloc_zero(p, n, o) ereallocz((p), (n), (o), TRUE)
+#define ereallocarray(p, n, s) oreallocarray((p), (n), (s))
+#define eallocarray(n, s)      oreallocarray(NULL, (n), (s))
+extern char *  estrdup_impl(const char *);
 #define        estrdup(s)              estrdup_impl(s)
 #else
 extern void *  ereallocz       (void *, size_t, size_t, int,
                                 const char *, int);
+extern void *  oreallocarray   (void *optr, size_t nmemb, size_t size,
+                                const char *, int);
 #define erealloczsite          ereallocz
 #define        emalloc(c)              ereallocz(NULL, (c), 0, FALSE, \
                                          __FILE__, __LINE__)
 #define        emalloc_zero(c)         ereallocz(NULL, (c), 0, TRUE, \
                                          __FILE__, __LINE__)
-#define        erealloc(p, c)          ereallocz(p, (c), 0, FALSE, \
+#define        erealloc(p, c)          ereallocz((p), (c), 0, FALSE, \
+                                         __FILE__, __LINE__)
+#define        erealloc_zero(p, n, o)  ereallocz((p), (n), (o), TRUE, \
+                                         __FILE__, __LINE__)
+#define ereallocarray(p, n, s) oreallocarray((p), (n), (s), \
                                          __FILE__, __LINE__)
-#define        erealloc_zero(p, n, o)  ereallocz(p, n, (o), TRUE, \
+#define eallocarray(n, s)      oreallocarray(NULL, (n), (s), \
                                          __FILE__, __LINE__)
-extern char *  estrdup_impl    (const char *, const char *, int);
+extern char *  estrdup_impl(const char *, const char *, int);
 #define        estrdup(s) estrdup_impl((s), __FILE__, __LINE__)
 #endif
 
index 6c1c6787ea41fc134af1689f051757d5e169fdaf..95d293f1c3dca55814f3927a9e8674175fd72ee5 100644 (file)
@@ -60,6 +60,59 @@ ereallocz(
        return mem;
 }
 
+/* oreallocarray.c is licensed under the following:
+ * 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 <stdint.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW        ((size_t)1 << (sizeof(size_t) * 4))
+
+void *
+oreallocarray(
+       void *optr,
+       size_t nmemb,
+       size_t size
+#ifdef EREALLOC_CALLSITE               /* ntp_malloc.h */
+       ,
+       const char *    file,
+       int             line
+#endif
+       )
+{
+       if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+           nmemb > 0 && SIZE_MAX / nmemb < size) {
+#ifndef EREALLOC_CALLSITE
+               msyslog(LOG_ERR, "fatal allocation size overflow");
+#else
+               msyslog(LOG_ERR,
+                       "fatal allocation size overflow %s line %d",
+                       file, line);
+#endif
+               exit(1);
+       }
+#ifndef EREALLOC_CALLSITE
+       return ereallocz(optr, (size * nmemb), 0, FALSE);
+#else
+       return ereallocz(optr, (size * nmemb), 0, FALSE, file, line);
+#endif
+}
 
 char *
 estrdup_impl(
index bff84066f1c6466479c853052abe04bafabf8fca..bea6b519aeba6bf0cf0720269492f3a49d5589fd 100644 (file)
@@ -4220,7 +4220,7 @@ config_sim(
        serv_info = HEAD_PFIFO(sim_n->servers);
        for (; serv_info != NULL; serv_info = serv_info->link)
                simulation.num_of_servers++;
-       simulation.servers = emalloc(simulation.num_of_servers *
+       simulation.servers = eallocarray(simulation.num_of_servers,
                                     sizeof(simulation.servers[0]));
 
        i = 0;
@@ -4774,8 +4774,9 @@ gettokens_netinfo (
                                if (namelist.ni_namelist_len == 0) continue;
 
                                config->val_list =
-                                   emalloc(sizeof(char*) *
-                                   (namelist.ni_namelist_len + 1));
+                                   eallocarray(
+                                       (namelist.ni_namelist_len + 1),
+                                       sizeof(char*));
                                val_list = config->val_list;
 
                                for (index = 0;
index 6f5ee107e9e51ec9afa5f082ccb995ed8c0c8f34..45b2cdd00d3130d94e68cf87cbc412358a83baa6 100644 (file)
@@ -316,8 +316,8 @@ make_keylist(
         */
        tstamp = crypto_time();
        if (peer->keylist == NULL)
-               peer->keylist = emalloc(sizeof(keyid_t) *
-                   NTP_MAXSESSION);
+               peer->keylist = eallocarray(NTP_MAXSESSION,
+                                           sizeof(keyid_t));
 
        /*
         * Generate an initial key ID which is unique and greater than
index 1214e1d661c28b2bc8eb34f9d2e3c5f7b2d35239..02fd757307daef532e4f682ebbecdd603498e593 100644 (file)
@@ -183,7 +183,7 @@ mon_getmoremem(void)
                      : mru_incalloc;
 
        if (entries) {
-               chunk = emalloc(entries * sizeof(*chunk));
+               chunk = eallocarray(entries, sizeof(*chunk));
                mru_alloc += entries;
                for (chunk += entries; entries; entries--)
                        mon_free_entry(--chunk);
index c91e70302ff7278f168ce8072c7c5f279d3d4c77..354be89903bcd2c95f796a24a58fdd38574816fd 100644 (file)
@@ -3002,7 +3002,7 @@ mrulist(
                goto cleanup_return;
 
        /* construct an array of entry pointers in default order */
-       sorted = emalloc(mru_count * sizeof(*sorted));
+       sorted = eallocarray(mru_count, sizeof(*sorted));
        ppentry = sorted;
        if (MRUSORT_R_DEF != order) {
                ITER_DLIST_BEGIN(mru_list, recent, mlink, mru)
index 562163945f5784447c61aa352a01b308fad1d7af..c8df3bdca60e1e9deca23225f2297c74e44c9a5d 100644 (file)
@@ -35,7 +35,7 @@ search_entry(
                return 0;
        }
 
-       *dst = emalloc(resc * sizeof(**dst));
+       *dst = eallocarray(resc, sizeof(**dst));
 
        b = 0;
        for (a = 0; a < kod_db_cnt; a++)
@@ -246,7 +246,7 @@ kod_init_kod_db(
 
        rewind(db_s);
 
-       kod_db = emalloc(sizeof(kod_db[0]) * kod_db_cnt);
+       kod_db = eallocarray(kod_db_cnt, sizeof(kod_db[0]));
 
        /* Read contents of file */
        for (b = 0;