Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932899AbcCKQfu (ORCPT ); Fri, 11 Mar 2016 11:35:50 -0500 Received: from mail-oi0-f41.google.com ([209.85.218.41]:33649 "EHLO mail-oi0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932809AbcCKQfm (ORCPT ); Fri, 11 Mar 2016 11:35:42 -0500 From: Seth Forshee To: Miklos Szeredi Cc: m.loschwitz@syseleven.de, robert@quobyte.com, seth.forshee@canonical.com, fuse-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] fuse: do not use iocb after it may have been freed Date: Fri, 11 Mar 2016 10:35:33 -0600 Message-Id: <1457714135-50289-2-git-send-email-seth.forshee@canonical.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1457714135-50289-1-git-send-email-seth.forshee@canonical.com> References: <1457714135-50289-1-git-send-email-seth.forshee@canonical.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10362 Lines: 177 From: Robert Doebbelin 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: [] dump_stack+0x45/0x57 kernel: [] print_trailer+0xf9/0x150 kernel: [] object_err+0x38/0x50 kernel: [] kasan_report_error+0x1e8/0x3f0 kernel: [] ? kasan_slab_free+0x44/0x50 kernel: [] __asan_report_load8_noabort+0x61/0x70 kernel: [] ? fuse_direct_IO+0xb1a/0xcc0 kernel: [] fuse_direct_IO+0xb1a/0xcc0 kernel: [] ? fuse_direct_write_iter+0x1f0/0x1f0 kernel: [] ? SyS_pselect6+0x460/0x460 kernel: [] ? cap_inode_need_killpriv+0x8e/0xb0 kernel: [] generic_file_direct_write+0x246/0x540 kernel: [] ? file_remove_privs+0xfd/0x270 kernel: [] ? generic_file_read_iter+0x1090/0x1090 kernel: [] ? __sb_start_write+0x10a/0x2d0 kernel: [] ? __sb_end_write+0xc0/0xc0 kernel: [] fuse_file_write_iter+0x31c/0x780 kernel: [] ? aa_file_perm+0x24d/0xa00 kernel: [] aio_run_iocb+0x68a/0x870 kernel: [] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [] ? fuse_perform_write+0xe80/0xe80 kernel: [] ? aio_complete+0xcb0/0xcb0 kernel: [] ? eventfd_ctx_read+0xda/0x6d0 kernel: [] ? eventfd_write+0x6e0/0x6e0 kernel: [] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [] ? wake_up_q+0xe0/0xe0 kernel: [] ? __fsnotify_inode_delete+0x10/0x10 kernel: [] ? __fget_light+0x7e/0x1f0 kernel: [] ? kasan_slab_alloc+0xd/0x10 kernel: [] do_io_submit+0x4a7/0xb40 kernel: [] ? SyS_io_destroy+0x200/0x200 kernel: [] ? do_sendfile+0x1280/0x1280 kernel: [] SyS_io_submit+0x10/0x20 kernel: [] 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: [] dump_stack+0x45/0x57 kernel: [] print_trailer+0xf9/0x150 kernel: [] object_err+0x38/0x50 kernel: [] kasan_report_error+0x1e8/0x3f0 kernel: [] ? kasan_slab_free+0x44/0x50 kernel: [] __asan_report_load8_noabort+0x61/0x70 kernel: [] ? fuse_direct_IO+0xb1a/0xcc0 kernel: [] fuse_direct_IO+0xb1a/0xcc0 kernel: [] ? fuse_direct_write_iter+0x1f0/0x1f0 kernel: [] ? cap_inode_need_killpriv+0x8e/0xb0 kernel: [] generic_file_direct_write+0x246/0x540 kernel: [] ? file_remove_privs+0xfd/0x270 kernel: [] ? generic_file_read_iter+0x1090/0x1090 kernel: [] ? __sb_start_write+0x10a/0x2d0 kernel: [] ? __sb_end_write+0xc0/0xc0 kernel: [] fuse_file_write_iter+0x31c/0x780 kernel: [] aio_run_iocb+0x68a/0x870 kernel: [] ? poll_select_copy_remaining+0x3a0/0x3a0 kernel: [] ? fuse_perform_write+0xe80/0xe80 kernel: [] ? aio_complete+0xcb0/0xcb0 kernel: [] ? should_numa_migrate_memory+0xfd/0x410 kernel: [] ? mpol_misplaced+0x393/0x520 kernel: [] ? __fget_light+0x7e/0x1f0 kernel: [] ? kasan_slab_alloc+0xd/0x10 kernel: [] do_io_submit+0x4a7/0xb40 kernel: [] ? SyS_io_destroy+0x200/0x200 kernel: [] ? do_sendfile+0x1280/0x1280 kernel: [] SyS_io_submit+0x10/0x20 kernel: [] 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: stable@vger.kernel.org # 3.10+ Signed-off-by: Robert Doebbelin --- 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