mtd/fs/jffs2 debug.c, 1.13, 1.14 erase.c, 1.88, 1.89 gc.c, 1.157, 1.158 nodelist.c, 1.117, 1.118 nodelist.h, 1.143, 1.144 read.c, 1.43, 1.44 scan.c, 1.130, 1.131 summary.c, 1.7, 1.8 wbuf.c, 1.105, 1.106

gleixner at infradead.org gleixner at infradead.org
Sun Nov 13 13:22:11 EST 2005


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv5393

Modified Files:
	debug.c erase.c gc.c nodelist.c nodelist.h read.c scan.c 
	summary.c wbuf.c 
Log Message:
[JFFS2] Fixup read_flash_safe patch

Plumb memory leaks, avoid use after free, prevent kfree of pointers
which point to variables on the stack



Index: debug.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/debug.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- debug.c	11 Nov 2005 14:29:11 -0000	1.13
+++ debug.c	13 Nov 2005 18:22:06 -0000	1.14
@@ -130,8 +130,10 @@
 	if (!buf)
 		return;
 
-	if (jffs2_flash_read_safe(c, ofs, len, buf))
+	if (jffs2_flash_read_safe(c, ofs, len, buf)) {
+		kfree(buf);
 		return;
+	}
 
 	ret = 0;
 	for (i = 0; i < len; i++)

Index: erase.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/erase.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- erase.c	11 Nov 2005 14:29:12 -0000	1.88
+++ erase.c	13 Nov 2005 18:22:06 -0000	1.89
@@ -323,7 +323,8 @@
 		*bad_offset = ofs;
 
 		if (jffs2_flash_read_safe(c, ofs, readlen, (void *)ebuf))
-			return ret;
+			goto fail;
+
 		for (i=0; i<readlen; i += sizeof(unsigned long)) {
 			/* It's OK. We know it's properly aligned */
 			unsigned long *datum = ebuf + i;

Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -r1.157 -r1.158
--- gc.c	11 Nov 2005 14:29:12 -0000	1.157
+++ gc.c	13 Nov 2005 18:22:06 -0000	1.158
@@ -530,8 +530,9 @@
 	if (!node)
                return -ENOMEM;
 
-	if (jffs2_flash_read_safe(c, ref_offset(raw), rawlen, (char*)node))
-		return -EIO;
+	ret = jffs2_flash_read_safe(c, ref_offset(raw), rawlen, (char*)node);
+	if (ret)
+		goto out_node;
 
 	crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4);
 	if (je32_to_cpu(node->u.hdr_crc) != crc) {
@@ -847,7 +848,8 @@
 
 			/* This is an obsolete node belonging to the same directory, and it's of the right
 			   length. We need to take a closer look...*/
-			if (jffs2_flash_read_safe(c, ref_offset(raw), rawlen, (char *)rd))
+			if (jffs2_flash_read_safe(c, ref_offset(raw), rawlen,
+						  (char *)rd))
 				/* If we can't read it, we don't need to continue to obsolete it. Continue */
 				continue;
 

Index: nodelist.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -r1.117 -r1.118
--- nodelist.c	11 Nov 2005 14:29:12 -0000	1.117
+++ nodelist.c	13 Nov 2005 18:22:07 -0000	1.118
@@ -451,8 +451,10 @@
 		if (unlikely(!buffer))
 			return -ENOMEM;
 
-		if (jffs2_flash_read_safe(c, ofs, len, buffer))
+		if (jffs2_flash_read_safe(c, ofs, len, buffer)) {
+			kfree(buffer);
 			return -EIO;
+		}
 	}
 
 	/* Continue calculating CRC */

Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.h,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -r1.143 -r1.144
--- nodelist.h	11 Nov 2005 08:51:38 -0000	1.143
+++ nodelist.h	13 Nov 2005 18:22:07 -0000	1.144
@@ -392,8 +392,6 @@
 /* scan.c */
 int jffs2_scan_medium(struct jffs2_sb_info *c);
 void jffs2_rotate_lists(struct jffs2_sb_info *c);
-int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
-				uint32_t ofs, uint32_t len);
 struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
 int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
 

Index: read.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/read.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- read.c	11 Nov 2005 14:29:12 -0000	1.43
+++ read.c	13 Nov 2005 18:22:07 -0000	1.44
@@ -112,8 +112,10 @@
 	D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize),
 		  readbuf));
 
-	if (jffs2_flash_read_safe(c, (ref_offset(fd->raw)) + sizeof(*ri), je32_to_cpu(ri->csize), readbuf))
-		return -EIO;
+	ret = jffs2_flash_read_safe(c, (ref_offset(fd->raw)) + sizeof(*ri),
+				    je32_to_cpu(ri->csize), readbuf);
+	if (ret)
+		goto out_decomprbuf;
 
 	crc = crc32(0, readbuf, je32_to_cpu(ri->csize));
 	if (crc != je32_to_cpu(ri->data_crc)) {

Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/scan.c,v
retrieving revision 1.130
retrieving revision 1.131
diff -u -r1.130 -r1.131
--- scan.c	12 Nov 2005 19:42:09 -0000	1.130
+++ scan.c	13 Nov 2005 18:22:07 -0000	1.131
@@ -271,18 +271,6 @@
 	return ret;
 }
 
-int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf,
-				uint32_t ofs, uint32_t len)
-{
-	D2(char *cbuf = buf);
-	if (jffs2_flash_read_safe(c, ofs, len, buf))
-		return -EIO;
-	D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs));
-	D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-		  cbuf[0], cbuf[1], cbuf[2], cbuf[3], cbuf[4], cbuf[5], cbuf[6], cbuf[7], cbuf[8], cbuf[9], cbuf[10], cbuf[11], cbuf[12], cbuf[13], cbuf[14], cbuf[15]));
-	return 0;
-}
-
 int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
 	if (EBFLAGS_HAS_EBH(jeb) && c->ebh_size) {
@@ -350,8 +338,10 @@
 			return -ENOMEM;
 		}
 
-		err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -
-					sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));
+		err = jffs2_flash_read_safe(c, jeb->offset + c->sector_size -
+					    sizeof(struct jffs2_sum_marker),
+					    sizeof(struct jffs2_sum_marker),
+					    (unsigned char *) sm);
 		if (err) {
 			kfree(sm);
 			return err;
@@ -378,14 +368,14 @@
 
 		if (jffs2_sum_active()) {
 			/* must reread because of summary test */
-			err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
+			err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 			if (err)
 				return err;
 		}
 
 	} else {
 		buf_len = EMPTY_SCAN_SIZE(c->sector_size);
-		err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
+		err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 		if (err)
 			return err;
 	}
@@ -460,7 +450,7 @@
 			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
 			D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",
 				  sizeof(struct jffs2_unknown_node), buf_len, ofs));
-			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+			err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 			if (err)
 				return err;
 			buf_ofs = ofs;
@@ -517,7 +507,7 @@
 				break;
 			}
 			D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs));
-			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+			err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 			if (err)
 				return err;
 			buf_ofs = ofs;
@@ -593,7 +583,7 @@
 				buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
 				D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n",
 					  sizeof(struct jffs2_raw_inode), buf_len, ofs));
-				err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+				err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 				if (err)
 					return err;
 				buf_ofs = ofs;
@@ -609,7 +599,7 @@
 				buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
 				D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n",
 					  je32_to_cpu(node->totlen), buf_len, ofs));
-				err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+				err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 				if (err)
 					return err;
 				buf_ofs = ofs;
@@ -656,7 +646,7 @@
 			} else {
 				if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
 					buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-					err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+					err = jffs2_flash_read_safe(c, buf_ofs, buf_len, buf);
 					if (err)
 						return err;
 					buf_ofs = ofs;

Index: summary.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/summary.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- summary.c	11 Nov 2005 08:51:39 -0000	1.7
+++ summary.c	13 Nov 2005 18:22:07 -0000	1.8
@@ -556,7 +556,8 @@
 		return -ENOMEM;
 	}
 
-	ret = jffs2_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
+	ret = jffs2_flash_read_safe_buf(c, ofs, sumsize,
+					(unsigned char *)summary);
 
 	if (ret) {
 		kfree(summary);

Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.105
retrieving revision 1.106
diff -u -r1.105 -r1.106
--- wbuf.c	11 Nov 2005 14:29:12 -0000	1.105
+++ wbuf.c	13 Nov 2005 18:22:07 -0000	1.106
@@ -930,24 +930,20 @@
 int jffs2_flash_read_safe(struct jffs2_sb_info *c, uint32_t ofs, int len, u_char *buf)
 {
 	size_t retlen;
-	int err, ret = 0;
-
-	/* read the data */
-	err = jffs2_flash_read(c, ofs, len, &retlen, buf);
+	int err = jffs2_flash_read(c, ofs, len, &retlen, buf);
 
 	/* did the read succeed? */
-	if (err) {
+	if (unlikely(err)) {
 		JFFS2_ERROR("can not read %d bytes from 0x%08x, error code: %d.\n", len, ofs, err);
-		kfree(buf);
-		ret = -EIO;
+		return -EIO;
 	}
+
 	/* did we read all? */
-	if (retlen != len) {
-	JFFS2_ERROR("short read at 0x%08x: %d instead of %d.\n", ofs, retlen, len);
-		kfree(buf);
-		ret = -EIO;
+	if (unlikely(retlen != len)) {
+		JFFS2_ERROR("short read at 0x%08x: %d instead of %d.\n", ofs, retlen, len);
+		return -EIO;
 	}
-	return ret;
+	return 0;
 }
 
 /*





More information about the linux-mtd-cvs mailing list