Add stronger checks for offset in seek#1017
Conversation
Previous checks were trying to validate that file->pos does not become
negative. However, the method used for checking this contains possible
undefined behaivor (UB) because of the signed integer overflow.
This commit adds stronger checks for offset calculation:
* make sure that ((lfs_soff_t) file->pos + off) is never < 0. Instead
of using signed addition to check that (which can possibly lead to
UB), use signed comparison: off < 0 && (lfs_soff_t) file->pos <
-off. A special check of off against INT32_MIN is added to make sure
that -off does not get transformed into -INT32_MIN, which is as well UB.
* make sure that unsigned overflow does not occur in file->pos +
(lfs_off_t) off.
Thoughts:
* the lseek manual mandates an EOVERFLOW when the new offset cannot be
represened in the offset type. I wonder if we want to return that
instead of INVAL when an unsigned overflow occurs.
Tests passed ✓, Code: 17136 B (+0.4%), Stack: 1440 B (+0.0%), Structs: 812 B (+0.0%)
|
|
Hi @lucic71, thanks for creating a PR, sorry about the late response. These checks were originally implemented before v2.9, in an attempt to provide limited support for 32-bit file sizes. But this idea has since been dropped due to API issues, with littlefs now strictly using 31-bit file sizes. Which makes me wonder, is it possible to simplify all of this by just doing unsigned arithmetic everywhere and checking that the result is in the 31-bit range? We probably don't need to worry about ever needing full 32-bit support as it would make more sense to provide a 63-bit variant at that point. |
This is an interesting question. Playing around with the API on 64-bit Linux I seem to only be able to get EINVAL as a result. Maybe EOVERFLOW is intended for when the result doesn't fit in an |
Previous checks were trying to validate that file->pos does not become negative. However, the method used for checking this contains possible undefined behaivor (UB) because of the signed integer overflow.
This commit adds stronger checks for offset calculation:
Thoughts: