From 96d84f8b8ada0c15d998835e7975874f8b475690 Mon Sep 17 00:00:00 2001 From: Bill Parker Date: Wed, 17 Jul 2013 09:45:46 -0700 Subject: [PATCH] Fix bug 10025 - Lack of Sanity Checking in calls to malloc()/calloc(). In reviewing various files in Samba-4.0.7, I found a number of instances where malloc()/calloc() were called without the checking the return value for a value of NULL, which would indicate failure. Reviewed-by: Jeremy Allison --- lib/ccan/htable/tools/speed.c | 4 ++++ lib/ccan/list/test/helper.c | 3 +++ lib/ccan/read_write_all/test/run-read_all.c | 4 ++++ lib/iniparser/src/dictionary.c | 16 ++++++++++++++++ lib/ntdb/tools/growtdb-bench.c | 16 ++++++++++++++++ lib/ntdb/tools/ntdbtorture.c | 4 ++++ lib/popt/popt.c | 9 +++++++++ lib/replace/getifaddrs.c | 29 +++++++++++++++++++++++++++++ lib/tdb/test/run-transaction-expand.c | 5 +++++ lib/tdb/tools/tdbtorture.c | 8 ++++++++ nsswitch/nsstest.c | 4 ++++ source4/heimdal/lib/hcrypto/dsa.c | 3 +++ source4/heimdal/lib/hcrypto/engine.c | 3 +++ source4/heimdal/lib/hdb/dbinfo.c | 29 +++++++++++++++++++++++++++-- source4/heimdal/lib/hx509/ks_mem.c | 5 +++++ source4/heimdal/lib/krb5/config_file.c | 6 +++++- source4/heimdal/lib/krb5/init_creds_pw.c | 5 +++++ source4/heimdal/lib/roken/resolve.c | 22 ++++++++++++++++++++++ source4/librpc/rpc/pyrpc_util.c | 3 +++ source4/torture/gentest.c | 8 ++++++++ 20 files changed, 183 insertions(+), 3 deletions(-) diff --git a/lib/ccan/htable/tools/speed.c b/lib/ccan/htable/tools/speed.c index 0b4e434..7b69ff3 100644 --- a/lib/ccan/htable/tools/speed.c +++ b/lib/ccan/htable/tools/speed.c @@ -145,6 +145,10 @@ int main(int argc, char *argv[]) } num = argv[1] ? atoi(argv[1]) : 1000000; objs = calloc(num, sizeof(objs[0])); + if (objs == NULL) { + printf("Unable to allocate memory for objs - exiting.\n"); + return -1; + } for (i = 0; i < num; i++) { objs[i].key = i; diff --git a/lib/ccan/list/test/helper.c b/lib/ccan/list/test/helper.c index f60eccc..922b871 100644 --- a/lib/ccan/list/test/helper.c +++ b/lib/ccan/list/test/helper.c @@ -19,6 +19,9 @@ static bool not_randomized = true; struct opaque *create_opaque_blob(void) { struct opaque *blob = calloc(1, sizeof(struct opaque)); + if (blob == NULL) { + return NULL; + } if (not_randomized) { srandom((int)time(NULL)); diff --git a/lib/ccan/read_write_all/test/run-read_all.c b/lib/ccan/read_write_all/test/run-read_all.c index 29f81fc..7cdbd7d 100644 --- a/lib/ccan/read_write_all/test/run-read_all.c +++ b/lib/ccan/read_write_all/test/run-read_all.c @@ -32,6 +32,10 @@ int main(int argc, char *argv[]) pid_t child; buffer = calloc(BUFSZ, 2); + if (buffer == NULL) { + printf("Unable to allocate memory for buffer.\n"); + exit(1); + } plan_tests(6); /* We fork and torture parent. */ diff --git a/lib/iniparser/src/dictionary.c b/lib/iniparser/src/dictionary.c index b9d426d..19762cc 100644 --- a/lib/iniparser/src/dictionary.c +++ b/lib/iniparser/src/dictionary.c @@ -53,6 +53,9 @@ static void * mem_double(void * ptr, int size) void * newptr ; newptr = calloc(2*size, 1); + if (newptr == NULL) { + return NULL; + } memcpy(newptr, ptr, size); free(ptr); return newptr ; @@ -119,8 +122,21 @@ dictionary * dictionary_new(int size) } d->size = size ; d->val = (char **)calloc(size, sizeof(char*)); + if (d->val == NULL) { + free(d); + return NULL; + } d->key = (char **)calloc(size, sizeof(char*)); + if (d->key == NULL) { + free(d->val); + free(d); + } d->hash = (unsigned int *)calloc(size, sizeof(unsigned)); + if (d->hash == NULL) { + free(d->key); + free(d->val); + free(d); + } return d ; } diff --git a/lib/ntdb/tools/growtdb-bench.c b/lib/ntdb/tools/growtdb-bench.c index 640f87a..aa5a406 100644 --- a/lib/ntdb/tools/growtdb-bench.c +++ b/lib/ntdb/tools/growtdb-bench.c @@ -48,12 +48,24 @@ int main(int argc, char *argv[]) idxkey.dsize = strlen("User index"); idxdata.dsize = 51; idxdata.dptr = calloc(idxdata.dsize, 1); + if (idxdata.dptr == NULL) { + fprintf(stderr, "Unable to allocate memory for idxdata.dptr\n"); + return -1; + } /* Create users. */ k.dsize = 48; k.dptr = calloc(k.dsize, 1); + if (k.dptr == NULL) { + fprintf(stderr, "Unable to allocate memory for k.dptr\n"); + return -1; + } d.dsize = 64; d.dptr = calloc(d.dsize, 1); + if (d.dptr == NULL) { + fprintf(stderr, "Unable to allocate memory for d.dptr\n"); + return -1; + } ntdb_transaction_start(ntdb); for (i = 0; i < users; i++) { @@ -79,6 +91,10 @@ int main(int argc, char *argv[]) * a group. */ gk.dsize = 48; gk.dptr = calloc(k.dsize, 1); + if (gk.dptr == NULL) { + fprintf(stderr, "Unable to allocate memory for gk.dptr\n"); + return -1; + } gk.dptr[gk.dsize-1] = 1; d.dsize = 32; diff --git a/lib/ntdb/tools/ntdbtorture.c b/lib/ntdb/tools/ntdbtorture.c index 3bcf320..7ddb5c3 100644 --- a/lib/ntdb/tools/ntdbtorture.c +++ b/lib/ntdb/tools/ntdbtorture.c @@ -96,6 +96,10 @@ static char *randbuf(int len) char *buf; int i; buf = (char *)malloc(len+1); + if (buf == NULL) { + perror("randbuf: unable to allocate memory for buffer.\n"); + exit(1); + } for (i=0;ileftovers = (const char **)calloc( (argc + 1), sizeof(*con->leftovers) ); + if (con->leftovers == NULL) { + free(con); + return NULL; + } /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ con->options = options; /*@=dependenttrans =assignexpose@*/ @@ -182,6 +186,11 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv, con->finalArgvAlloced = argc * 2; con->finalArgv = (const char **)calloc( con->finalArgvAlloced, sizeof(*con->finalArgv) ); + if (con->finalArgv == NULL) { + free(con->leftovers); + free(con); + return NULL; + } con->execAbsolute = 1; con->arg_strip = NULL; diff --git a/lib/replace/getifaddrs.c b/lib/replace/getifaddrs.c index 8da022f..f07d700 100644 --- a/lib/replace/getifaddrs.c +++ b/lib/replace/getifaddrs.c @@ -113,11 +113,23 @@ int rep_getifaddrs(struct ifaddrs **ifap) for (i=n-1; i>=0; i--) { if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { freeifaddrs(*ifap); + close(fd); return -1; } curif = calloc(1, sizeof(struct ifaddrs)); + if (curif == NULL) { + freeifaddrs(*ifap); + close(fd); + return -1; + } curif->ifa_name = strdup(ifr[i].ifr_name); + if (curif->ifa_name == NULL) { + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } curif->ifa_flags = ifr[i].ifr_flags; curif->ifa_dstaddr = NULL; curif->ifa_data = NULL; @@ -126,11 +138,28 @@ int rep_getifaddrs(struct ifaddrs **ifap) curif->ifa_addr = NULL; if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); + if (curif->ifa_addr == NULL) { + free(curif->ifa_name); + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } } curif->ifa_netmask = NULL; if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); + if (curif->ifa_netmask == NULL) { + if (curif->ifa_addr != NULL) { + free(curif->ifa_addr); + } + free(curif->ifa_name); + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } } if (lastif == NULL) { diff --git a/lib/tdb/test/run-transaction-expand.c b/lib/tdb/test/run-transaction-expand.c index 1271d92..d62c76a 100644 --- a/lib/tdb/test/run-transaction-expand.c +++ b/lib/tdb/test/run-transaction-expand.c @@ -73,6 +73,11 @@ int main(int argc, char *argv[]) data.dsize = 0; data.dptr = calloc(1000, getpagesize()); + if (data.dptr == NULL) { + diag("Unable to allocate memory for data.dptr"); + tdb_close(tdb); + exit(1); + } /* Simulate a slowly growing record. */ for (i = 0; i < 1000; i++) diff --git a/lib/tdb/tools/tdbtorture.c b/lib/tdb/tools/tdbtorture.c index a23d154..5ae08f6 100644 --- a/lib/tdb/tools/tdbtorture.c +++ b/lib/tdb/tools/tdbtorture.c @@ -342,7 +342,15 @@ int main(int argc, char * const *argv) } pids = (pid_t *)calloc(sizeof(pid_t), num_procs); + if (pids == NULL) { + perror("Unable to allocate memory for pids"); + exit(1); + } done = (int *)calloc(sizeof(int), num_procs); + if (done == NULL) { + perror("Unable to allocate memory for done"); + exit(1); + } if (pipe(pfds) != 0) { perror("Creating pipe"); diff --git a/nsswitch/nsstest.c b/nsswitch/nsstest.c index 39d0342..4b3d0a4 100644 --- a/nsswitch/nsstest.c +++ b/nsswitch/nsstest.c @@ -371,6 +371,10 @@ static void nss_test_initgroups(char *name, gid_t gid) NSS_STATUS status; groups = (gid_t *)malloc(sizeof(gid_t) * size); + if (groups == NULL) { + printf("Unable to allocate memory for groups\n"); + return; + } groups[0] = gid; status = nss_initgroups(name, gid, &groups, &start, &size); diff --git a/source4/heimdal/lib/hcrypto/dsa.c b/source4/heimdal/lib/hcrypto/dsa.c index a5bdbab..278ba1d 100644 --- a/source4/heimdal/lib/hcrypto/dsa.c +++ b/source4/heimdal/lib/hcrypto/dsa.c @@ -47,6 +47,9 @@ DSA * DSA_new(void) { DSA *dsa = calloc(1, sizeof(*dsa)); + if (dsa == NULL) { + return NULL; + } dsa->meth = rk_UNCONST(DSA_get_default_method()); dsa->references = 1; return dsa; diff --git a/source4/heimdal/lib/hcrypto/engine.c b/source4/heimdal/lib/hcrypto/engine.c index 3b22e56..a19232d 100644 --- a/source4/heimdal/lib/hcrypto/engine.c +++ b/source4/heimdal/lib/hcrypto/engine.c @@ -62,6 +62,9 @@ ENGINE_new(void) ENGINE *engine; engine = calloc(1, sizeof(*engine)); + if (engine == NULL) { + return NULL; + } engine->references = 1; return engine; diff --git a/source4/heimdal/lib/hdb/dbinfo.c b/source4/heimdal/lib/hdb/dbinfo.c index 52e3941..692e1b3 100644 --- a/source4/heimdal/lib/hdb/dbinfo.c +++ b/source4/heimdal/lib/hdb/dbinfo.c @@ -139,29 +139,54 @@ hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) if(databases == NULL) { /* if there are none specified, create one and use defaults */ di = calloc(1, sizeof(*di)); + if (di == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } databases = di; di->label = strdup("default"); + if (di->label == NULL) { + free(di); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } } for(di = databases; di; di = di->next) { if(di->dbname == NULL) { di->dbname = strdup(default_dbname); + if (di->dbname == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } if (di->mkey_file == NULL) di->mkey_file = strdup(default_mkey); + if (di->mkey_file == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } } if(di->mkey_file == NULL) { p = strrchr(di->dbname, '.'); if(p == NULL || strchr(p, '/') != NULL) /* final pathname component does not contain a . */ - asprintf(&di->mkey_file, "%s.mkey", di->dbname); + ret = asprintf(&di->mkey_file, "%s.mkey", di->dbname); else /* the filename is something.else, replace .else with .mkey */ - asprintf(&di->mkey_file, "%.*s.mkey", + ret = asprintf(&di->mkey_file, "%.*s.mkey", (int)(p - di->dbname), di->dbname); + if (ret == -1) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } } if(di->acl_file == NULL) di->acl_file = strdup(default_acl); + if (di->acl_file == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } } *dbp = databases; return 0; diff --git a/source4/heimdal/lib/hx509/ks_mem.c b/source4/heimdal/lib/hx509/ks_mem.c index 684acb0..eab59ca 100644 --- a/source4/heimdal/lib/hx509/ks_mem.c +++ b/source4/heimdal/lib/hx509/ks_mem.c @@ -163,6 +163,11 @@ mem_getkeys(hx509_context context, for (i = 0; mem->keys && mem->keys[i]; i++) ; *keys = calloc(i + 1, sizeof(**keys)); + if (*keys == NULL) { + hx509_set_error_string(context, 0, ENOMEM, "out of memory"); + return ENOMEM; + } + for (i = 0; mem->keys && mem->keys[i]; i++) { (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); if ((*keys)[i] == NULL) { diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index 4ac25ae..816e0e5 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -581,7 +581,11 @@ _krb5_config_copy(krb5_context context, while (c) { d = calloc(1, sizeof(*d)); - + if (d == NULL) { + krb5_abortx(context, + "Unable to allocate memory in krb5_config_copy"); + return ENOMEM; + } if (*head == NULL) *head = d; diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 6c87412..212a5be 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -1203,6 +1203,11 @@ process_pa_data_to_md(krb5_context context, unsigned flag; paid = calloc(1, sizeof(*paid)); + if (paid == NULL) { + krb5_set_error_message(context, + ENOMEM, N_("malloc: out of memory", "")); + return ENOMEM; + } paid->etype = KRB5_ENCTYPE_NULL; ppaid = process_pa_info(context, creds->client, a, paid, in_md); diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c index b27f37a..9ede886 100644 --- a/source4/heimdal/lib/roken/resolve.c +++ b/source4/heimdal/lib/roken/resolve.c @@ -723,8 +723,15 @@ parse_dns_record(PDNS_RECORD pRec) return NULL; rr = calloc(1, sizeof(*rr)); + if (rr == NULL) { + return NULL; + } rr->domain = strdup(pRec->pName); + if (rr->domain == NULL) { + dns_free_rr(rr); + return NULL; + } rr->type = pRec->wType; rr->class = 0; rr->ttl = pRec->dwTtl; @@ -781,12 +788,20 @@ parse_dns_record(PDNS_RECORD pRec) if (pRec->Data.TXT.dwStringCount == 0) { rr->u.txt = strdup(""); + if (rr->u.txt == NULL) { + dns_free_rr(rr); + return NULL; + } break; } len = strnlen(pRec->Data.TXT.pStringArray[0], DNS_MAX_TEXT_STRING_LENGTH); rr->u.txt = (char *)malloc(len + 1); + if (rr->u.txt == NULL) { + dns_free_rr(rr); + return NULL; + } strcpy_s(rr->u.txt, len + 1, pRec->Data.TXT.pStringArray[0]); break; @@ -900,7 +915,14 @@ rk_dns_lookup(const char *domain, const char *type_name) return NULL; r = calloc(1, sizeof(*r)); + if (r == NULL) { + return NULL; + } r->q.domain = strdup(domain); + if (r->q.domain == NULL) { + free(r); + return NULL; + } r->q.type = type; r->q.class = 0; diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index a000c76..ab6caac 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -246,6 +246,9 @@ bool PyInterface_AddNdrRpcMethods(PyTypeObject *ifacetype, const struct PyNdrRpc PyObject *ret; struct wrapperbase *wb = (struct wrapperbase *)calloc(sizeof(struct wrapperbase), 1); + if (wb == NULL) { + return false; + } wb->name = discard_const_p(char, mds[i].name); wb->flags = PyWrapperFlag_KEYWORDS; wb->wrapper = (wrapperfunc)py_dcerpc_call_wrapper; diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 91b60e2..f3c4c20 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -3068,9 +3068,17 @@ static bool start_gentest(struct tevent_context *ev, /* allocate the open_handles array */ open_handles = calloc(options.max_open_handles, sizeof(open_handles[0])); + if (open_handles == NULL) { + printf("Unable to allocate memory for open_handles array.\n"); + exit(1); + } srandom(options.seed); op_parms = calloc(options.numops, sizeof(op_parms[0])); + if (op_parms == NULL) { + printf("Unable to allocate memory for op_parms.\n"); + exit(1); + } /* generate the seeds - after this everything is deterministic */ if (options.use_preset_seeds) { -- 1.8.3