Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Feb 2020 15:22:18 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r358388 - stable/12/lib/libdevstat
Message-ID:  <202002271522.01RFMIST083723@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Thu Feb 27 15:22:18 2020
New Revision: 358388
URL: https://svnweb.freebsd.org/changeset/base/358388

Log:
  MFC r355325: devstat_selectdevs: resize dev_select only after copying data
  
  The resizing could be a downsizing so some data would be lost and we
  could attempt to read past the end of the new memory allocation.
  
  Sponsored by:	Panzura

Modified:
  stable/12/lib/libdevstat/devstat.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/lib/libdevstat/devstat.c
==============================================================================
--- stable/12/lib/libdevstat/devstat.c	Thu Feb 27 15:21:05 2020	(r358387)
+++ stable/12/lib/libdevstat/devstat.c	Thu Feb 27 15:22:18 2020	(r358388)
@@ -584,10 +584,10 @@ devstat_selectdevs(struct device_selection **dev_selec
 	 * In this case, we have selected devices before, but the device
 	 * list has changed since we last selected devices, so we need to
 	 * either enlarge or reduce the size of the device selection list.
+	 * But delay the resizing until after copying the data to old_dev_select
+	 * as to not lose any data in the case of reducing the size.
 	 */
 	} else if (*num_selections != numdevs) {
-		*dev_select = (struct device_selection *)reallocf(*dev_select,
-			numdevs * sizeof(struct device_selection));
 		*select_generation = current_generation;
 		init_selections = 1;
 	/*
@@ -643,6 +643,11 @@ devstat_selectdevs(struct device_selection **dev_selec
 		old_num_selections = *num_selections;
 		bcopy(*dev_select, old_dev_select, 
 		    sizeof(struct device_selection) * *num_selections);
+	}
+
+	if (!changed && *num_selections != numdevs) {
+		*dev_select = (struct device_selection *)reallocf(*dev_select,
+			numdevs * sizeof(struct device_selection));
 	}
 
 	if (init_selections != 0) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002271522.01RFMIST083723>