fs/romfs: reject negative resulting position in romfs_seek()

romfs_seek() clamps the computed position to the file size when it
exceeds rf_size, but never checks for a negative result. lseek(fd,
offset, SEEK_SET/SEEK_CUR/SEEK_END) with an offset that produces a
negative position (e.g. a negative SEEK_SET offset, or a SEEK_CUR/
SEEK_END offset more negative than the current position/file size)
is written straight into filep->f_pos.

The subsequent romfs_read() computes
`rf->rf_startoffset + filep->f_pos` into a uint32_t, so a negative
f_pos wraps around to a huge unsigned offset, and romfs_hwread()'s
XIP path memcpy()s from rm_xipbase plus that offset -- an
out-of-bounds read far past the mapped flash region.

Add the same "if (position < 0) return -EINVAL" guard already used
by fs/fat/fs_fat32.c's seek function, before the existing
end-of-file clamp.

Assisted-by: Claude:claude-sonnet-5
This commit is contained in:
yi chen 2026-07-13 10:58:47 +08:00
parent d75d713165
commit 625562d962

View file

@ -563,6 +563,13 @@ static off_t romfs_seek(FAR struct file *filep, off_t offset, int whence)
goto errout_with_lock;
}
if (position < 0)
{
ferr("ERROR: Invalid position: %jd\n", (intmax_t)position);
ret = -EINVAL;
goto errout_with_lock;
}
/* Limit positions to the end of the file. */
if (position > rf->rf_size)