Print this page
5679 be_sort_list(): Possible null pointer dereference

*** 24,33 **** --- 24,34 ---- */ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright 2015 Toomas Soome <tsoome@me.com> + * Copyright 2015 Gary Mills */ #include <assert.h> #include <libintl.h> #include <libnvpair.h>
*** 65,75 **** static int be_get_zone_node_data(be_node_list_t *, char *); static int be_get_ds_data(zfs_handle_t *, char *, be_dataset_list_t *, be_node_list_t *); static int be_get_ss_data(zfs_handle_t *, char *, be_snapshot_list_t *, be_node_list_t *); ! static void be_sort_list(be_node_list_t **, int (*)(const void *, const void *)); static int be_qsort_compare_BEs_name(const void *, const void *); static int be_qsort_compare_BEs_name_rev(const void *, const void *); static int be_qsort_compare_BEs_date(const void *, const void *); static int be_qsort_compare_BEs_date_rev(const void *, const void *); --- 66,76 ---- static int be_get_zone_node_data(be_node_list_t *, char *); static int be_get_ds_data(zfs_handle_t *, char *, be_dataset_list_t *, be_node_list_t *); static int be_get_ss_data(zfs_handle_t *, char *, be_snapshot_list_t *, be_node_list_t *); ! static int be_sort_list(be_node_list_t **, int (*)(const void *, const void *)); static int be_qsort_compare_BEs_name(const void *, const void *); static int be_qsort_compare_BEs_name_rev(const void *, const void *); static int be_qsort_compare_BEs_date(const void *, const void *); static int be_qsort_compare_BEs_date_rev(const void *, const void *);
*** 141,164 **** * Function: be_sort * Description: Sort BE node list * Parameters: * pointer to address of list head * sort order type ! * Returns: ! * nothing * Side effect: * node list sorted by name * Scope: * Public */ ! void be_sort(be_node_list_t **be_nodes, int order) { int (*compar)(const void *, const void *) = be_qsort_compare_BEs_date; if (be_nodes == NULL) ! return; switch (order) { case BE_SORT_UNSPECIFIED: case BE_SORT_DATE: compar = be_qsort_compare_BEs_date; --- 142,166 ---- * Function: be_sort * Description: Sort BE node list * Parameters: * pointer to address of list head * sort order type ! * Return: ! * BE_SUCCESS - Success ! * be_errno_t - Failure * Side effect: * node list sorted by name * Scope: * Public */ ! int be_sort(be_node_list_t **be_nodes, int order) { int (*compar)(const void *, const void *) = be_qsort_compare_BEs_date; if (be_nodes == NULL) ! return (BE_ERR_INVAL); switch (order) { case BE_SORT_UNSPECIFIED: case BE_SORT_DATE: compar = be_qsort_compare_BEs_date;
*** 179,192 **** compar = be_qsort_compare_BEs_space_rev; break; default: be_print_err(gettext("be_sort: invalid sort order %d\n"), order); ! return; } ! be_sort_list(be_nodes, compar); } /* ******************************************************************** */ /* Semi-Private Functions */ /* ******************************************************************** */ --- 181,194 ---- compar = be_qsort_compare_BEs_space_rev; break; default: be_print_err(gettext("be_sort: invalid sort order %d\n"), order); ! return (BE_ERR_INVAL); } ! return (be_sort_list(be_nodes, compar)); } /* ******************************************************************** */ /* Semi-Private Functions */ /* ******************************************************************** */
*** 212,221 **** --- 214,224 ---- _be_list(char *be_name, be_node_list_t **be_nodes) { list_callback_data_t cb = { 0 }; be_transaction_data_t bt = { 0 }; int ret = BE_SUCCESS; + int sret; zpool_handle_t *zphp; char *rpool = NULL; struct be_defaults be_defaults; if (be_nodes == NULL)
*** 275,287 **** *be_nodes = cb.be_nodes_head; free(cb.be_name); ! be_sort(be_nodes, BE_SORT_DATE); ! return (ret); } /* * Function: be_free_list * Description: Frees up all the data allocated for the list of BEs, --- 278,290 ---- *be_nodes = cb.be_nodes_head; free(cb.be_name); ! sret = be_sort(be_nodes, BE_SORT_DATE); ! return ((ret == BE_SUCCESS) ? sret : ret); } /* * Function: be_free_list * Description: Frees up all the data allocated for the list of BEs,
*** 682,715 **** * Function: be_sort_list * Description: Sort BE node list * Parameters: * pointer to address of list head * compare function ! * Returns: ! * nothing * Side effect: * node list sorted by name * Scope: * Private */ ! static void be_sort_list(be_node_list_t **pstart, int (*compar)(const void *, const void *)) { size_t ibe, nbe; be_node_list_t *p = NULL; be_node_list_t **ptrlist = NULL; ! if (pstart == NULL) ! return; /* build array of linked list BE struct pointers */ for (p = *pstart, nbe = 0; p != NULL; nbe++, p = p->be_next_node) { ! ptrlist = realloc(ptrlist, sizeof (be_node_list_t *) * (nbe + 2)); ptrlist[nbe] = p; } ! if (nbe == 0) ! return; /* in-place list quicksort using qsort(3C) */ if (nbe > 1) /* no sort if less than 2 BEs */ qsort(ptrlist, nbe, sizeof (be_node_list_t *), compar); ptrlist[nbe] = NULL; /* add linked list terminator */ --- 685,728 ---- * Function: be_sort_list * Description: Sort BE node list * Parameters: * pointer to address of list head * compare function ! * Return: ! * BE_SUCCESS - Success ! * be_errno_t - Failure * Side effect: * node list sorted by name * Scope: * Private */ ! static int be_sort_list(be_node_list_t **pstart, int (*compar)(const void *, const void *)) { + int ret = BE_SUCCESS; size_t ibe, nbe; be_node_list_t *p = NULL; be_node_list_t **ptrlist = NULL; + be_node_list_t **ptrtmp; ! if (pstart == NULL) /* Nothing to sort */ ! return (BE_SUCCESS); /* build array of linked list BE struct pointers */ for (p = *pstart, nbe = 0; p != NULL; nbe++, p = p->be_next_node) { ! ptrtmp = realloc(ptrlist, sizeof (be_node_list_t *) * (nbe + 2)); + if (ptrtmp == NULL) { /* out of memory */ + be_print_err(gettext("be_sort_list: memory " + "allocation failed\n")); + ret = BE_ERR_NOMEM; + goto free; + } + ptrlist = ptrtmp; ptrlist[nbe] = p; } ! if (nbe == 0) /* Nothing to sort */ ! return (BE_SUCCESS); /* in-place list quicksort using qsort(3C) */ if (nbe > 1) /* no sort if less than 2 BEs */ qsort(ptrlist, nbe, sizeof (be_node_list_t *), compar); ptrlist[nbe] = NULL; /* add linked list terminator */
*** 725,736 **** const size_t nmax = ptrlist[ibe]->be_node_num_snapshots; be_snapshot_list_t ** const slist = malloc(sizeof (be_snapshot_list_t *) * (nmax + 1)); be_snapshot_list_t *p; ! if (slist == NULL) continue; /* build array of linked list snapshot struct ptrs */ for (ns = 0, p = ptrlist[ibe]->be_node_snapshots; ns < nmax && p != NULL; ns++, p = p->be_next_snapshot) { slist[ns] = p; --- 738,751 ---- const size_t nmax = ptrlist[ibe]->be_node_num_snapshots; be_snapshot_list_t ** const slist = malloc(sizeof (be_snapshot_list_t *) * (nmax + 1)); be_snapshot_list_t *p; ! if (slist == NULL) { ! ret = BE_ERR_NOMEM; continue; + } /* build array of linked list snapshot struct ptrs */ for (ns = 0, p = ptrlist[ibe]->be_node_snapshots; ns < nmax && p != NULL; ns++, p = p->be_next_snapshot) { slist[ns] = p;
*** 753,764 **** const size_t nmax = ptrlist[ibe]->be_node_num_datasets; be_dataset_list_t ** const slist = malloc(sizeof (be_dataset_list_t *) * (nmax + 1)); be_dataset_list_t *p; ! if (slist == NULL) continue; /* build array of linked list dataset struct ptrs */ for (ns = 0, p = ptrlist[ibe]->be_node_datasets; ns < nmax && p != NULL; ns++, p = p->be_next_dataset) { slist[ns] = p; --- 768,781 ---- const size_t nmax = ptrlist[ibe]->be_node_num_datasets; be_dataset_list_t ** const slist = malloc(sizeof (be_dataset_list_t *) * (nmax + 1)); be_dataset_list_t *p; ! if (slist == NULL) { ! ret = BE_ERR_NOMEM; continue; + } /* build array of linked list dataset struct ptrs */ for (ns = 0, p = ptrlist[ibe]->be_node_datasets; ns < nmax && p != NULL; ns++, p = p->be_next_dataset) { slist[ns] = p;
*** 777,786 **** --- 794,804 ---- free(slist); } } free: free(ptrlist); + return (ret); } /* * Function: be_qsort_compare_BEs_date * Description: compare BE creation times for qsort(3C)