Module Name:    src
Committed By:   he
Date:           Mon Sep  1 16:27:38 UTC 2014

Modified Files:
        src/sys/ufs/chfs: chfs_scan.c

Log Message:
Plug leak in chfs_scan_eraseblock() of the allocated buffer.
Make sure to release it both on success and failure returns.
OK'ed by ttoth@


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/ufs/chfs/chfs_scan.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/chfs/chfs_scan.c
diff -u src/sys/ufs/chfs/chfs_scan.c:1.4 src/sys/ufs/chfs/chfs_scan.c:1.5
--- src/sys/ufs/chfs/chfs_scan.c:1.4	Fri Oct 19 12:44:39 2012
+++ src/sys/ufs/chfs/chfs_scan.c	Mon Sep  1 16:27:38 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: chfs_scan.c,v 1.4 2012/10/19 12:44:39 ttoth Exp $	*/
+/*	$NetBSD: chfs_scan.c,v 1.5 2014/09/01 16:27:38 he Exp $	*/
 
 /*-
  * Copyright (c) 2010 Department of Software Engineering,
@@ -443,15 +443,15 @@ chfs_scan_eraseblock(struct chfs_mount *
 		memset(buf, 0 , CHFS_MAX_NODE_SIZE);
 		err = chfs_read_leb(chmp,
 		    lnr, buf, ofs, CHFS_NODE_HDR_SIZE, &retlen);
-		if (err) {
-			return err;
-		}
+		if (err)
+			goto err_return;
 
 		if (retlen != CHFS_NODE_HDR_SIZE) {
 			chfs_err("Error reading node header: "
 			    "read: %zu instead of: %zu\n",
 			    CHFS_NODE_HDR_SIZE, retlen);
-			return EIO;
+			err = EIO;
+			goto err_return;
 		}
 
 		/* first we check if the buffer we read is full with 0xff, if yes maybe
@@ -476,9 +476,8 @@ chfs_scan_eraseblock(struct chfs_mount *
 		if (err) {
 			dbg("node hdr error\n");
 			err = chfs_update_eb_dirty(chmp, cheb, 4);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			ofs += 4;
 			continue;
@@ -486,7 +485,8 @@ chfs_scan_eraseblock(struct chfs_mount *
 		ofs += CHFS_NODE_HDR_SIZE;
 		if (ofs > chmp->chm_ebh->eb_size) {
 			chfs_err("Second part of node is on the next eraseblock.\n");
-			return EIO;
+			err = EIO;
+			goto err_return;
 		}
 		switch (le16toh(nhdr->type)) {
 		case CHFS_NODETYPE_VNODE:
@@ -496,21 +496,20 @@ chfs_scan_eraseblock(struct chfs_mount *
 			err = chfs_read_leb(chmp,
 			    lnr, buf + CHFS_NODE_HDR_SIZE,
 			    ofs, len,  &retlen);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			if (retlen != len) {
 				chfs_err("Error reading vnode: read: %zu instead of: %zu\n",
 				    len, retlen);
-				return EIO;
+				err = EIO;
+				goto err_return;
 			}
 			KASSERT(lnr == cheb->lnr);
 			err = chfs_scan_check_vnode(chmp,
 			    cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			break;
 		case CHFS_NODETYPE_DIRENT:
@@ -521,23 +520,22 @@ chfs_scan_eraseblock(struct chfs_mount *
 			err = chfs_read_leb(chmp,
 			    lnr, buf + CHFS_NODE_HDR_SIZE,
 			    ofs, len, &retlen);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			if (retlen != len) {
 				chfs_err("Error reading dirent node: read: %zu "
 				    "instead of: %zu\n", len, retlen);
-				return EIO;
+				err = EIO;
+				goto err_return;
 			}
 
 			KASSERT(lnr == cheb->lnr);
 
 			err = chfs_scan_check_dirent_node(chmp,
 			    cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			break;
 		case CHFS_NODETYPE_DATA:
@@ -547,20 +545,20 @@ chfs_scan_eraseblock(struct chfs_mount *
 			err = chfs_read_leb(chmp,
 			    lnr, buf + CHFS_NODE_HDR_SIZE,
 			    ofs, len, &retlen);
-			if (err) {
-				return err;
-			}
+			if (err)
+				goto err_return;
 
 			if (retlen != len) {
 				chfs_err("Error reading data node: read: %zu "
 				    "instead of: %zu\n", len, retlen);
-				return EIO;
+				err = EIO;
+				goto err_return;
 			}
 			KASSERT(lnr == cheb->lnr);
 			err = chfs_scan_check_data_node(chmp,
 			    cheb, buf, ofs - CHFS_NODE_HDR_SIZE);
 			if (err)
-				return err;
+				goto err_return;
 
 			break;
 		case CHFS_NODETYPE_PADDING:
@@ -573,7 +571,7 @@ chfs_scan_eraseblock(struct chfs_mount *
 			err = chfs_update_eb_dirty(chmp, cheb,
 			    le32toh(nhdr->length));
 			if (err)
-				return err;
+				goto err_return;
 
 			break;
 		default:
@@ -581,7 +579,7 @@ chfs_scan_eraseblock(struct chfs_mount *
 			err = chfs_update_eb_dirty(chmp, cheb,
 			    le32toh(nhdr->length));
 			if (err)
-				return err;
+				goto err_return;
 
 			break;
 		}
@@ -591,5 +589,9 @@ chfs_scan_eraseblock(struct chfs_mount *
 	KASSERT(cheb->used_size + cheb->free_size + cheb->dirty_size +
 	    cheb->unchecked_size + cheb->wasted_size == chmp->chm_ebh->eb_size);
 
-	return chfs_scan_classify_cheb(chmp, cheb);
+	err = chfs_scan_classify_cheb(chmp, cheb);
+	/* FALLTHROUGH */
+    err_return:
+	kmem_free(buf, CHFS_MAX_NODE_SIZE);
+	return err;
 }

Reply via email to