From: Robert Doebbelin <rob...@quobyte.com> Reading wrong data may cause the IO thread to starve waiting for completion. The issue was introduced with commit 04b2fa9 and thus affects kernel >= 4.1. It was discovered by KASan:
kernel: ================================================================== kernel: BUG: KASan: use after free in fuse_direct_IO+0xb1a/0xcc0 at addr ffff88036c414390 kernel: Read of size 8 by task qemu-system-x86/2784 kernel: ============================================================================= kernel: BUG kmalloc-128 (Tainted: G I ): kasan: bad access detected kernel: ----------------------------------------------------------------------------- kernel: Disabling lock debugging due to kernel taint kernel: INFO: Slab 0xffffea000db10500 objects=32 used=26 fp=0xffff88036c414e80 flags=0x2ffff0000000080 kernel: INFO: Object 0xffff88036c414380 @offset=896 fp=0x (null) kernel: Bytes b4 ffff88036c414370: 18 00 00 00 40 27 a3 1f 3b 56 00 00 00 00 00 00 ....@'..;V...... kernel: Object ffff88036c414380: 00 00 00 00 00 00 00 00 00 f0 75 35 00 00 00 00 ..........u5.... kernel: Object ffff88036c414390: 80 27 67 81 ff ff ff ff 00 00 00 00 00 00 00 00 .'g............. kernel: Object ffff88036c4143a0: 05 00 00 00 00 00 00 00 80 82 44 ad 05 88 ff ff ..........D..... kernel: Object ffff88036c4143b0: 00 00 00 00 00 00 00 00 10 e1 bc 56 49 56 00 00 ...........VIV.. kernel: Object ffff88036c4143c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: Object ffff88036c4143d0: 00 00 00 00 00 00 00 00 80 f6 85 6d 03 88 ff ff ...........m.... kernel: Object ffff88036c4143e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: Object ffff88036c4143f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: CPU: 0 PID: 2784 Comm: qemu-system-x86 Tainted: G B I 4.2.0-25-generic 0000030 kernel: Hardware name: IBM System x3550 M2 -[794654G]-/49Y6512 , BIOS -[D6E131CUS-1.05]- 11/25/2009 kernel: ffff88036c414380 00000000d939cde9 ffff8805adf0f7c8 ffffffff828cafee kernel: 0000000000000080 ffff880373803680 ffff8805adf0f7f8 ffffffff81546759 kernel: ffff880373803680 ffffea000db10500 ffff88036c414380 ffff8805ad56d600 kernel: Call Trace: kernel: [<ffffffff828cafee>] dump_stack+0x45/0x57 kernel: [<ffffffff81546759>] print_trailer+0xf9/0x150 kernel: [<ffffffff8154b9c8>] object_err+0x38/0x50 kernel: [<ffffffff8154e3d8>] kasan_report_error+0x1e8/0x3f0 kernel: [<ffffffff8154de94>] ? kasan_slab_free+0x44/0x50 kernel: [<ffffffff8154e791>] __asan_report_load8_noabort+0x61/0x70 kernel: [<ffffffff818d8bfa>] ? fuse_direct_IO+0xb1a/0xcc0 kernel: [<ffffffff818d8bfa>] fuse_direct_IO+0xb1a/0xcc0 kernel: [<ffffffff818d80e0>] ? fuse_direct_write_iter+0x1f0/0x1f0 kernel: [<ffffffff815d1d90>] ? SyS_pselect6+0x460/0x460 kernel: [<ffffffff8193528e>] ? cap_inode_need_killpriv+0x8e/0xb0 kernel: [<ffffffff8145eda6>] generic_file_direct_write+0x246/0x540 kernel: [<ffffffff815e1ced>] ? file_remove_privs+0xfd/0x270 kernel: [<ffffffff8145eb60>] ? generic_file_read_iter+0x1090/0x1090 kernel: [<ffffffff8159beaa>] ? __sb_start_write+0x10a/0x2d0 kernel: [<ffffffff8159bda0>] ? __sb_end_write+0xc0/0xc0 kernel: [<ffffffff818da16c>] fuse_file_write_iter+0x31c/0x780 kernel: [<ffffffff81a0e91d>] ? aa_file_perm+0x24d/0xa00 kernel: [<ffffffff81673aba>] aio_run_iocb+0x68a/0x870 kernel: [<ffffffff815cfa80>] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [<ffffffff818d9e50>] ? fuse_perform_write+0xe80/0xe80 kernel: [<ffffffff81673430>] ? aio_complete+0xcb0/0xcb0 kernel: [<ffffffff8166f52a>] ? eventfd_ctx_read+0xda/0x6d0 kernel: [<ffffffff8166f450>] ? eventfd_write+0x6e0/0x6e0 kernel: [<ffffffff815cfa80>] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [<ffffffff811d3280>] ? wake_up_q+0xe0/0xe0 kernel: [<ffffffff81652110>] ? __fsnotify_inode_delete+0x10/0x10 kernel: [<ffffffff815e872e>] ? __fget_light+0x7e/0x1f0 kernel: [<ffffffff8154de4d>] ? kasan_slab_alloc+0xd/0x10 kernel: [<ffffffff81676567>] do_io_submit+0x4a7/0xb40 kernel: [<ffffffff816760c0>] ? SyS_io_destroy+0x200/0x200 kernel: [<ffffffff81597fc0>] ? do_sendfile+0x1280/0x1280 kernel: [<ffffffff81676c10>] SyS_io_submit+0x10/0x20 kernel: [<ffffffff828dc632>] entry_SYSCALL_64_fastpath+0x16/0x75 kernel: Memory state around the buggy address: kernel: ffff88036c414280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: ffff88036c414300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 kernel: >ffff88036c414380: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: ^ kernel: ffff88036c414400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 kernel: ffff88036c414480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc kernel: ================================================================== kernel: ================================================================== kernel: BUG: KASan: use after free in fuse_direct_IO+0xb1a/0xcc0 at addr ffff88054c8ad210 kernel: Read of size 8 by task qemu-system-x86/2747 kernel: ============================================================================= kernel: BUG kmalloc-128 (Tainted: G B I ): kasan: bad access detected kernel: ----------------------------------------------------------------------------- kernel: INFO: Slab 0xffffea0015322b40 objects=32 used=10 fp=0xffff88054c8ad200 flags=0x6ffff0000000080 kernel: INFO: Object 0xffff88054c8ad200 @offset=512 fp=0xffff88054c8ade00 kernel: Bytes b4 ffff88054c8ad1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: Object ffff88054c8ad200: 00 de 8a 4c 05 88 ff ff 00 00 12 07 00 00 00 00 ...L............ kernel: Object ffff88054c8ad210: 80 27 67 81 ff ff ff ff 00 00 00 00 00 00 00 00 .'g............. kernel: Object ffff88054c8ad220: 05 00 00 00 00 00 00 00 00 80 44 ad 05 88 ff ff ..........D..... kernel: Object ffff88054c8ad230: 00 00 00 00 00 00 00 00 90 a3 6e 75 94 55 00 00 ..........nu.U.. kernel: Object ffff88054c8ad240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: Object ffff88054c8ad250: 00 00 00 00 00 00 00 00 00 ed 81 ae 05 88 ff ff ................ kernel: Object ffff88054c8ad260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: Object ffff88054c8ad270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ kernel: CPU: 3 PID: 2747 Comm: qemu-system-x86 Tainted: G B I 4.2.0-25-generic 0000030 kernel: Hardware name: IBM System x3550 M2 -[794654G]-/49Y6512 , BIOS -[D6E131CUS-1.05]- 11/25/2009 kernel: ffff88054c8ad200 000000005e8ba930 ffff880371aef7c8 ffffffff828cafee kernel: 0000000000000080 ffff880373803680 ffff880371aef7f8 ffffffff81546759 kernel: ffff880373803680 ffffea0015322b40 ffff88054c8ad200 ffff8805aa4d1e00 kernel: Call Trace: kernel: [<ffffffff828cafee>] dump_stack+0x45/0x57 kernel: [<ffffffff81546759>] print_trailer+0xf9/0x150 kernel: [<ffffffff8154b9c8>] object_err+0x38/0x50 kernel: [<ffffffff8154e3d8>] kasan_report_error+0x1e8/0x3f0 kernel: [<ffffffff8154de94>] ? kasan_slab_free+0x44/0x50 kernel: [<ffffffff8154e791>] __asan_report_load8_noabort+0x61/0x70 kernel: [<ffffffff818d8bfa>] ? fuse_direct_IO+0xb1a/0xcc0 kernel: [<ffffffff818d8bfa>] fuse_direct_IO+0xb1a/0xcc0 kernel: [<ffffffff818d80e0>] ? fuse_direct_write_iter+0x1f0/0x1f0 kernel: [<ffffffff8193528e>] ? cap_inode_need_killpriv+0x8e/0xb0 kernel: [<ffffffff8145eda6>] generic_file_direct_write+0x246/0x540 kernel: [<ffffffff815e1ced>] ? file_remove_privs+0xfd/0x270 kernel: [<ffffffff8145eb60>] ? generic_file_read_iter+0x1090/0x1090 kernel: [<ffffffff8159beaa>] ? __sb_start_write+0x10a/0x2d0 kernel: [<ffffffff8159bda0>] ? __sb_end_write+0xc0/0xc0 kernel: [<ffffffff818da16c>] fuse_file_write_iter+0x31c/0x780 kernel: [<ffffffff81673aba>] aio_run_iocb+0x68a/0x870 kernel: [<ffffffff815cfa80>] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [<ffffffff818d9e50>] ? fuse_perform_write+0xe80/0xe80 kernel: [<ffffffff81673430>] ? aio_complete+0xcb0/0xcb0 kernel: [<ffffffff8120390d>] ? should_numa_migrate_memory+0xfd/0x410 kernel: [<ffffffff8153a963>] ? mpol_misplaced+0x393/0x520 kernel: [<ffffffff815e872e>] ? __fget_light+0x7e/0x1f0 kernel: [<ffffffff8154de4d>] ? kasan_slab_alloc+0xd/0x10 kernel: [<ffffffff81676567>] do_io_submit+0x4a7/0xb40 kernel: [<ffffffff816760c0>] ? SyS_io_destroy+0x200/0x200 kernel: [<ffffffff81597fc0>] ? do_sendfile+0x1280/0x1280 kernel: [<ffffffff81676c10>] SyS_io_submit+0x10/0x20 kernel: [<ffffffff828dc632>] entry_SYSCALL_64_fastpath+0x16/0x75 kernel: Memory state around the buggy address: kernel: ffff88054c8ad100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: ffff88054c8ad180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: >ffff88054c8ad200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: ^ kernel: ffff88054c8ad280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb kernel: ffff88054c8ad300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc kernel: ================================================================== Fixes: bcba24ccdc82 ("fuse: enable asynchronous processing direct IO") Cc: sta...@vger.kernel.org # 3.10+ Signed-off-by: Robert Doebbelin <rob...@quobyte.com> --- fs/fuse/file.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index b03d253ece15..34a23df361ca 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2843,6 +2843,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) loff_t i_size; size_t count = iov_iter_count(iter); struct fuse_io_priv *io; + bool is_sync = is_sync_kiocb(iocb); pos = offset; inode = file->f_mapping->host; @@ -2882,11 +2883,11 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) * to wait on real async I/O requests, so we must submit this request * synchronously. */ - if (!is_sync_kiocb(iocb) && (offset + count > i_size) && + if (!is_sync && (offset + count > i_size) && iov_iter_rw(iter) == WRITE) io->async = false; - if (io->async && is_sync_kiocb(iocb)) + if (io->async && is_sync) io->done = &wait; if (iov_iter_rw(iter) == WRITE) { @@ -2900,7 +2901,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset) fuse_aio_complete(io, ret < 0 ? ret : 0, -1); /* we have a non-extending, async request, so return */ - if (!is_sync_kiocb(iocb)) + if (!is_sync) return -EIOCBQUEUED; wait_for_completion(&wait); -- 1.9.1