[go: up one dir, main page]

Menu

#6 Initialization Robustness in BuildValidTreeNode

v1.0 (example)
open
nobody
None
5
2014-04-03
2014-03-28
Conrad
No

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);

ifdef CONFIG_UFFS_REFRESH_BLOCK

if (ret == UFFS_FLASH_ECC_OK)
uffs_BadBlockAdd(dev, block, UFFS_PENDING_BLK_REFRESH);
else

endif

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);

Discussion

  • Ricky Zheng

    Ricky Zheng - 2014-03-28

    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.

     
  • Conrad

    Conrad - 2014-03-29

    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.

     
  • Conrad

    Conrad - 2014-04-03

    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:

    • A runtime check to see if UFFS is being configured with more pages per block than it supports, and if so error out.
    • The line TAG_PAGE_ID(tag) = (u8)(i & 0xFF); should be updated to TAG_PAGE_ID(tag) = i; in the latest code release, and the FIX ME comment deleted.
    • A CRC should be added to the FileInfo page to verify the integrity of the metadata.
    • Put a LEN sanity check on the core CRC routine. Cap the max length to 16K or 64K for instance.
    • There are a few spots in the code where a page read is done, but the contents of the page are used unconditionally (i.e. file metadata), even if the page reports as bad (bad ECC or bad CRC). In these places, the assumption is made that the page will be good based on a recent prior good page read of the data. However, I don't think this is an assumption that should be relied upon. I think the code should assume that a bad page read can happen at any time even if it was recently good.

    Chris

     

Log in to post a comment.