From a801c6e613fde89c09c755a20003ab82fd6a5c47 Mon Sep 17 00:00:00 2001 From: Frank Morgner Date: Wed, 12 Apr 2017 16:08:53 +0200 Subject: [PATCH] simclist: handle faults during memory allocation fixes several situations that cause segmentation faults --- src/simclist.c | 111 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 30 deletions(-) diff --git a/src/simclist.c b/src/simclist.c index c8d36f5f..27927cd3 100644 --- a/src/simclist.c +++ b/src/simclist.c @@ -264,6 +264,8 @@ static inline long get_random(void) { int list_init(list_t *restrict l) { if (l == NULL) return -1; + memset(l, 0, sizeof *l); + seed_random(); l->numels = 0; @@ -271,6 +273,9 @@ int list_init(list_t *restrict l) { /* head/tail sentinels and mid pointer */ l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + if (NULL == l->tail_sentinel || NULL == l->head_sentinel) + return -1; + l->head_sentinel->next = l->tail_sentinel; l->tail_sentinel->prev = l->head_sentinel; l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL; @@ -284,12 +289,15 @@ int list_init(list_t *restrict l) { /* free-list attributes */ l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *)); l->spareelsnum = 0; + if (NULL == l->spareels) + return -1; #ifdef SIMCLIST_WITH_THREADS l->threadcount = 0; #endif - list_attributes_setdefaults(l); + if (list_attributes_setdefaults(l)) + return -1; assert(list_repOk(l)); assert(list_attrOk(l)); @@ -435,6 +443,9 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po float x; int i; + if (NULL == l->head_sentinel || NULL == l->tail_sentinel) + return NULL; + /* accept 1 slot overflow for fetching head and tail sentinels */ if (posstart < -1 || posstart > (int)l->numels) return NULL; @@ -463,6 +474,9 @@ void *list_extract_at(list_t *restrict l, unsigned int pos) { if (l->iter_active || pos >= l->numels) return NULL; tmp = list_findpos(l, pos); + if (NULL == tmp) + return NULL; + data = tmp->data; tmp->data = NULL; /* save data from list_drop_elem() free() */ @@ -493,6 +507,8 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) { /* make room for user' data (has to be copied) */ size_t datalen = l->attrs.meter(data); lent->data = (struct list_entry_s *)malloc(datalen); + if (NULL == lent->data) + return -1; memcpy(lent->data, data, datalen); } else { lent->data = (void*)data; @@ -500,6 +516,8 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) { /* actually append element */ prec = list_findpos(l, pos-1); + if (NULL == prec) + return -1; succ = prec->next; prec->next = lent; @@ -629,34 +647,36 @@ int list_clear(list_t *restrict l) { if (l->iter_active) return -1; - if (l->attrs.copy_data) { /* also free user data */ - /* spare a loop conditional with two loops: spareing elems and freeing elems */ - for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { - /* move elements as spares as long as there is room */ - if (s->data != NULL) free(s->data); - l->spareels[l->spareelsnum++] = s; - } - while (s != l->tail_sentinel) { - /* free the remaining elems */ - if (s->data != NULL) free(s->data); - s = s->next; - free(s->prev); - } - l->head_sentinel->next = l->tail_sentinel; - l->tail_sentinel->prev = l->head_sentinel; - } else { /* only free element containers */ - /* spare a loop conditional with two loops: spareing elems and freeing elems */ - for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { - /* move elements as spares as long as there is room */ - l->spareels[l->spareelsnum++] = s; - } - while (s != l->tail_sentinel) { - /* free the remaining elems */ - s = s->next; - free(s->prev); + if (l->head_sentinel && l->tail_sentinel) { + if (l->attrs.copy_data) { /* also free user data */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ + for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { + /* move elements as spares as long as there is room */ + if (s->data != NULL) free(s->data); + l->spareels[l->spareelsnum++] = s; + } + while (s != l->tail_sentinel) { + /* free the remaining elems */ + if (s->data != NULL) free(s->data); + s = s->next; + free(s->prev); + } + l->head_sentinel->next = l->tail_sentinel; + l->tail_sentinel->prev = l->head_sentinel; + } else { /* only free element containers */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ + for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { + /* move elements as spares as long as there is room */ + l->spareels[l->spareelsnum++] = s; + } + while (s != l->tail_sentinel) { + /* free the remaining elems */ + s = s->next; + free(s->prev); + } + l->head_sentinel->next = l->tail_sentinel; + l->tail_sentinel->prev = l->head_sentinel; } - l->head_sentinel->next = l->tail_sentinel; - l->tail_sentinel->prev = l->head_sentinel; } l->numels = 0; l->mid = NULL; @@ -678,6 +698,9 @@ int list_locate(const list_t *restrict l, const void *data) { struct list_entry_s *el; int pos = 0; + if (NULL == l->head_sentinel || NULL == l->tail_sentinel) + return -1; + if (l->attrs.comparator != NULL) { /* use comparator */ for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { @@ -699,6 +722,9 @@ void *list_seek(list_t *restrict l, const void *indicator) { if (l->attrs.seeker == NULL) return NULL; + if (NULL == l->head_sentinel || NULL == l->tail_sentinel) + return NULL; + for (iter = l->head_sentinel->next; iter != l->tail_sentinel; iter = iter->next) { if (l->attrs.seeker(iter->data, indicator) != 0) return iter->data; } @@ -719,7 +745,12 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { if (l1 == NULL || l2 == NULL || dest == NULL || l1 == dest || l2 == dest) return -1; - list_init(dest); + if (NULL == l1->head_sentinel || NULL == l1->tail_sentinel + || NULL == l2->head_sentinel || NULL == l2->tail_sentinel) + return -1; + + if (list_init(dest)) + return -1; dest->numels = l1->numels + l2->numels; if (dest->numels == 0) @@ -730,6 +761,8 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { el = dest->head_sentinel; while (srcel != l1->tail_sentinel) { el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + if (NULL == el->next) + return -1; el->next->prev = el; el = el->next; el->data = srcel->data; @@ -740,6 +773,8 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { srcel = l2->head_sentinel->next; while (srcel != l2->tail_sentinel) { el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + if (NULL == el->next) + return -1; el->next->prev = el; el = el->next; el->data = srcel->data; @@ -769,6 +804,10 @@ int list_sort(list_t *restrict l, int versus) { if (l->numels <= 1) return 0; + + if (NULL == l->head_sentinel || NULL == l->tail_sentinel) + return -1; + list_sort_quicksort(l, versus, 0, l->head_sentinel->next, l->numels-1, l->tail_sentinel->prev); assert(list_repOk(l)); return 0; @@ -907,6 +946,8 @@ static void list_sort_quicksort(list_t *restrict l, int versus, /* prepare wrapped args, then start thread */ if (l->threadcount < SIMCLIST_MAXTHREADS-1) { struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams)); + if (NULL == wp) + return -1; l->threadcount++; traised = 1; wp->l = l; @@ -937,6 +978,8 @@ static void list_sort_quicksort(list_t *restrict l, int versus, int list_iterator_start(list_t *restrict l) { if (l->iter_active) return 0; + if (NULL == l->head_sentinel) + return -1; l->iter_pos = 0; l->iter_active = 1; l->iter_curentry = l->head_sentinel->next; @@ -1281,6 +1324,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len if (l->attrs.unserializer != NULL) { /* use unserializer */ buf = malloc(header.elemlen); + if (NULL == buf) + return -1; for (cnt = 0; cnt < header.numels; cnt++) { READ_ERRCHECK(fd, buf, header.elemlen); list_append(l, l->attrs.unserializer(buf, & elsize)); @@ -1290,6 +1335,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len /* copy verbatim into memory */ for (cnt = 0; cnt < header.numels; cnt++) { buf = malloc(header.elemlen); + if (NULL == buf) + return -1; READ_ERRCHECK(fd, buf, header.elemlen); list_append(l, buf); } @@ -1303,6 +1350,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len for (cnt = 0; cnt < header.numels; cnt++) { READ_ERRCHECK(fd, & elsize, sizeof(elsize)); buf = malloc((size_t)elsize); + if (NULL == buf) + return -1; READ_ERRCHECK(fd, buf, elsize); totreadlen += elsize; list_append(l, l->attrs.unserializer(buf, & elsize)); @@ -1313,6 +1362,8 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len for (cnt = 0; cnt < header.numels; cnt++) { READ_ERRCHECK(fd, & elsize, sizeof(elsize)); buf = malloc(elsize); + if (NULL == buf) + return -1; READ_ERRCHECK(fd, buf, elsize); totreadlen += elsize; list_append(l, buf); @@ -1404,7 +1455,7 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned if (l->attrs.copy_data && tmp->data != NULL) free(tmp->data); - if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { + if (l->spareels != NULL && l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { l->spareels[l->spareelsnum++] = tmp; } else { free(tmp);