diff mbox series

JFFS2: fix the reading address over nand's limit

Message ID 518786c46f01890819e44f06647de5bf3c47fe05.camel@gmail.com
State New
Delegated to: Tom Rini
Headers show
Series JFFS2: fix the reading address over nand's limit | expand

Commit Message

Wagner Popov dos Santos Feb. 23, 2021, 2:30 a.m. UTC
Fixes address violation in functions read_nand_cached() and
read_onenand_cached(). This happens because these functions
try to read a fixed amount
of data even when the offset+length
is above the nand's limit.

Signed-off-by: Wagner Popov dos Santos <wpopov@gmail.com>
---
 fs/jffs2/jffs2_1pass.c | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

Comments

Wagner Popov dos Santos March 4, 2021, 12:33 a.m. UTC | #1
Forgot to Cc the maintainer, doing it now, sorry for the spam.

Em seg, 2021-02-22 às 23:30 -0300, Wagner Popov dos Santos escreveu:
> Fixes address violation in functions read_nand_cached() and
> read_onenand_cached(). This happens because these functions
> try to read a fixed amount
> of data even when the offset+length
> is above the nand's limit.
> 
> Signed-off-by: Wagner Popov dos Santos <wpopov@gmail.com>
> ---
>  fs/jffs2/jffs2_1pass.c | 37 +++++++++++++++++++++++++++----------
>  1 file changed, 27 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
> index a98745c50e..b39943671c 100644
> --- a/fs/jffs2/jffs2_1pass.c
> +++ b/fs/jffs2/jffs2_1pass.c
> @@ -180,6 +180,7 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf)
>  	struct mtd_info *mtd;
>  	u32 bytes_read = 0;
>  	size_t retlen;
> +	size_t toread;
>  	int cpy_bytes;
>  
>  	mtd = get_nand_dev_by_index(id->num);
> @@ -187,8 +188,12 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf)
>  		return -1;
>  
>  	while (bytes_read < size) {
> +		retlen = NAND_CACHE_SIZE;
> +		if( nand_cache_off + retlen > mtd->size )
> +			retlen = mtd->size - nand_cache_off;
> +
>  		if ((off + bytes_read < nand_cache_off) ||
> -		    (off + bytes_read >= nand_cache_off+NAND_CACHE_SIZE)) {
> +		    (off + bytes_read >= nand_cache_off + retlen)) {
>  			nand_cache_off = (off + bytes_read) & NAND_PAGE_MASK;
>  			if (!nand_cache) {
>  				/* This memory never gets freed but 'cause
> @@ -201,16 +206,20 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf)
>  				}
>  			}
>  
> -			retlen = NAND_CACHE_SIZE;
> +			toread = NAND_CACHE_SIZE;
> +			if( nand_cache_off + toread > mtd->size )
> +				toread = mtd->size - nand_cache_off;
> +
> +			retlen = toread;
>  			if (nand_read(mtd, nand_cache_off,
>  				      &retlen, nand_cache) < 0 ||
> -					retlen != NAND_CACHE_SIZE) {
> +					retlen != toread) {
>  				printf("read_nand_cached: error reading nand off %#x size %d bytes\n",
> -						nand_cache_off, NAND_CACHE_SIZE);
> +						nand_cache_off, toread);
>  				return -1;
>  			}
>  		}
> -		cpy_bytes = nand_cache_off + NAND_CACHE_SIZE - (off + bytes_read);
> +		cpy_bytes = nand_cache_off + retlen - (off + bytes_read);
>  		if (cpy_bytes > size - bytes_read)
>  			cpy_bytes = size - bytes_read;
>  		memcpy(buf + bytes_read,
> @@ -283,11 +292,16 @@ static int read_onenand_cached(u32 off, u32 size, u_char *buf)
>  {
>  	u32 bytes_read = 0;
>  	size_t retlen;
> +	size_t toread;
>  	int cpy_bytes;
>  
>  	while (bytes_read < size) {
> +		retlen = ONENAND_CACHE_SIZE;
> +		if( onenand_cache_off + retlen > onenand_mtd.size )
> +			retlen = onenand_mtd.size - onenand_cache_off;
> +
>  		if ((off + bytes_read < onenand_cache_off) ||
> -		    (off + bytes_read >= onenand_cache_off + ONENAND_CACHE_SIZE)) {
> +		    (off + bytes_read >= onenand_cache_off + retlen)) {
>  			onenand_cache_off = (off + bytes_read) & ONENAND_PAGE_MASK;
>  			if (!onenand_cache) {
>  				/* This memory never gets freed but 'cause
> @@ -300,16 +314,19 @@ static int read_onenand_cached(u32 off, u32 size, u_char *buf)
>  				}
>  			}
>  
> -			retlen = ONENAND_CACHE_SIZE;
> +			toread = ONENAND_CACHE_SIZE;
> +			if( onenand_cache_off + toread > onenand_mtd.size )
> +				toread = onenand_mtd.size - onenand_cache_off;
> +			retlen = toread;
>  			if (onenand_read(&onenand_mtd, onenand_cache_off, retlen,
>  						&retlen, onenand_cache) < 0 ||
> -					retlen != ONENAND_CACHE_SIZE) {
> +					retlen != toread) {
>  				printf("read_onenand_cached: error reading nand off %#x size %d bytes\n",
> -					onenand_cache_off, ONENAND_CACHE_SIZE);
> +					onenand_cache_off, toread);
>  				return -1;
>  			}
>  		}
> -		cpy_bytes = onenand_cache_off + ONENAND_CACHE_SIZE - (off + bytes_read);
> +		cpy_bytes = onenand_cache_off + retlen - (off + bytes_read);
>  		if (cpy_bytes > size - bytes_read)
>  			cpy_bytes = size - bytes_read;
>  		memcpy(buf + bytes_read,
diff mbox series

Patch

diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
index a98745c50e..b39943671c 100644
--- a/fs/jffs2/jffs2_1pass.c
+++ b/fs/jffs2/jffs2_1pass.c
@@ -180,6 +180,7 @@  static int read_nand_cached(u32 off, u32 size, u_char *buf)
 	struct mtd_info *mtd;
 	u32 bytes_read = 0;
 	size_t retlen;
+	size_t toread;
 	int cpy_bytes;
 
 	mtd = get_nand_dev_by_index(id->num);
@@ -187,8 +188,12 @@  static int read_nand_cached(u32 off, u32 size, u_char *buf)
 		return -1;
 
 	while (bytes_read < size) {
+		retlen = NAND_CACHE_SIZE;
+		if( nand_cache_off + retlen > mtd->size )
+			retlen = mtd->size - nand_cache_off;
+
 		if ((off + bytes_read < nand_cache_off) ||
-		    (off + bytes_read >= nand_cache_off+NAND_CACHE_SIZE)) {
+		    (off + bytes_read >= nand_cache_off + retlen)) {
 			nand_cache_off = (off + bytes_read) & NAND_PAGE_MASK;
 			if (!nand_cache) {
 				/* This memory never gets freed but 'cause
@@ -201,16 +206,20 @@  static int read_nand_cached(u32 off, u32 size, u_char *buf)
 				}
 			}
 
-			retlen = NAND_CACHE_SIZE;
+			toread = NAND_CACHE_SIZE;
+			if( nand_cache_off + toread > mtd->size )
+				toread = mtd->size - nand_cache_off;
+
+			retlen = toread;
 			if (nand_read(mtd, nand_cache_off,
 				      &retlen, nand_cache) < 0 ||
-					retlen != NAND_CACHE_SIZE) {
+					retlen != toread) {
 				printf("read_nand_cached: error reading nand off %#x size %d bytes\n",
-						nand_cache_off, NAND_CACHE_SIZE);
+						nand_cache_off, toread);
 				return -1;
 			}
 		}
-		cpy_bytes = nand_cache_off + NAND_CACHE_SIZE - (off + bytes_read);
+		cpy_bytes = nand_cache_off + retlen - (off + bytes_read);
 		if (cpy_bytes > size - bytes_read)
 			cpy_bytes = size - bytes_read;
 		memcpy(buf + bytes_read,
@@ -283,11 +292,16 @@  static int read_onenand_cached(u32 off, u32 size, u_char *buf)
 {
 	u32 bytes_read = 0;
 	size_t retlen;
+	size_t toread;
 	int cpy_bytes;
 
 	while (bytes_read < size) {
+		retlen = ONENAND_CACHE_SIZE;
+		if( onenand_cache_off + retlen > onenand_mtd.size )
+			retlen = onenand_mtd.size - onenand_cache_off;
+
 		if ((off + bytes_read < onenand_cache_off) ||
-		    (off + bytes_read >= onenand_cache_off + ONENAND_CACHE_SIZE)) {
+		    (off + bytes_read >= onenand_cache_off + retlen)) {
 			onenand_cache_off = (off + bytes_read) & ONENAND_PAGE_MASK;
 			if (!onenand_cache) {
 				/* This memory never gets freed but 'cause
@@ -300,16 +314,19 @@  static int read_onenand_cached(u32 off, u32 size, u_char *buf)
 				}
 			}
 
-			retlen = ONENAND_CACHE_SIZE;
+			toread = ONENAND_CACHE_SIZE;
+			if( onenand_cache_off + toread > onenand_mtd.size )
+				toread = onenand_mtd.size - onenand_cache_off;
+			retlen = toread;
 			if (onenand_read(&onenand_mtd, onenand_cache_off, retlen,
 						&retlen, onenand_cache) < 0 ||
-					retlen != ONENAND_CACHE_SIZE) {
+					retlen != toread) {
 				printf("read_onenand_cached: error reading nand off %#x size %d bytes\n",
-					onenand_cache_off, ONENAND_CACHE_SIZE);
+					onenand_cache_off, toread);
 				return -1;
 			}
 		}
-		cpy_bytes = onenand_cache_off + ONENAND_CACHE_SIZE - (off + bytes_read);
+		cpy_bytes = onenand_cache_off + retlen - (off + bytes_read);
 		if (cpy_bytes > size - bytes_read)
 			cpy_bytes = size - bytes_read;
 		memcpy(buf + bytes_read,