FreeRTOS+FAT memory overwrite in FF_WritePartial

I have an old, very used SD card that occasionally fails. When this happens, my I/O Manager’s fnWriteBlocks returns FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG. This often leads to a HardFault. Chasing down this error path, I think I see a problem in FF_WritePartial:

  • pxFile->pucBuffer is allocated in prvAllocFileHandle:
pxFile->pucBuffer = ( uint8_t * ) ffconfigMALLOC( pxIOManager->usSectorSize );

where pxIOManager->usSectorSize is 512.

  • FF_WritePartial is called with ulCount 4096
  • FF_WritePartial does
memcpy( pxFile->pucBuffer + ulRelBlockPos, pucBuffer, ulCount );

which winds up clobbering various things on the heap.

In this scenario, FF_WritePartial() at ff_file.c:2,166 has:

pxFile	FF_FILE *	0x2000c988 <ucHeap+47644>	
pxFile@entry	FF_FILE *	0x2000c988 <ucHeap+47644>	
	pxIOManager	FF_IOManager_t *	0x2000a5b8 <ucHeap+38476>	
	ulFileSize	uint32_t	16384	
	ulObjectCluster	uint32_t	113548	
	ulChainLength	uint32_t	1	
	ulCurrentCluster	uint32_t	0	
	ulAddrCurrentCluster	uint32_t	113548	
	ulEndOfChain	uint32_t	268435455	
	ulFilePointer	uint32_t	16384	
	ulDirCluster	uint32_t	106017	
	ulValidFlags	uint32_t	0	
	pucBuffer	uint8_t *	0x2000c9c8 <ucHeap+47708> ""	
	ucState	uint8_t	0 '\0'	
	ucMode	uint8_t	26 '\032'	
	usDirEntry	uint16_t	83	
	pxNext	struct _FF_FILE *	0x0	
ulItemLBA	uint32_t	7282794	
ulRelBlockPos	uint32_t	0	
ulRelBlockPos@entry	uint32_t	0	
ulCount	uint32_t	4096	
ulCount@entry	uint32_t	4096	

It is called from FF_Write() at ff_file.c:2,465 with:

ulBytesLeft	uint32_t	4096	
nBytesWritten	uint32_t	0	
pxIOManager	FF_IOManager_t *	0x2000a5b8 <ucHeap+38476>	
xError	FF_Error_t	0	
pxFile	FF_FILE *	0x2000c988 <ucHeap+47644>	
ulElementSize	uint32_t	1	
ulElementSize@entry	uint32_t	1	
ulCount	uint32_t	4096	
ulCount@entry	uint32_t	4096	

which is called from ff_fwrite() at ff_stdio.c:398 with:

xSize	size_t	1	
xSize@entry	size_t	1	
xItems	size_t	4096	
xItems@entry	size_t	4096	

The problem is easy to recreate simply by modifying fnWriteBlocks to occasionally return an error.

Hi, thanks for the bug report!

I’ve opened a PR to fix it here: Add missing error check by archigup · Pull Request #68 · FreeRTOS/Lab-Project-FreeRTOS-FAT · GitHub

If the fix works for you, let us know, thanks!

1 Like