[PATCH 0/2] fs: honor FOP_UNSIGNED_OFFSET in llseek and positional I/O
From: Stian Halseth
Date: Thu Sep 17 2026 - 12:26:01 EST
Two generic VFS bugs found while fixing pldd(1) on sparc64, where
userspace is mapped above 2^63 so file positions on /proc/PID/mem have
the top bit set.
FOP_UNSIGNED_OFFSET declares a file's offsets unsigned, and vfs_llseek(),
rw_verify_area() and the mmap path honor it. Two sets of syscall
wrappers do not:
1. sys_llseek() takes a negative result from vfs_llseek() for an error
and returns it truncated to int without filling *result.
2. pread64/pwrite64/preadv/pwritev reject a negative position before
looking up the file.
Both patches only change behavior for a file with FOP_UNSIGNED_OFFSET
and a position with the top bit set. Today that is /proc/PID/mem,
/dev/mem, the sparc ADI driver and the DRM/accel device files; for all
of them lseek() followed by read() at that position already works, so
the wrappers now match it.
Tested on an UltraSPARC T4: pread(), preadv(), pwrite(), pwritev() and
lseek() on /proc/PID/mem at positions above 2^63 return the correct data
and offset; a negative position on a regular file or a pipe still fails
with EINVAL and position 0 on a pipe with ESPIPE, as before; and the
stock pldd(1) works again. On other architectures the change is a no-op
for every file without FOP_UNSIGNED_OFFSET, and userspace addresses
never set the top bit, so the new paths are only reachable by passing
a bogus position to /proc/PID/mem or /dev/mem, which then fails in the
driver instead of the wrapper.
The glibc side is https://sourceware.org/bugzilla/show_bug.cgi?id=34641;
Stian Halseth (2):
fs: fix llseek() result for files with unsigned offsets
fs: allow positional I/O on files with unsigned offsets
fs/read_write.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
--
2.43.0