mirror of
https://github.com/eledio-devices/thirdparty-littlefs.git
synced 2025-11-01 00:38:29 +01:00
Modified lfs_ctz_extend to be a little bit safer
Specifically around error handling. As is, incorrectly handled errors could cause higher code to get uninitialized blocks, potentially leading to writes to arbitray blocks on storage.
This commit is contained in:
20
lfs.c
20
lfs.c
@@ -1054,17 +1054,18 @@ static int lfs_ctz_find(lfs_t *lfs,
|
|||||||
static int lfs_ctz_extend(lfs_t *lfs,
|
static int lfs_ctz_extend(lfs_t *lfs,
|
||||||
lfs_cache_t *rcache, lfs_cache_t *pcache,
|
lfs_cache_t *rcache, lfs_cache_t *pcache,
|
||||||
lfs_block_t head, lfs_size_t size,
|
lfs_block_t head, lfs_size_t size,
|
||||||
lfs_off_t *block, lfs_block_t *off) {
|
lfs_block_t *block, lfs_off_t *off) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (true) {
|
|
||||||
// go ahead and grab a block
|
// go ahead and grab a block
|
||||||
int err = lfs_alloc(lfs, block);
|
lfs_block_t nblock;
|
||||||
|
int err = lfs_alloc(lfs, &nblock);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
assert(*block >= 2 && *block <= lfs->cfg->block_count);
|
assert(nblock >= 2 && nblock <= lfs->cfg->block_count);
|
||||||
|
|
||||||
err = lfs_bd_erase(lfs, *block);
|
if (true) {
|
||||||
|
err = lfs_bd_erase(lfs, nblock);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
goto relocate;
|
goto relocate;
|
||||||
@@ -1073,6 +1074,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
|
*block = nblock;
|
||||||
*off = 0;
|
*off = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1092,7 +1094,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = lfs_cache_prog(lfs, pcache, rcache,
|
err = lfs_cache_prog(lfs, pcache, rcache,
|
||||||
*block, i, &data, 1);
|
nblock, i, &data, 1);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
goto relocate;
|
goto relocate;
|
||||||
@@ -1101,6 +1103,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*block = nblock;
|
||||||
*off = size;
|
*off = size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1111,7 +1114,7 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
|||||||
|
|
||||||
for (lfs_off_t i = 0; i < skips; i++) {
|
for (lfs_off_t i = 0; i < skips; i++) {
|
||||||
int err = lfs_cache_prog(lfs, pcache, rcache,
|
int err = lfs_cache_prog(lfs, pcache, rcache,
|
||||||
*block, 4*i, &head, 4);
|
nblock, 4*i, &head, 4);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == LFS_ERR_CORRUPT) {
|
if (err == LFS_ERR_CORRUPT) {
|
||||||
goto relocate;
|
goto relocate;
|
||||||
@@ -1130,12 +1133,13 @@ static int lfs_ctz_extend(lfs_t *lfs,
|
|||||||
assert(head >= 2 && head <= lfs->cfg->block_count);
|
assert(head >= 2 && head <= lfs->cfg->block_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*block = nblock;
|
||||||
*off = 4*skips;
|
*off = 4*skips;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
relocate:
|
relocate:
|
||||||
LFS_DEBUG("Bad block at %d", *block);
|
LFS_DEBUG("Bad block at %d", nblock);
|
||||||
|
|
||||||
// just clear cache and try a new block
|
// just clear cache and try a new block
|
||||||
pcache->block = 0xffffffff;
|
pcache->block = 0xffffffff;
|
||||||
|
|||||||
Reference in New Issue
Block a user