e.g the following test program fails for me on 4.10, but works on 4.9: #include <string.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char* argv[]) { char buf1[512]; char buf2[512]; int fd; fd = open("/proc/mounts", O_RDONLY); if (read(fd, buf1, 0) < 0) return 1; if (read(fd, buf1, sizeof buf1) < 0) return 1; lseek(fd, 0, SEEK_SET); if (read(fd, buf2, sizeof buf2) < 0) return 1; return strcmp(buf1, buf2) != 0; } strace shows that the read after a 0 read repeats the first line $ strace -s 222 ./a.out execve("./a.out", ["./a.out"], [/* 33 vars */]) = 0 set_tid_address(0x4110a8) = 5025 openat(AT_FDCWD, "/proc/mounts", O_RDONLY|0x20000) = 3 read(3, "", 0) = 0 read(3, "sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\nsysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\nproc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\nudev /dev devtmpfs rw,nosuid,relatime,size=16435904k,nr_inodes=4"..., 512) = 512 lseek(3, 0, SEEK_SET) = 0 read(3, "sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\nproc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\nudev /dev devtmpfs rw,nosuid,relatime,size=16435904k,nr_inodes=4108976,mode=755 0 0\ndevpts /dev/pts devpts rw,nosuid,"..., 512) = 512 exit_group(1) = ? +++ exited with 1 +++ i suspect this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e522751d605d99a81508e58390a8f51ee96fb662 but i cannot rebuild the kernel here to verify.
strcmp in the test should be memcmp(buf1,buf2,300) or similar, my bad. forgot to mention that this affects musl libc based userspace as it uses readv in its stdio where the first iov buf can have 0 length which exhibit the same broken behaviour.