mirror of
				https://github.com/eledio-devices/thirdparty-littlefs.git
				synced 2025-10-31 08:42:40 +01:00 
			
		
		
		
	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
This commit is contained in:
		
							
								
								
									
										14
									
								
								lfs.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								lfs.c
									
									
									
									
									
								
							| @@ -2475,7 +2475,11 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|     lfs_dir_t cwd = {.d.tail[0] = 0, .d.tail[1] = 1}; |     lfs_dir_t cwd = {.d.tail[0] = 0, .d.tail[1] = 1}; | ||||||
|  |  | ||||||
|     // iterate over all directory directory entries |     // iterate over all directory directory entries | ||||||
|     while (!lfs_pairisnull(cwd.d.tail)) { |     for (int i = 0; i < lfs->cfg->block_count; i++) { | ||||||
|  |         if (lfs_pairisnull(cwd.d.tail)) { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         int err = lfs_dir_fetch(lfs, &cwd, cwd.d.tail); |         int err = lfs_dir_fetch(lfs, &cwd, cwd.d.tail); | ||||||
|         if (err) { |         if (err) { | ||||||
|             return err; |             return err; | ||||||
| @@ -2504,7 +2508,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|                     return err; |                     return err; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 break; |                 return 0; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (!lfs_pairsync(entry.d.u.dir, pdir.d.tail)) { |             if (!lfs_pairsync(entry.d.u.dir, pdir.d.tail)) { | ||||||
| @@ -2520,7 +2524,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|                     return err; |                     return err; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 break; |                 return 0; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -2565,5 +2569,7 @@ int lfs_deorphan(lfs_t *lfs) { | |||||||
|         memcpy(&pdir, &cwd, sizeof(pdir)); |         memcpy(&pdir, &cwd, sizeof(pdir)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return 0; |     // If we reached here, we have more directory pairs than blocks in the | ||||||
|  |     // filesystem... So something must be horribly wrong | ||||||
|  |     return LFS_ERR_CORRUPT; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user