From dan@kulesh.obluda.cz  Tue Jul 12 22:59:48 2005
Return-Path: <dan@kulesh.obluda.cz>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id A2E1C16A41C
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 12 Jul 2005 22:59:48 +0000 (GMT)
	(envelope-from dan@kulesh.obluda.cz)
Received: from kulesh.obluda.cz (kulesh.obluda.cz [193.179.22.243])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 7799043D48
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 12 Jul 2005 22:59:47 +0000 (GMT)
	(envelope-from dan@kulesh.obluda.cz)
Received: from kulesh.obluda.cz (localhost.eunet.cz [127.0.0.1])
	by kulesh.obluda.cz (8.13.3/8.13.3) with ESMTP id j6CMxjrf018195
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 13 Jul 2005 00:59:45 +0200 (CEST)
	(envelope-from dan@kulesh.obluda.cz)
Received: (from root@localhost)
	by kulesh.obluda.cz (8.13.3/8.13.1/Submit) id j6CMxjZL018194;
	Wed, 13 Jul 2005 00:59:45 +0200 (CEST)
	(envelope-from dan)
Message-Id: <200507122259.j6CMxjZL018194@kulesh.obluda.cz>
Date: Wed, 13 Jul 2005 00:59:45 +0200 (CEST)
From: Dan Lukes <dan@obluda.cz>
Reply-To: Dan Lukes <dan@obluda.cz>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [ PATCH ] improper handling of malloc failures within libdevstat code
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         83359
>Category:       bin
>Synopsis:       [patch] improper handling of malloc failures within libdevstat code
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 12 23:00:26 GMT 2005
>Closed-Date:    Fri Jan 06 15:30:36 CST 2012
>Last-Modified:  Fri Jan 06 15:30:36 CST 2012
>Originator:     Dan Lukes
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
Obludarium
>Environment:
System: FreeBSD 5.4-STABLE #8: Sat Jul 9 16:31:08 CEST 2005 i386
lib/libdevstat/devstat.c,v 1.26 2004/06/25 01:16:02 kan

>Description:
	Improper handling of malloc failures within libdevstat code can
cause NULL deference.

>How-To-Repeat:
>Fix:


	WARNS level within lib/libdevstat/Makefile can be raised to '3'



--- patch begins here ---
--- lib/libdevstat/devstat.c.ORIG	Sun Aug  8 21:03:38 2004
+++ lib/libdevstat/devstat.c	Wed Jul 13 00:51:25 2005
@@ -370,6 +370,12 @@
 			dssize = (dinfo->numdevs * sizeof(struct devstat)) +
 				 sizeof(long);
 			dinfo->mem_ptr = (u_int8_t *)malloc(dssize);
+			if (dinfo->mem_ptr == NULL) {
+				snprintf(devstat_errbuf, sizeof(devstat_errbuf),
+					 "%s: Cannot allocate memory for mem_ptr element",
+					 func_name);
+				return(-1);
+			}
 		} else
 			dssize = (dinfo->numdevs * sizeof(struct devstat)) +
 				 sizeof(long);
@@ -549,6 +555,7 @@
 	int old_num_selections = 0, old_num_selected;
 	int selection_number = 0;
 	int changed = 0, found = 0;
+	const char *func_name = "devstat_selectdevs";
 
 	if ((dev_select == NULL) || (devices == NULL) || (numdevs < 0))
 		return(-1);
