Skip to content

Commit e5a6938

Browse files
committed
Fixed possible infinite loop in deorphan step
Normally, the linked-list of directory pairs should terminate at a null pointer. However, it is possible if the filesystem is corrupted, that that this linked-list forms a cycle. This should never happen with littlefs's power resilience, but if it does we should recover appropriately. Modified lfs_deorphan to notice if we have a cycle and return LFS_ERR_CORRUPT in that situation. Found by kneko715
1 parent 3419284 commit e5a6938

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

lfs.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,7 +2475,11 @@ int lfs_deorphan(lfs_t *lfs) {
24752475
lfs_dir_t cwd = {.d.tail[0] = 0, .d.tail[1] = 1};
24762476

24772477
// iterate over all directory directory entries
2478-
while (!lfs_pairisnull(cwd.d.tail)) {
2478+
for (int i = 0; i < lfs->cfg->block_count; i++) {
2479+
if (lfs_pairisnull(cwd.d.tail)) {
2480+
return 0;
2481+
}
2482+
24792483
int err = lfs_dir_fetch(lfs, &cwd, cwd.d.tail);
24802484
if (err) {
24812485
return err;
@@ -2504,7 +2508,7 @@ int lfs_deorphan(lfs_t *lfs) {
25042508
return err;
25052509
}
25062510

2507-
break;
2511+
return 0;
25082512
}
25092513

25102514
if (!lfs_pairsync(entry.d.u.dir, pdir.d.tail)) {
@@ -2520,7 +2524,7 @@ int lfs_deorphan(lfs_t *lfs) {
25202524
return err;
25212525
}
25222526

2523-
break;
2527+
return 0;
25242528
}
25252529
}
25262530

@@ -2565,5 +2569,7 @@ int lfs_deorphan(lfs_t *lfs) {
25652569
memcpy(&pdir, &cwd, sizeof(pdir));
25662570
}
25672571

2568-
return 0;
2572+
// If we reached here, we have more directory pairs than blocks in the
2573+
// filesystem... So something must be horribly wrong
2574+
return LFS_ERR_CORRUPT;
25692575
}

0 commit comments

Comments
 (0)