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


   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  28  * Copyright 2015 Toomas Soome <tsoome@me.com>

  29  */
  30 
  31 #include <assert.h>
  32 #include <libintl.h>
  33 #include <libnvpair.h>
  34 #include <libzfs.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <string.h>
  38 #include <strings.h>
  39 #include <sys/types.h>
  40 #include <sys/stat.h>
  41 #include <unistd.h>
  42 #include <errno.h>
  43 
  44 #include <libbe.h>
  45 #include <libbe_priv.h>
  46 
  47 /*
  48  * Callback data used for zfs_iter calls.


 680 
 681 /*
 682  * Function:    be_sort_list
 683  * Description: Sort BE node list
 684  * Parameters:
 685  *              pointer to address of list head
 686  *              compare function
 687  * Returns:
 688  *              nothing
 689  * Side effect:
 690  *              node list sorted by name
 691  * Scope:
 692  *              Private
 693  */
 694 static void
 695 be_sort_list(be_node_list_t **pstart, int (*compar)(const void *, const void *))
 696 {
 697         size_t ibe, nbe;
 698         be_node_list_t *p = NULL;
 699         be_node_list_t **ptrlist = NULL;

 700 
 701         if (pstart == NULL)
 702                 return;
 703         /* build array of linked list BE struct pointers */
 704         for (p = *pstart, nbe = 0; p != NULL; nbe++, p = p->be_next_node) {
 705                 ptrlist = realloc(ptrlist,
 706                     sizeof (be_node_list_t *) * (nbe + 2));






 707                 ptrlist[nbe] = p;
 708         }
 709         if (nbe == 0)
 710                 return;
 711         /* in-place list quicksort using qsort(3C) */
 712         if (nbe > 1) /* no sort if less than 2 BEs */
 713                 qsort(ptrlist, nbe, sizeof (be_node_list_t *), compar);
 714 
 715         ptrlist[nbe] = NULL; /* add linked list terminator */
 716         *pstart = ptrlist[0]; /* set new linked list header */
 717         /* for each BE in list */
 718         for (ibe = 0; ibe < nbe; ibe++) {
 719                 size_t k, ns;   /* subordinate index, count */
 720 
 721                 /* rewrite list pointer chain, including terminator */
 722                 ptrlist[ibe]->be_next_node = ptrlist[ibe + 1];
 723                 /* sort subordinate snapshots */
 724                 if (ptrlist[ibe]->be_node_num_snapshots > 1) {
 725                         const size_t nmax = ptrlist[ibe]->be_node_num_snapshots;
 726                         be_snapshot_list_t ** const slist =




   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  28  * Copyright 2015 Toomas Soome <tsoome@me.com>
  29  * Copyright 2015 Gary Mills
  30  */
  31 
  32 #include <assert.h>
  33 #include <libintl.h>
  34 #include <libnvpair.h>
  35 #include <libzfs.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <string.h>
  39 #include <strings.h>
  40 #include <sys/types.h>
  41 #include <sys/stat.h>
  42 #include <unistd.h>
  43 #include <errno.h>
  44 
  45 #include <libbe.h>
  46 #include <libbe_priv.h>
  47 
  48 /*
  49  * Callback data used for zfs_iter calls.


 681 
 682 /*
 683  * Function:    be_sort_list
 684  * Description: Sort BE node list
 685  * Parameters:
 686  *              pointer to address of list head
 687  *              compare function
 688  * Returns:
 689  *              nothing
 690  * Side effect:
 691  *              node list sorted by name
 692  * Scope:
 693  *              Private
 694  */
 695 static void
 696 be_sort_list(be_node_list_t **pstart, int (*compar)(const void *, const void *))
 697 {
 698         size_t ibe, nbe;
 699         be_node_list_t *p = NULL;
 700         be_node_list_t **ptrlist = NULL;
 701         be_node_list_t **ptrtmp;
 702 
 703         if (pstart == NULL)
 704                 return;
 705         /* build array of linked list BE struct pointers */
 706         for (p = *pstart, nbe = 0; p != NULL; nbe++, p = p->be_next_node) {
 707                 ptrtmp = realloc(ptrlist,
 708                     sizeof (be_node_list_t *) * (nbe + 2));
 709                 if (ptrtmp == NULL) { /* out of memory */
 710                         be_print_err(gettext("be_sort_list: memory "
 711                             "allocation failed\n"));
 712                         goto free;
 713                 }
 714                 ptrlist = ptrtmp;
 715                 ptrlist[nbe] = p;
 716         }
 717         if (nbe == 0)
 718                 return;
 719         /* in-place list quicksort using qsort(3C) */
 720         if (nbe > 1) /* no sort if less than 2 BEs */
 721                 qsort(ptrlist, nbe, sizeof (be_node_list_t *), compar);
 722 
 723         ptrlist[nbe] = NULL; /* add linked list terminator */
 724         *pstart = ptrlist[0]; /* set new linked list header */
 725         /* for each BE in list */
 726         for (ibe = 0; ibe < nbe; ibe++) {
 727                 size_t k, ns;   /* subordinate index, count */
 728 
 729                 /* rewrite list pointer chain, including terminator */
 730                 ptrlist[ibe]->be_next_node = ptrlist[ibe + 1];
 731                 /* sort subordinate snapshots */
 732                 if (ptrlist[ibe]->be_node_num_snapshots > 1) {
 733                         const size_t nmax = ptrlist[ibe]->be_node_num_snapshots;
 734                         be_snapshot_list_t ** const slist =