@@ -572,7 +579,7 @@
 	 * either enlarge or reduce the size of the device selection list.
 	 */
 	} else if (*num_selections != numdevs) {
-		*dev_select = (struct device_selection *)realloc(*dev_select,
+		*dev_select = (struct device_selection *)reallocf(*dev_select,
 			numdevs * sizeof(struct device_selection));
 		*select_generation = current_generation;
 		init_selections = 1;
@@ -586,6 +593,13 @@
 		init_selections = 1;
 	}
 
+	if (*dev_select == NULL) {
+		snprintf(devstat_errbuf, sizeof(devstat_errbuf),
+			 "%s: Cannot (re)allocate memory for dev_select argument",
+			 func_name);
+		return(-1);
+	}
+
 	/*
 	 * If we're in "only" mode, we want to clear out the selected
 	 * variable since we're going to select exactly what the user wants
@@ -613,6 +627,12 @@
 	 || (perf_select != 0)) && (changed == 0)){
 		old_dev_select = (struct device_selection *)malloc(
 		    *num_selections * sizeof(struct device_selection));
+		if (old_dev_select == NULL) {
+			snprintf(devstat_errbuf, sizeof(devstat_errbuf),
+				 "%s: Cannot allocate memory for selection list backup",
+				 func_name);
+			return(-1);
+		}
 		old_num_selections = *num_selections;
 		bcopy(*dev_select, old_dev_select, 
 		    sizeof(struct device_selection) * *num_selections);
@@ -1033,16 +1053,17 @@
 		return(-1);
 	}
 
-	/*
-	 * Since you can't realloc a pointer that hasn't been malloced
-	 * first, we malloc first and then realloc.
-	 */
 	if (*num_matches == 0)
-		*matches = (struct devstat_match *)malloc(
-			   sizeof(struct devstat_match));
-	else
-		*matches = (struct devstat_match *)realloc(*matches,
-			  sizeof(struct devstat_match) * (*num_matches + 1));
+		*matches = NULL;
+
+	*matches = (struct devstat_match *)reallocf(*matches,
+		  sizeof(struct devstat_match) * (*num_matches + 1));
+
+	if (*matches == NULL) {
+		snprintf(devstat_errbuf, sizeof(devstat_errbuf),
+			 "%s: Cannot allocate memory for matches list", func_name);
+		return(-1);
+	}
 			  
 	/* Make sure the current entry is clear */
 	bzero(&matches[0][*num_matches], sizeof(struct devstat_match));
--- patch ends here ---
>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/83359: commit references a PR
Date: Fri,  6 Jan 2012 21:28:44 +0000 (UTC)

 Author: ghelmer
 Date: Fri Jan  6 21:28:29 2012
 New Revision: 229735
 URL: http://svn.freebsd.org/changeset/base/229735
 
 Log:
   Handle memory allocation failures in devstat_getdevs(), devstat_selectdevs(),
   and devstat_buildmatch().
   
   PR:		bin/83359
   Reviewed by:	ken
 
 Modified:
   head/lib/libdevstat/devstat.c
 
 Modified: head/lib/libdevstat/devstat.c
 ==============================================================================
 --- head/lib/libdevstat/devstat.c	Fri Jan  6 21:23:00 2012	(r229734)
 +++ head/lib/libdevstat/devstat.c	Fri Jan  6 21:28:29 2012	(r229735)
 @@ -365,6 +365,12 @@ devstat_getdevs(kvm_t *kd, struct statin
  			dssize = (dinfo->numdevs * sizeof(struct devstat)) +
  				 sizeof(long);
  			dinfo->mem_ptr = (u_int8_t *)malloc(dssize);
 +			if (dinfo->mem_ptr == NULL) {
 +				snprintf(devstat_errbuf, sizeof(devstat_errbuf),
 +					 "%s: Cannot allocate memory for mem_ptr element",
 +					 __func__);
 +				return(-1);
 +			}
  		} else
  			dssize = (dinfo->numdevs * sizeof(struct devstat)) +
  				 sizeof(long);
 @@ -567,7 +573,7 @@ devstat_selectdevs(struct device_selecti
  	 * either enlarge or reduce the size of the device selection list.
  	 */
  	} else if (*num_selections != numdevs) {
 -		*dev_select = (struct device_selection *)realloc(*dev_select,
 +		*dev_select = (struct device_selection *)reallocf(*dev_select,
  			numdevs * sizeof(struct device_selection));
  		*select_generation = current_generation;
  		init_selections = 1;
 @@ -581,6 +587,13 @@ devstat_selectdevs(struct device_selecti
  		init_selections = 1;
  	}
  
 +	if (*dev_select == NULL) {
 +		snprintf(devstat_errbuf, sizeof(devstat_errbuf),
 +			 "%s: Cannot (re)allocate memory for dev_select argument",
 +			 __func__);
 +		return(-1);
 +	}
 +
  	/*
  	 * If we're in "only" mode, we want to clear out the selected
  	 * variable since we're going to select exactly what the user wants
 @@ -608,6 +621,12 @@ devstat_selectdevs(struct device_selecti
  	 || (perf_select != 0)) && (changed == 0)){
  		old_dev_select = (struct device_selection *)malloc(
  		    *num_selections * sizeof(struct device_selection));
 +		if (old_dev_select == NULL) {
 +			snprintf(devstat_errbuf, sizeof(devstat_errbuf),
 +				 "%s: Cannot allocate memory for selection list backup",
 +				 __func__);
 +			return(-1);
 +		}
  		old_num_selections = *num_selections;
  		bcopy(*dev_select, old_dev_select, 
  		    sizeof(struct device_selection) * *num_selections);
 @@ -1028,16 +1047,17 @@ devstat_buildmatch(char *match_str, stru
  		return(-1);
  	}
  
 -	/*
 -	 * Since you can't realloc a pointer that hasn't been malloced
 -	 * first, we malloc first and then realloc.
 -	 */
  	if (*num_matches == 0)
 -		*matches = (struct devstat_match *)malloc(
 -			   sizeof(struct devstat_match));
 -	else
 -		*matches = (struct devstat_match *)realloc(*matches,
 -			  sizeof(struct devstat_match) * (*num_matches + 1));
 +		*matches = NULL;
 +
 +	*matches = (struct devstat_match *)reallocf(*matches,
 +		  sizeof(struct devstat_match) * (*num_matches + 1));
 +
 +	if (*matches == NULL) {
 +		snprintf(devstat_errbuf, sizeof(devstat_errbuf),
 +			 "%s: Cannot allocate memory for matches list", __func__);
 +		return(-1);
 +	}
  			  
  	/* Make sure the current entry is clear */
  	bzero(&matches[0][*num_matches], sizeof(struct devstat_match));
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: ghelmer 
State-Changed-When: Fri Jan 6 15:30:13 CST 2012 
State-Changed-Why:  
Committed after review, thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=83359 
>Unformatted:
