-
Notifications
You must be signed in to change notification settings - Fork 797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add stronger checks for offset in seek #1017
base: master
Are you sure you want to change the base?
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: