Message ID | 518786c46f01890819e44f06647de5bf3c47fe05.camel@gmail.com |
---|---|
State | Accepted |
Commit | 610a2cc7a38782bf2fa5c1037959a42838ebb2ad |
Delegated to: | Tom Rini |
Headers | show |
Series | JFFS2: fix the reading address over nand's limit | expand |
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,
On Mon, Feb 22, 2021 at 11:30:58PM -0300, Wagner Popov dos Santos wrote: > 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> Applied to u-boot/master, thanks!
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,
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(-)