FIONREAD returns the difference between the file size and the current position in an int. When the difference is outside the int range, the result wraps, so a file with 4 GiB remaining can be reported as empty. Clamp the result to the signed int range before returning it to userspace. Preserve negative counts for file positions past EOF. Signed-off-by: Avi Weiss --- fs/ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ioctl.c b/fs/ioctl.c index 1c152c2b1b67d..ecc2a4cfe6100 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -550,8 +551,8 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd, if (!S_ISREG(inode->i_mode) || IS_ANON_FILE(inode)) return vfs_ioctl(filp, cmd, arg); - return put_user(i_size_read(inode) - filp->f_pos, - (int __user *)argp); + return put_user(clamp_t(loff_t, i_size_read(inode) - filp->f_pos, + INT_MIN, INT_MAX), (int __user *)argp); case FS_IOC_GETFLAGS: return ioctl_getflags(filp, argp); base-commit: 36aad21d50d1af3f6954bb0c988257a908202477 -- 2.43.0