On Mon, Jan 03, 2022 at 08:03:51AM +0100, Jann Horn wrote: > io_prep_rw() grabs file->f_pos; then later, io_read() calls > io_iter_do_read() (which will fail with -EINVAL), and then the error > path goes through kiocb_done(), which writes the position back to > req->file->f_pos. So I think the following race might work: Why does it touch ->f_pos on failure, anyway? It's a bug, plain and simple; note that read(2) and write(2) are explicitly requested to leave IO position alone if they return an error. See e.g. fs/read_write.c:ksys_read() - ret = vfs_read(f.file, buf, count, ppos); if (ret >= 0 && ppos) f.file->f_pos = pos; fdput_pos(f); Position update happens only on success (and only for non-stream files, at that). No matter how special io-uring is (it's not covered by POSIX, for obvious reasons), this is simply wrong, directories or no directories.