From: Greg Kroah-Hartman Date: Sat, 7 Feb 2015 08:55:59 +0000 (+0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.69~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a2ba38772fd230286a82d379b231a70059981d9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: ext4-prevent-bugon-on-race-between-write-fcntl.patch --- diff --git a/queue-3.10/ext4-prevent-bugon-on-race-between-write-fcntl.patch b/queue-3.10/ext4-prevent-bugon-on-race-between-write-fcntl.patch new file mode 100644 index 00000000000..6095c803c43 --- /dev/null +++ b/queue-3.10/ext4-prevent-bugon-on-race-between-write-fcntl.patch @@ -0,0 +1,120 @@ +From a41537e69b4aa43f0fea02498c2595a81267383b Mon Sep 17 00:00:00 2001 +From: Dmitry Monakhov +Date: Thu, 30 Oct 2014 10:53:16 -0400 +Subject: ext4: prevent bugon on race between write/fcntl + +From: Dmitry Monakhov + +commit a41537e69b4aa43f0fea02498c2595a81267383b upstream. + +O_DIRECT flags can be toggeled via fcntl(F_SETFL). But this value checked +twice inside ext4_file_write_iter() and __generic_file_write() which +result in BUG_ON inside ext4_direct_IO. + +Let's initialize iocb->private unconditionally. + +TESTCASE: xfstest:generic/036 https://patchwork.ozlabs.org/patch/402445/ + +#TYPICAL STACK TRACE: +kernel BUG at fs/ext4/inode.c:2960! +invalid opcode: 0000 [#1] SMP +Modules linked in: brd iTCO_wdt lpc_ich mfd_core igb ptp dm_mirror dm_region_hash dm_log dm_mod +CPU: 6 PID: 5505 Comm: aio-dio-fcntl-r Not tainted 3.17.0-rc2-00176-gff5c017 #161 +Hardware name: Intel Corporation W2600CR/W2600CR, BIOS SE5C600.86B.99.99.x028.061320111235 06/13/2011 +task: ffff88080e95a7c0 ti: ffff88080f908000 task.ti: ffff88080f908000 +RIP: 0010:[] [] ext4_direct_IO+0x162/0x3d0 +RSP: 0018:ffff88080f90bb58 EFLAGS: 00010246 +RAX: 0000000000000400 RBX: ffff88080fdb2a28 RCX: 00000000a802c818 +RDX: 0000040000080000 RSI: ffff88080d8aeb80 RDI: 0000000000000001 +RBP: ffff88080f90bbc8 R08: 0000000000000000 R09: 0000000000001581 +R10: 0000000000000000 R11: 0000000000000000 R12: ffff88080d8aeb80 +R13: ffff88080f90bbf8 R14: ffff88080fdb28c8 R15: ffff88080fdb2a28 +FS: 00007f23b2055700(0000) GS:ffff880818400000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f23b2045000 CR3: 000000080cedf000 CR4: 00000000000407e0 +Stack: + ffff88080f90bb98 0000000000000000 7ffffffffffffffe ffff88080fdb2c30 + 0000000000000200 0000000000000200 0000000000000001 0000000000000200 + ffff88080f90bbc8 ffff88080fdb2c30 ffff88080f90be08 0000000000000200 +Call Trace: + [] generic_file_direct_write+0xed/0x180 + [] __generic_file_write_iter+0x222/0x370 + [] ext4_file_write_iter+0x34b/0x400 + [] ? aio_run_iocb+0x239/0x410 + [] ? aio_run_iocb+0x239/0x410 + [] ? local_clock+0x25/0x30 + [] ? __lock_acquire+0x274/0x700 + [] ? ext4_unwritten_wait+0xb0/0xb0 + [] aio_run_iocb+0x286/0x410 + [] ? local_clock+0x25/0x30 + [] ? lock_release_holdtime+0x29/0x190 + [] ? lookup_ioctx+0x4b/0xf0 + [] do_io_submit+0x55b/0x740 + [] ? do_io_submit+0x3ca/0x740 + [] SyS_io_submit+0x10/0x20 + [] system_call_fastpath+0x16/0x1b +Code: 01 48 8b 80 f0 01 00 00 48 8b 18 49 8b 45 10 0f 85 f1 01 00 00 48 03 45 c8 48 3b 43 48 0f 8f e3 01 00 00 49 83 7c +24 18 00 75 04 <0f> 0b eb fe f0 ff 83 ec 01 00 00 49 8b 44 24 18 8b 00 85 c0 89 +RIP [] ext4_direct_IO+0x162/0x3d0 + RSP + +Reported-by: Sasha Levin +Signed-off-by: Theodore Ts'o +Signed-off-by: Dmitry Monakhov +[hujianyang: Backported to 3.10 + - Move initialization of iocb->private to ext4_file_write() as we don't + have ext4_file_write_iter(), which is introduced by commit 9b884164. + - Adjust context to make 'overwrite' changes apply to ext4_file_dio_write() + as ext4_file_dio_write() is not move into ext4_file_write()] +Signed-off-by: hujianyang +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/file.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/fs/ext4/file.c ++++ b/fs/ext4/file.c +@@ -100,7 +100,7 @@ ext4_file_dio_write(struct kiocb *iocb, + struct blk_plug plug; + int unaligned_aio = 0; + ssize_t ret; +- int overwrite = 0; ++ int *overwrite = iocb->private; + size_t length = iov_length(iov, nr_segs); + + if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS) && +@@ -118,8 +118,6 @@ ext4_file_dio_write(struct kiocb *iocb, + mutex_lock(&inode->i_mutex); + blk_start_plug(&plug); + +- iocb->private = &overwrite; +- + /* check whether we do a DIO overwrite or not */ + if (ext4_should_dioread_nolock(inode) && !unaligned_aio && + !file->f_mapping->nrpages && pos + length <= i_size_read(inode)) { +@@ -143,7 +141,7 @@ ext4_file_dio_write(struct kiocb *iocb, + * So we should check these two conditions. + */ + if (err == len && (map.m_flags & EXT4_MAP_MAPPED)) +- overwrite = 1; ++ *overwrite = 1; + } + + ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); +@@ -170,6 +168,7 @@ ext4_file_write(struct kiocb *iocb, cons + { + struct inode *inode = file_inode(iocb->ki_filp); + ssize_t ret; ++ int overwrite = 0; + + /* + * If we have encountered a bitmap-format file, the size limit +@@ -190,6 +189,7 @@ ext4_file_write(struct kiocb *iocb, cons + } + } + ++ iocb->private = &overwrite; + if (unlikely(iocb->ki_filp->f_flags & O_DIRECT)) + ret = ext4_file_dio_write(iocb, iov, nr_segs, pos); + else diff --git a/queue-3.10/series b/queue-3.10/series index 254b248f475..7552c5c5d68 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -8,3 +8,4 @@ mm-pagewalk-call-pte_hole-for-vm_pfnmap-during-walk_page_range.patch lib-checksum.c-fix-carry-in-csum_tcpudp_nofold.patch nilfs2-fix-deadlock-of-segment-constructor-over-i_sync-flag.patch arm64-fix-up-proc-cpuinfo.patch +ext4-prevent-bugon-on-race-between-write-fcntl.patch