Description: Catch *alloc failures Author: Christoph Biedl Bug: https://bitbucket.org/ripencc/bgpdump/issues/28/ Last-Update: 2016-07-13 Better exit(1) than doing null pointer accesses --- a/bgpdump_lib.c +++ b/bgpdump_lib.c @@ -94,7 +94,7 @@ return NULL; } - BGPDUMP *this_dump = malloc(sizeof(BGPDUMP)); + BGPDUMP *this_dump = malloc_check(sizeof(BGPDUMP)); strcpy(this_dump->filename, "[STDIN]"); if(filename && strcmp(filename, "-")) { if (strlen(filename) >= BGPDUMP_MAX_FILE_LEN - 1) { @@ -137,7 +137,7 @@ int ok=0; u_int32_t bytes_read; - this_entry = malloc(sizeof(BGPDUMP_ENTRY)); + this_entry = malloc_check(sizeof(BGPDUMP_ENTRY)); bytes_read = cfr_read_n(dump->f, &(this_entry->time), 4); bytes_read += cfr_read_n(dump->f, &(this_entry->type), 2); @@ -182,7 +182,7 @@ dump->parsed++; this_entry->attr=NULL; - buffer = malloc(this_entry->length); + buffer = malloc_check(this_entry->length); bytes_read = cfr_read_n(dump->f, buffer, this_entry->length); if(bytes_read != this_entry->length) { err("bgpdump_read_next: incomplete dump record (%d bytes read, expecting %d)", @@ -456,7 +456,7 @@ free(table_dump_v2_peer_index_table); } - table_dump_v2_peer_index_table = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE)); + table_dump_v2_peer_index_table = malloc_check(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE)); t = table_dump_v2_peer_index_table; t->entries = NULL; @@ -793,7 +793,7 @@ entry->body.zebra_message.notify_len = entry->body.zebra_message.size - 21; if(entry->body.zebra_message.notify_len > 0) { - entry->body.zebra_message.notify_data = malloc(entry->body.zebra_message.notify_len); + entry->body.zebra_message.notify_data = malloc_check(entry->body.zebra_message.notify_len); mstream_get(s, entry->body.zebra_message.notify_data, entry->body.zebra_message.notify_len); } @@ -808,7 +808,7 @@ mstream_getc(s, &entry->body.zebra_message.opt_len); if(entry->body.zebra_message.opt_len) { - entry->body.zebra_message.opt_data = malloc(entry->body.zebra_message.opt_len); + entry->body.zebra_message.opt_data = malloc_check(entry->body.zebra_message.opt_len); mstream_get(s, entry->body.zebra_message.opt_data, entry->body.zebra_message.opt_len); } @@ -844,9 +844,9 @@ static attributes_t *attr_init(struct mstream *s, int len) { - attributes_t *attr = malloc(sizeof(struct attr)); + attributes_t *attr = malloc_check(sizeof(struct attr)); - attr->data=malloc(len); + attr->data=malloc_check(len); memcpy(attr->data, &s->start[s->position], len); attr->len = len; @@ -865,7 +865,7 @@ attr->aspath = NULL; attr->community = NULL; attr->transit = NULL; - attr->mp_info = calloc(1, sizeof(struct mp_info));; + attr->mp_info = calloc_check(1, sizeof(struct mp_info));; attr->unknown_num = 0; attr->unknown = NULL; @@ -881,14 +881,14 @@ static void process_unknown_attr(struct mstream *s, attributes_t *attr, int flag, int type, int len) { /* Unknown attribute. Save as is */ attr->unknown_num++; - attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr)); + attr->unknown = realloc_check(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr)); /* Pointer to the unknown attribute we want to fill in */ struct unknown_attr unknown = { .flag = flag, .type = type, .len = len, - .raw = malloc(len) + .raw = malloc_check(len) }; attr->unknown[attr->unknown_num - 1] = unknown; @@ -956,9 +956,9 @@ break; case BGP_ATTR_COMMUNITIES: assert(! attr->community); - attr->community = malloc(sizeof(struct community)); + attr->community = malloc_check(sizeof(struct community)); attr->community->size = len / 4; - attr->community->val = malloc(len); + attr->community->val = malloc_check(len); mstream_get(s,attr->community->val,len); attr->community->str = NULL; process_attr_community_string(attr->community); @@ -982,9 +982,9 @@ break; case BGP_ATTR_CLUSTER_LIST: assert(! attr->cluster); - attr->cluster = malloc(sizeof(struct cluster_list)); + attr->cluster = malloc_check(sizeof(struct cluster_list)); attr->cluster->length = len/4; - attr->cluster->list = malloc((attr->cluster->length) * sizeof(struct in_addr)); + attr->cluster->list = malloc_check((attr->cluster->length) * sizeof(struct in_addr)); int i; // cluster index for (i = 0; i < attr->cluster->length; i++) @@ -1014,14 +1014,14 @@ } struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len) { - struct aspath *aspath = malloc(sizeof(struct aspath)); + struct aspath *aspath = malloc_check(sizeof(struct aspath)); if(aspath) { aspath->asn_len = asn_len; aspath->length = len; aspath->count = 0; aspath->str = NULL; if(len > 0) - aspath->data = malloc(len); + aspath->data = malloc_check(len); else aspath->data = NULL; } @@ -1036,13 +1036,13 @@ as->str = NULL; } - as->str = malloc(strlen(ASPATH_STR_ERROR) + 1); + as->str = malloc_check(strlen(ASPATH_STR_ERROR) + 1); strcpy(as->str, ASPATH_STR_ERROR); } void process_attr_aspath_string(struct aspath *as) { const int MAX_ASPATH_LEN = 8000; - as->str = malloc(MAX_ASPATH_LEN); + as->str = malloc_check(MAX_ASPATH_LEN); /* Set default values */ int space = 0; @@ -1210,12 +1210,12 @@ } } - com->str = malloc(strlen(buf)+1); + com->str = malloc_check(strlen(buf)+1); strcpy(com->str, buf); } static struct mp_nlri *get_nexthop(struct mstream *s, u_int16_t afi) { - struct mp_nlri *nlri = calloc(1, sizeof(struct mp_nlri)); + struct mp_nlri *nlri = calloc_check(1, sizeof(struct mp_nlri)); nlri->nexthop_len = mstream_getc(s, NULL); @@ -1300,7 +1300,7 @@ } /* Allocate structure */ - mp_nlri = malloc(sizeof(struct mp_nlri)); + mp_nlri = malloc_check(sizeof(struct mp_nlri)); memset(mp_nlri, 0, sizeof(struct mp_nlri)); info->withdraw[afi][safi] = mp_nlri; @@ -1439,7 +1439,7 @@ while(mergedpath->count < path->count - newpath->count) { /* Make room */ newlen = mergedpath->length + sizeof(struct assegment) + segment->length * ASN32_LEN; - mergedpath->data = realloc(mergedpath->data, newlen); + mergedpath->data = realloc_check(mergedpath->data, newlen); /* Create a new AS-path segment */ mergedsegment = (struct assegment *) (mergedpath->data + mergedpath->length); @@ -1464,7 +1464,7 @@ } /* Append NEW_AS_PATH to merged path */ - mergedpath->data = realloc(mergedpath->data, mergedpath->length + newpath->length); + mergedpath->data = realloc_check(mergedpath->data, mergedpath->length + newpath->length); memcpy(mergedpath->data + mergedpath->length, newpath->data, newpath->length); mergedpath->length += newpath->length; --- a/cfile_tools.c +++ b/cfile_tools.c @@ -73,7 +73,7 @@ format = 2; // skip specials 0, 1 // Do action dependent on file format - retval = (CFRFILE *) calloc(1,sizeof(CFRFILE)); + retval = (CFRFILE *) calloc_check(1,sizeof(CFRFILE)); retval->eof = 0; retval->error1 = 0; retval->error2 = 0; @@ -357,12 +357,12 @@ // allocate initial buffer if none was passed or size was zero if (*lineptr == NULL) { - *lineptr = (char *) calloc(120, 1); + *lineptr = (char *) calloc_check(120, 1); *n = 120; } if (*n == 0) { *n = 120; - *lineptr = (char *) realloc(*lineptr, *n); // to avoid memory-leaks + *lineptr = (char *) realloc_check(*lineptr, *n); // to avoid memory-leaks } count = 0; @@ -375,7 +375,7 @@ count ++; if (count >= *n) { *n = 2 * *n; - *lineptr = (char *) realloc(*lineptr, *n); + *lineptr = (char *) realloc_check(*lineptr, *n); if (*lineptr == NULL) { stream->error1 = errno; return(-1); @@ -551,3 +551,29 @@ } #endif +void *malloc_check(size_t __size) { + void *ptr = malloc(__size); + if(ptr==NULL) { + fputs ("Out of memory!", stderr); + exit(1); + } + return ptr; +} + +void *calloc_check(size_t __nmemb, size_t __size) { + void *ptr = calloc(__nmemb, __size); + if(ptr==NULL) { + fputs ("Out of memory!", stderr); + exit(1); + } + return ptr; +} + +void *realloc_check(void *__ptr, size_t __size) { + void *ptr = realloc(__ptr, __size); + if(ptr==NULL) { + fputs ("Out of memory!", stderr); + exit(1); + } + return ptr; +} --- a/cfile_tools.h +++ b/cfile_tools.h @@ -89,5 +89,8 @@ const char * _bz2_strerror(int err); #endif +void *malloc_check(size_t size); +void *calloc_check(size_t __nmemb, size_t __size); +void *realloc_check(void *__ptr, size_t __size); #endif