Eryu Guan
161f55efba
xfs: fix use-after-free in xfs_finish_page_writeback
Commit 28b783e47ad7 ("xfs: bufferhead chains are invalid after
end_page_writeback") fixed one use-after-free issue by
pre-calculating the loop conditionals before calling bh->b_end_io()
in the end_io processing loop, but it assigned 'next' pointer before
checking end offset boundary & breaking the loop, at which point the
bh might be freed already, and caused use-after-free.
This is caught by KASAN when running fstests generic/127 on sub-page
block size XFS.
[ 2517.244502] run fstests generic/127 at 2017-04-27 07:30:50
[ 2747.868840] ==================================================================
[ 2747.876949] BUG: KASAN: use-after-free in xfs_destroy_ioend+0x3d3/0x4e0 [xfs] at addr ffff8801395ae698
...
[ 2747.918245] Call Trace:
[ 2747.920975] dump_stack+0x63/0x84
[ 2747.924673] kasan_object_err+0x21/0x70
[ 2747.928950] kasan_report+0x271/0x530
[ 2747.933064] ? xfs_destroy_ioend+0x3d3/0x4e0 [xfs]
[ 2747.938409] ? end_page_writeback+0xce/0x110
[ 2747.943171] __asan_report_load8_noabort+0x19/0x20
[ 2747.948545] xfs_destroy_ioend+0x3d3/0x4e0 [xfs]
[ 2747.953724] xfs_end_io+0x1af/0x2b0 [xfs]
[ 2747.958197] process_one_work+0x5ff/0x1000
[ 2747.962766] worker_thread+0xe4/0x10e0
[ 2747.966946] kthread+0x2d3/0x3d0
[ 2747.970546] ? process_one_work+0x1000/0x1000
[ 2747.975405] ? kthread_create_on_node+0xc0/0xc0
[ 2747.980457] ? syscall_return_slowpath+0xe6/0x140
[ 2747.985706] ? do_page_fault+0x30/0x80
[ 2747.989887] ret_from_fork+0x2c/0x40
[ 2747.993874] Object at ffff8801395ae690, in cache buffer_head size: 104
[ 2748.001155] Allocated:
[ 2748.003782] PID = 8327
[ 2748.006411] save_stack_trace+0x1b/0x20
[ 2748.010688] save_stack+0x46/0xd0
[ 2748.014383] kasan_kmalloc+0xad/0xe0
[ 2748.018370] kasan_slab_alloc+0x12/0x20
[ 2748.022648] kmem_cache_alloc+0xb8/0x1b0
[ 2748.027024] alloc_buffer_head+0x22/0xc0
[ 2748.031399] alloc_page_buffers+0xd1/0x250
[ 2748.035968] create_empty_buffers+0x30/0x410
[ 2748.040730] create_page_buffers+0x120/0x1b0
[ 2748.045493] __block_write_begin_int+0x17a/0x1800
[ 2748.050740] iomap_write_begin+0x100/0x2f0
[ 2748.055308] iomap_zero_range_actor+0x253/0x5c0
[ 2748.060362] iomap_apply+0x157/0x270
[ 2748.064347] iomap_zero_range+0x5a/0x80
[ 2748.068624] iomap_truncate_page+0x6b/0xa0
[ 2748.073227] xfs_setattr_size+0x1f7/0xa10 [xfs]
[ 2748.078312] xfs_vn_setattr_size+0x68/0x140 [xfs]
[ 2748.083589] xfs_file_fallocate+0x4ac/0x820 [xfs]
[ 2748.088838] vfs_fallocate+0x2cf/0x780
[ 2748.093021] SyS_fallocate+0x48/0x80
[ 2748.097006] do_syscall_64+0x18a/0x430
[ 2748.101186] return_from_SYSCALL_64+0x0/0x6a
[ 2748.105948] Freed:
[ 2748.108189] PID = 8327
[ 2748.110816] save_stack_trace+0x1b/0x20
[ 2748.115093] save_stack+0x46/0xd0
[ 2748.118788] kasan_slab_free+0x73/0xc0
[ 2748.122969] kmem_cache_free+0x7a/0x200
[ 2748.127247] free_buffer_head+0x41/0x80
[ 2748.131524] try_to_free_buffers+0x178/0x250
[ 2748.136316] xfs_vm_releasepage+0x2e9/0x3d0 [xfs]
[ 2748.141563] try_to_release_page+0x100/0x180
[ 2748.146325] invalidate_inode_pages2_range+0x7da/0xcf0
[ 2748.152087] xfs_shift_file_space+0x37d/0x6e0 [xfs]
[ 2748.157557] xfs_collapse_file_space+0x49/0x120 [xfs]
[ 2748.163223] xfs_file_fallocate+0x2a7/0x820 [xfs]
[ 2748.168462] vfs_fallocate+0x2cf/0x780
[ 2748.172642] SyS_fallocate+0x48/0x80
[ 2748.176629] do_syscall_64+0x18a/0x430
[ 2748.180810] return_from_SYSCALL_64+0x0/0x6a
Fixed it by checking on offset against end & breaking out first,
dereference bh only if there're still bufferheads to process.
Signed-off-by: Eryu Guan <eguan@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
2017-05-05 12:16:48 -07:00
..
2017-05-03 13:21:40 -07:00
2016-06-21 09:53:44 +10:00
2017-03-07 20:10:50 -08:00
2017-03-07 20:10:50 -08:00
2017-04-03 15:18:17 -07:00
2016-10-10 20:16:43 -07:00
2015-12-06 21:34:16 -05:00
2017-05-05 12:16:48 -07:00
2016-11-30 14:37:15 +11:00
2016-06-01 17:38:15 +10:00
2016-12-05 12:32:14 +11:00
2016-12-05 12:32:14 +11:00
2017-05-03 13:21:40 -07:00
2016-10-04 11:05:44 -07:00
2017-04-25 09:40:41 -07:00
2017-01-30 16:32:25 -08:00
2017-02-03 14:39:07 -08:00
2015-08-25 10:05:13 +10:00
2017-04-25 09:40:42 -07:00
2017-04-25 09:40:42 -07:00
2017-04-25 09:40:40 -07:00
2017-04-27 10:45:34 -07:00
2017-02-09 11:36:40 -08:00
2016-07-22 09:52:35 +10:00
2013-12-13 11:34:08 +11:00
2017-01-17 11:43:38 -08:00
2015-01-09 10:48:58 +11:00
2016-07-20 11:51:08 +10:00
2016-10-05 16:26:31 -07:00
2016-07-15 15:31:29 -04:00
2017-02-16 17:20:12 -08:00
2017-02-09 10:50:25 -08:00
2017-04-25 09:40:42 -07:00
2016-08-03 11:23:49 +10:00
2017-02-27 18:43:46 -08:00
2016-10-03 09:56:28 +11:00
2014-04-23 07:11:52 +10:00
2017-04-25 09:40:41 -07:00
2017-04-03 15:18:17 -07:00
2017-01-30 16:32:24 -08:00
2016-10-05 16:26:27 -07:00
2016-10-05 16:26:28 -07:00
2017-04-28 08:11:08 -07:00
2017-04-28 08:11:08 -07:00
2016-11-28 14:57:42 +11:00
2013-08-12 16:10:35 -05:00
2017-04-25 09:40:42 -07:00
2016-02-09 16:54:58 +11:00
2017-04-12 08:43:23 -07:00
2017-04-28 08:11:08 -07:00
2017-04-03 15:18:17 -07:00
2014-10-02 09:17:58 +10:00
2017-04-25 09:40:42 -07:00
2016-07-20 11:29:35 +10:00
2017-04-06 16:00:39 -07:00
2017-02-06 17:47:46 -08:00
2017-03-02 20:51:15 -05:00
2016-09-22 10:56:19 +02:00
2017-04-03 15:18:15 -07:00
2014-11-07 08:30:30 +11:00
2017-04-12 08:42:51 -07:00
2017-02-09 11:36:40 -08:00
2017-02-09 11:36:40 -08:00
2016-12-07 17:42:30 +11:00
2017-04-25 09:40:42 -07:00
2017-01-30 16:32:25 -08:00
2015-10-12 16:04:45 +11:00
2017-04-28 08:10:53 -07:00
2017-04-25 09:40:41 -07:00
2015-03-25 14:57:53 +11:00
2014-04-23 07:11:51 +10:00
2016-10-03 09:11:18 -07:00
2016-11-30 14:33:25 +11:00
2016-11-30 14:33:25 +11:00
2014-11-28 14:27:09 +11:00
2017-04-28 08:11:08 -07:00
2017-04-25 09:40:42 -07:00
2016-02-08 11:27:55 +11:00
2015-06-01 07:15:37 +10:00
2016-02-08 11:27:38 +11:00
2017-04-25 09:40:42 -07:00
2016-10-03 09:11:21 -07:00
2017-05-03 13:21:40 -07:00
2017-03-07 16:45:58 -08:00
2017-04-25 09:40:42 -07:00
2016-09-19 10:24:27 +10:00
2017-02-17 16:52:52 -08:00
2017-04-03 15:18:17 -07:00
2016-12-05 14:38:58 +11:00
2016-12-05 14:38:58 +11:00
2017-04-03 15:18:15 -07:00
2017-02-09 11:36:40 -08:00
2016-11-30 14:33:25 +11:00
2013-10-08 14:53:02 -05:00
2016-10-05 16:26:28 -07:00
2016-10-05 16:26:28 -07:00
2017-02-16 17:19:15 -08:00
2016-05-18 10:58:51 +10:00
2017-04-03 15:18:17 -07:00
2017-04-25 09:40:42 -07:00
2017-04-25 09:40:42 -07:00
2016-10-04 11:05:44 -07:00
2016-02-10 15:01:11 +11:00
2016-02-08 11:27:55 +11:00
2016-09-19 10:30:52 +10:00
2016-09-27 21:06:22 -04:00
2017-04-25 09:40:42 -07:00
2016-10-03 09:11:22 -07:00
2016-10-05 16:26:29 -07:00
2017-04-06 16:00:11 -07:00
2017-04-06 16:00:11 -07:00
2016-12-05 12:32:14 +11:00