From: Juergen Perlinger Date: Tue, 9 Jun 2015 21:58:56 +0000 (+0200) Subject: [Bug 2845] Harden memory allocation in ntpd X-Git-Tag: NTP_4_3_40~2^2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57c4684598cabc509cc60acd13a7de075ed590ed;p=thirdparty%2Fntp.git [Bug 2845] Harden memory allocation in ntpd implement and use 'eallocarray(...)' where appropriate bk: 557761a0USeVPFgg6Fs6jOyVeUmzvA --- diff --git a/ChangeLog b/ChangeLog index 97d1605aa..eb8a2e8be 100644 --- 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. diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index 38180f0d7..bad2697d0 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -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 diff --git a/libntp/emalloc.c b/libntp/emalloc.c index 6c1c6787e..95d293f1c 100644 --- a/libntp/emalloc.c +++ b/libntp/emalloc.c @@ -60,6 +60,59 @@ ereallocz( return mem; } +/* oreallocarray.c is licensed under the following: + * 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 + +/* + * 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( diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index bff84066f..bea6b519a 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -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; diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index 6f5ee107e..45b2cdd00 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -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 diff --git a/ntpd/ntp_monitor.c b/ntpd/ntp_monitor.c index 1214e1d66..02fd75730 100644 --- a/ntpd/ntp_monitor.c +++ b/ntpd/ntp_monitor.c @@ -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); diff --git a/ntpq/ntpq-subs.c b/ntpq/ntpq-subs.c index c91e70302..354be8990 100644 --- a/ntpq/ntpq-subs.c +++ b/ntpq/ntpq-subs.c @@ -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) diff --git a/sntp/kod_management.c b/sntp/kod_management.c index 562163945..c8df3bdca 100644 --- a/sntp/kod_management.c +++ b/sntp/kod_management.c @@ -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;