From bcdd0c1600903e9222abfcde28947406020ccb5d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 22 Nov 2011 11:00:20 +0300 Subject: ext3: NULL dereference in ext3_evict_inode() This is an fsfuzzer bug. ->s_journal is set at the end of ext3_load_journal() but we try to use it in the error handling from ext3_get_journal() while it's still NULL. [ 337.039041] BUG: unable to handle kernel NULL pointer dereference at 0000000000000024 [ 337.040380] IP: [] _raw_spin_lock+0x9/0x30 [ 337.041687] PGD 0 [ 337.043118] Oops: 0002 [#1] SMP [ 337.044483] CPU 3 [ 337.044495] Modules linked in: ecb md4 cifs fuse kvm_intel kvm brcmsmac brcmutil crc8 cordic r8169 [last unloaded: scsi_wait_scan] [ 337.047633] [ 337.049259] Pid: 8308, comm: mount Not tainted 3.2.0-rc2-next-20111121+ #24 SAMSUNG ELECTRONICS CO., LTD. RV411/RV511/E3511/S3511 /RV411/RV511/E3511/S3511 [ 337.051064] RIP: 0010:[] [] _raw_spin_lock+0x9/0x30 [ 337.052879] RSP: 0018:ffff8800b1d11ae8 EFLAGS: 00010282 [ 337.054668] RAX: 0000000000000100 RBX: 0000000000000000 RCX: ffff8800b77c2000 [ 337.056400] RDX: ffff8800a97b5c00 RSI: 0000000000000000 RDI: 0000000000000024 [ 337.058099] RBP: ffff8800b1d11ae8 R08: 6000000000000000 R09: e018000000000000 [ 337.059841] R10: ff67366cc2607c03 R11: 00000000110688e6 R12: 0000000000000000 [ 337.061607] R13: 0000000000000000 R14: 0000000000000000 R15: ffff8800a78f06e8 [ 337.063385] FS: 00007f9d95652800(0000) GS:ffff8800b7180000(0000) knlGS:0000000000000000 [ 337.065110] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 337.066801] CR2: 0000000000000024 CR3: 00000000aef2c000 CR4: 00000000000006e0 [ 337.068581] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 337.070321] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 337.072105] Process mount (pid: 8308, threadinfo ffff8800b1d10000, task ffff8800b1d02be0) [ 337.073800] Stack: [ 337.075487] ffff8800b1d11b08 ffffffff811f48cf ffff88007ac9b158 0000000000000000 [ 337.077255] ffff8800b1d11b38 ffffffff8119405d ffff88007ac9b158 ffff88007ac9b250 [ 337.078851] ffffffff8181bda0 ffffffff8181bda0 ffff8800b1d11b68 ffffffff81131e31 [ 337.080284] Call Trace: [ 337.081706] [] log_start_commit+0x1f/0x40 [ 337.083107] [] ext3_evict_inode+0x1fd/0x2a0 [ 337.084490] [] evict+0xa1/0x1a0 [ 337.085857] [] iput+0x101/0x210 [ 337.087220] [] iget_failed+0x21/0x30 [ 337.088581] [] ext3_iget+0x15c/0x450 [ 337.089936] [] ? ext3_rsv_window_add+0x81/0x100 [ 337.091284] [] ext3_get_journal+0x15/0xde [ 337.092641] [] ext3_fill_super+0xf2b/0x1c30 [ 337.093991] [] ? register_shrinker+0x4d/0x60 [ 337.095332] [] mount_bdev+0x1a2/0x1e0 [ 337.096680] [] ? ext3_setup_super+0x210/0x210 [ 337.098026] [] ext3_mount+0x10/0x20 [ 337.099362] [] mount_fs+0x3e/0x1b0 [ 337.100759] [] ? __alloc_percpu+0xb/0x10 [ 337.102330] [] vfs_kern_mount+0x65/0xc0 [ 337.103889] [] do_kern_mount+0x4f/0x100 [ 337.105442] [] do_mount+0x19c/0x890 [ 337.106989] [] ? memdup_user+0x46/0x90 [ 337.108572] [] ? strndup_user+0x53/0x70 [ 337.110114] [] sys_mount+0x8b/0xe0 [ 337.111617] [] system_call_fastpath+0x16/0x1b [ 337.113133] Code: 38 c2 74 0f 66 0f 1f 44 00 00 f3 90 0f b6 03 38 c2 75 f7 48 83 c4 08 5b 5d c3 0f 1f 84 00 00 00 00 00 55 b8 00 01 00 00 48 89 e5 66 0f c1 07 0f b6 d4 38 c2 74 0c 0f 1f 00 f3 90 0f b6 07 38 [ 337.116588] RIP [] _raw_spin_lock+0x9/0x30 [ 337.118260] RSP [ 337.119998] CR2: 0000000000000024 [ 337.188701] ---[ end trace c36d790becac1615 ]--- Signed-off-by: Dan Carpenter Signed-off-by: Jan Kara --- fs/ext3/inode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'fs/ext3/inode.c') diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 85fe655fe3e0..9da9125ba3ef 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -223,8 +223,12 @@ void ext3_evict_inode (struct inode *inode) * * Note that directories do not have this problem because they don't * use page cache. + * + * The s_journal check handles the case when ext3_get_journal() fails + * and puts the journal inode. */ if (inode->i_nlink && ext3_should_journal_data(inode) && + EXT3_SB(inode->i_sb)->s_journal && (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) { tid_t commit_tid = atomic_read(&ei->i_datasync_tid); journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; -- cgit v1.2.3 From d03e1292c46721f60830c5d2e334966472002ed0 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Mon, 5 Dec 2011 15:55:11 +0800 Subject: ext3: replace ll_rw_block with other functions ll_rw_block() is deprecated. Thus we replace it with other functions. CC: Jan Kara Signed-off-by: Zheng Liu Signed-off-by: Jan Kara --- fs/ext3/inode.c | 14 +++++++------- fs/ext3/namei.c | 9 ++++++--- fs/ext3/super.c | 10 +++++----- 3 files changed, 18 insertions(+), 15 deletions(-) (limited to 'fs/ext3/inode.c') diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 9da9125ba3ef..a8d3217c5cfe 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1136,9 +1136,11 @@ struct buffer_head *ext3_bread(handle_t *handle, struct inode *inode, bh = ext3_getblk(handle, inode, block, create, err); if (!bh) return bh; - if (buffer_uptodate(bh)) + if (bh_uptodate_or_lock(bh)) return bh; - ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh); + get_bh(bh); + bh->b_end_io = end_buffer_read_sync; + submit_bh(READ | REQ_META | REQ_PRIO, bh); wait_on_buffer(bh); if (buffer_uptodate(bh)) return bh; @@ -2068,12 +2070,10 @@ static int ext3_block_truncate_page(struct inode *inode, loff_t from) if (PageUptodate(page)) set_buffer_uptodate(bh); - if (!buffer_uptodate(bh)) { - err = -EIO; - ll_rw_block(READ, 1, &bh); - wait_on_buffer(bh); + if (!bh_uptodate_or_lock(bh)) { + err = bh_submit_read(bh); /* Uhhuh. Read error. Complain and punt. */ - if (!buffer_uptodate(bh)) + if (err) goto unlock; } diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 642dc6d66dfd..337c3f3375c4 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -921,9 +921,12 @@ restart: num++; bh = ext3_getblk(NULL, dir, b++, 0, &err); bh_use[ra_max] = bh; - if (bh) - ll_rw_block(READ | REQ_META | REQ_PRIO, - 1, &bh); + if (bh && !bh_uptodate_or_lock(bh)) { + get_bh(bh); + bh->b_end_io = end_buffer_read_sync; + submit_bh(READ | REQ_META | REQ_PRIO, + bh); + } } } if ((bh = bh_use[ra_ptr++]) == NULL) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 767fa3a2bd17..662cef4569ab 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -2231,11 +2231,11 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, goto out_bdev; } journal->j_private = sb; - ll_rw_block(READ, 1, &journal->j_sb_buffer); - wait_on_buffer(journal->j_sb_buffer); - if (!buffer_uptodate(journal->j_sb_buffer)) { - ext3_msg(sb, KERN_ERR, "I/O error on journal device"); - goto out_journal; + if (!bh_uptodate_or_lock(journal->j_sb_buffer)) { + if (bh_submit_read(journal->j_sb_buffer)) { + ext3_msg(sb, KERN_ERR, "I/O error on journal device"); + goto out_journal; + } } if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { ext3_msg(sb, KERN_ERR, -- cgit v1.2.3 From 33c104d415e92a51aaf638dc3d93920cfa601e5c Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 22 Dec 2011 16:49:05 +0100 Subject: ext3: Don't warn from writepage when readonly inode is spotted after error WARN_ON_ONCE(IS_RDONLY(inode)) tends to trip when filesystem hits error and is remounted read-only. This unnecessarily scares users (well, they should be scared because of filesystem error, but the stack trace distracts them from the right source of their fear ;-). We could as well just remove the WARN_ON but it's not hard to fix it to not trip on filesystem with errors and not use more cycles in the common case so that's what we do. CC: stable@kernel.org Signed-off-by: Jan Kara --- fs/ext3/inode.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'fs/ext3/inode.c') diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a8d3217c5cfe..fbf6599a1ce6 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -1623,7 +1623,13 @@ static int ext3_ordered_writepage(struct page *page, int err; J_ASSERT(PageLocked(page)); - WARN_ON_ONCE(IS_RDONLY(inode)); + /* + * We don't want to warn for emergency remount. The condition is + * ordered to avoid dereferencing inode->i_sb in non-error case to + * avoid slow-downs. + */ + WARN_ON_ONCE(IS_RDONLY(inode) && + !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); /* * We give up here if we're reentered, because it might be for a @@ -1698,7 +1704,13 @@ static int ext3_writeback_writepage(struct page *page, int err; J_ASSERT(PageLocked(page)); - WARN_ON_ONCE(IS_RDONLY(inode)); + /* + * We don't want to warn for emergency remount. The condition is + * ordered to avoid dereferencing inode->i_sb in non-error case to + * avoid slow-downs. + */ + WARN_ON_ONCE(IS_RDONLY(inode) && + !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); if (ext3_journal_current_handle()) goto out_fail; @@ -1741,7 +1753,13 @@ static int ext3_journalled_writepage(struct page *page, int err; J_ASSERT(PageLocked(page)); - WARN_ON_ONCE(IS_RDONLY(inode)); + /* + * We don't want to warn for emergency remount. The condition is + * ordered to avoid dereferencing inode->i_sb in non-error case to + * avoid slow-downs. + */ + WARN_ON_ONCE(IS_RDONLY(inode) && + !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS)); if (ext3_journal_current_handle()) goto no_write; -- cgit v1.2.3 From 302bf2f3259948c93361d501b04a5ed69c3bd4f8 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 4 Jan 2012 15:59:47 -0500 Subject: ext2/3/4: delete unneeded includes of module.h Delete any instances of include module.h that were not strictly required. In the case of ext2, the declaration of MODULE_LICENSE etc. were in inode.c but the module_init/exit were in super.c, so relocate the MODULE_LICENCE/AUTHOR block to super.c which makes it consistent with ext3 and ext4 at the same time. Signed-off-by: Paul Gortmaker Signed-off-by: Jan Kara --- fs/ext2/inode.c | 5 ----- fs/ext2/super.c | 3 +++ fs/ext2/xattr.c | 1 - fs/ext2/xattr_security.c | 1 - fs/ext2/xattr_trusted.c | 1 - fs/ext2/xattr_user.c | 1 - fs/ext3/inode.c | 1 - fs/ext3/xattr_security.c | 1 - fs/ext3/xattr_trusted.c | 1 - fs/ext3/xattr_user.c | 1 - fs/ext4/block_validity.c | 1 - fs/ext4/extents.c | 1 - fs/ext4/indirect.c | 1 - fs/ext4/inode.c | 1 - fs/ext4/migrate.c | 1 - fs/ext4/page-io.c | 1 - fs/ext4/xattr_security.c | 1 - fs/ext4/xattr_trusted.c | 1 - fs/ext4/xattr_user.c | 1 - 19 files changed, 3 insertions(+), 22 deletions(-) (limited to 'fs/ext3/inode.c') diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 91a6945af6d8..740cad8dcd8d 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -36,10 +35,6 @@ #include "acl.h" #include "xip.h" -MODULE_AUTHOR("Remy Card and others"); -MODULE_DESCRIPTION("Second Extended Filesystem"); -MODULE_LICENSE("GPL"); - static int __ext2_write_inode(struct inode *inode, int do_sync); /* diff --git a/fs/ext2/super.c b/fs/ext2/super.c index bd8ac164a3bf..9e7e203146b1 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1521,5 +1521,8 @@ static void __exit exit_ext2_fs(void) exit_ext2_xattr(); } +MODULE_AUTHOR("Remy Card and others"); +MODULE_DESCRIPTION("Second Extended Filesystem"); +MODULE_LICENSE("GPL"); module_init(init_ext2_fs) module_exit(exit_ext2_fs) diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index d27b71f1d183..6dcafc7efdfd 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -54,7 +54,6 @@ */ #include -#include #include #include #include diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index c922adc8ef41..be7a8d02c9a7 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c @@ -3,7 +3,6 @@ * Handler for storing security labels as extended attributes. */ -#include #include #include #include diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index 667e46a8d62d..2989467d3595 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c @@ -5,7 +5,6 @@ * Copyright (C) 2003 by Andreas Gruenbacher, */ -#include #include #include #include diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 099d20f47163..f470e44c4b8d 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c @@ -6,7 +6,6 @@ */ #include -#include #include #include "ext2.h" #include "xattr.h" diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index fbf6599a1ce6..261979feb4b5 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -22,7 +22,6 @@ * Assorted race fixes, rewrite of ext3_get_block() by Al Viro, 2000 */ -#include #include #include #include diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 3c218b8a51d4..ea26f2acab94 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c @@ -3,7 +3,6 @@ * Handler for storing security labels as extended attributes. */ -#include #include #include #include diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index dc8edda9ffe0..2526a8829de8 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c @@ -5,7 +5,6 @@ * Copyright (C) 2003 by Andreas Gruenbacher, */ -#include #include #include #include diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index 7a321974d584..b32e473a1e33 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c @@ -5,7 +5,6 @@ * Copyright (C) 2001 by Andreas Gruenbacher, */ -#include #include #include #include diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 8efb2f0a3447..3f11656bd72e 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 61fa9e1614af..130ffe4818fa 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -29,7 +29,6 @@ * - smart tree reduction */ -#include #include #include #include diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index 3cfc73fbca8e..830e1b2bf145 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -20,7 +20,6 @@ * (sct@redhat.com), 1993, 1998 */ -#include #include "ext4_jbd2.h" #include "truncate.h" diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 240f6e2dc7ee..e53858033368 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -18,7 +18,6 @@ * Assorted race fixes, rewrite of ext4_get_block() by Al Viro, 2000 */ -#include #include #include #include diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 16ac228dbec6..e7d6bb0acfa6 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c @@ -12,7 +12,6 @@ * */ -#include #include #include "ext4_jbd2.h" diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 7ce1d0b19c94..b1758538b3b5 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -6,7 +6,6 @@ * Written by Theodore Ts'o, 2010. */ -#include #include #include #include diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index 34e4350dd4d9..b60f9f81e33c 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c @@ -3,7 +3,6 @@ * Handler for storing security labels as extended attributes. */ -#include #include #include #include diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index 37e6ebca2cc3..95f1f4ab59a4 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c @@ -5,7 +5,6 @@ * Copyright (C) 2003 by Andreas Gruenbacher, */ -#include #include #include #include diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index 98c375352d0e..0edb7611ffbe 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c @@ -5,7 +5,6 @@ * Copyright (C) 2001 by Andreas Gruenbacher, */ -#include #include #include #include "ext4_jbd2.h" -- cgit v1.2.3