In _BuildValidTreeNode(), there is the following code (at end). Between the FlashReadPage and the uffs_MakeSum16() call, the validity of the page is not considered. "info->" is used unconditionally. Here, the read page is garbage and it is trying to pass a value of 16843009 for info->len, sending uffs_MakeSum16() off into space! Some parameter checking must be implemented here. I'm not sure of the right way to address it.
ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE);
if (ret == UFFS_FLASH_ECC_OK)
uffs_BadBlockAdd(dev, block, UFFS_PENDING_BLK_REFRESH);
else
if (UFFS_FLASH_IS_BAD_BLOCK(ret))
uffs_BadBlockAdd(dev, block, UFFS_PENDING_BLK_RECOVER);
info = (uffs_FileInfo *) (buf->data);
data_sum = uffs_MakeSum16(info->name, info->name_len);
I guess we could check the name_len here or add a CRC to check uffs_FileInfo.
But why the info is invalid ? we are building a valid tree node and the data suppose to be valid.
My immediate workaround was to add a length sanity check to the core CRC routine. It might be good to cap the length at whatever the maximum size expected for this routine (max page size?) so at least it always falls through in reasonable time.
As far as why the info is invalid, that is what I am trying to figure out. I am still having an issue with getting UFFS up and running for the first time on my target. Files above a certain size are not appearing in the directory. I think it is related (i.e. bad FileInfo). However, this is probably a problem with my low level flash drivers, not UFFS. I'm still investigating.
To add additional robustness I think the assumption should be made that any page read can result in bad data, even though it may have passed integrity check before. In this case, a page is read from external flash, it is checked to be marked as a bad, however the info-> data is then unconditionally used (even if the page is detected as corrupt). Here, it's probably my faulty flash driver. However, an unintended write or cosmic event could give a corrupt page read at any time. Yes, I think a CRC should validate ALL file metadata in the absence of a page wide ECC or CRC check, including the FileInfo. I think a CRC here would be a good solution.
There are only a few spots in the code where uffs_FlashPageRead() is called, and in some of those spots the metadata is used unconditionally regardless of the page error reporting:
URET _BuildValidTreeNode(()
uffs_BufFlush_Exist_With_BlockRecover()
uffs_BufGetEx()
process_pending_recover()
Additional error handling should be added in these spots to mitigate a bad page read or a maliciously corrupted page.
An update to this post:
Ricky, thanks for your help in troubleshooting the problem!
The core problem was that the max number of pages per block UFFS supports out of the box is 64, and UFFS was aliasing to the wrong page looking for the FileInfo header. This can be rectified by modifying the uffs_TagStoreSt to increase the pade_id bit-field while reducing the reserved field to make room. Additionally the line TAG_PAGE_ID(tag) = (u8)(i & 0xFF); needs to be updated.
To this, I have the following feature requests:
Chris