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)