Fixed seek undefined behavior on signed integer overflow
In the previous implementation of lfs_file_seek, we calculated the new offset using signed arithmetic before checking for possible overflow/underflow conditions. This results in undefined behavior in C. Fortunately for us, littlefs is now limited to 31-bit file sizes for API reasons, so we don't have to be too clever here. Doing the arithmetic with unsigned integers and just checking if we're in a valid range afterwards should work. Found by m-kostrzewa and lucic71
This commit is contained in:
parent
f1c430e779
commit
abaec45652
16
lfs.c
16
lfs.c
@ -3664,22 +3664,16 @@ static lfs_ssize_t lfs_file_write_(lfs_t *lfs, lfs_file_t *file,
|
||||
static lfs_soff_t lfs_file_seek_(lfs_t *lfs, lfs_file_t *file,
|
||||
lfs_soff_t off, int whence) {
|
||||
// find new pos
|
||||
//
|
||||
// fortunately for us, littlefs is limited to 31-bit file sizes, so we
|
||||
// don't have to worry too much about integer overflow
|
||||
lfs_off_t npos = file->pos;
|
||||
if (whence == LFS_SEEK_SET) {
|
||||
npos = off;
|
||||
} else if (whence == LFS_SEEK_CUR) {
|
||||
if ((lfs_soff_t)file->pos + off < 0) {
|
||||
return LFS_ERR_INVAL;
|
||||
} else {
|
||||
npos = file->pos + off;
|
||||
}
|
||||
npos = file->pos + (lfs_off_t)off;
|
||||
} else if (whence == LFS_SEEK_END) {
|
||||
lfs_soff_t res = lfs_file_size_(lfs, file) + off;
|
||||
if (res < 0) {
|
||||
return LFS_ERR_INVAL;
|
||||
} else {
|
||||
npos = res;
|
||||
}
|
||||
npos = (lfs_off_t)lfs_file_size_(lfs, file) + (lfs_off_t)off;
|
||||
}
|
||||
|
||||
if (npos > lfs->file_max) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user