mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
JFFS2: fix the reading address over nand's limit
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>
This commit is contained in:
parent
02395fec00
commit
610a2cc7a3
1 changed files with 27 additions and 10 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue