|
@@ -0,0 +1,276 @@
|
|
|
+Description: Catch *alloc failures
|
|
|
+Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de>
|
|
|
+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
|