1. 22 5月, 2019 23 次提交
    • K
      pstore: Centralize init/exit routines · f4bf101b
      Kees Cook 提交于
      commit cb095afd44768bf495894b9ad063bd078e4bb201 upstream.
      
      In preparation for having additional actions during init/exit, this moves
      the init/exit into platform.c, centralizing the logic to make call outs
      to the fs init/exit.
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Tested-by: NGuenter Roeck <groeck@chromium.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f4bf101b
    • C
      jbd2: fix potential double free · 5b856768
      Chengguang Xu 提交于
      commit 0d52154bb0a700abb459a2cbce0a30fc2549b67e upstream.
      
      When failing from creating cache jbd2_inode_cache, we will destroy the
      previously created cache jbd2_handle_cache twice.  This patch fixes
      this by moving each cache initialization/destruction to its own
      separate, individual function.
      Signed-off-by: NChengguang Xu <cgxu519@gmail.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      5b856768
    • J
      ext4: avoid panic during forced reboot due to aborted journal · 316063bf
      Jan Kara 提交于
      commit 2c1d0e3631e5732dba98ef49ac0bec1388776793 upstream.
      
      Handling of aborted journal is a special code path different from
      standard ext4_error() one and it can call panic() as well. Commit
      1dc1097ff60e ("ext4: avoid panic during forced reboot") forgot to update
      this path so fix that omission.
      
      Fixes: 1dc1097ff60e ("ext4: avoid panic during forced reboot")
      Signed-off-by: NJan Kara <jack@suse.cz>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org # 5.1
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      316063bf
    • S
      ext4: fix use-after-free in dx_release() · c19db366
      Sahitya Tummala 提交于
      commit 08fc98a4d6424af66eb3ac4e2cedd2fc927ed436 upstream.
      
      The buffer_head (frames[0].bh) and it's corresping page can be
      potentially free'd once brelse() is done inside the for loop
      but before the for loop exits in dx_release(). It can be free'd
      in another context, when the page cache is flushed via
      drop_caches_sysctl_handler(). This results into below data abort
      when accessing info->indirect_levels in dx_release().
      
      Unable to handle kernel paging request at virtual address ffffffc17ac3e01e
      Call trace:
       dx_release+0x70/0x90
       ext4_htree_fill_tree+0x2d4/0x300
       ext4_readdir+0x244/0x6f8
       iterate_dir+0xbc/0x160
       SyS_getdents64+0x94/0x174
      Signed-off-by: NSahitya Tummala <stummala@codeaurora.org>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: NAndreas Dilger <adilger@dilger.ca>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c19db366
    • L
      ext4: fix data corruption caused by overlapping unaligned and aligned IO · 0db24122
      Lukas Czerner 提交于
      commit 57a0da28ced8707cb9f79f071a016b9d005caf5a upstream.
      
      Unaligned AIO must be serialized because the zeroing of partial blocks
      of unaligned AIO can result in data corruption in case it's overlapping
      another in flight IO.
      
      Currently we wait for all unwritten extents before we submit unaligned
      AIO which protects data in case of unaligned AIO is following overlapping
      IO. However if a unaligned AIO is followed by overlapping aligned AIO we
      can still end up corrupting data.
      
      To fix this, we must make sure that the unaligned AIO is the only IO in
      flight by waiting for unwritten extents conversion not just before the
      IO submission, but right after it as well.
      
      This problem can be reproduced by xfstest generic/538
      Signed-off-by: NLukas Czerner <lczerner@redhat.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      0db24122
    • S
      ext4: zero out the unused memory region in the extent tree block · 25d010f4
      Sriram Rajagopalan 提交于
      commit 592acbf16821288ecdc4192c47e3774a4c48bb64 upstream.
      
      This commit zeroes out the unused memory region in the buffer_head
      corresponding to the extent metablock after writing the extent header
      and the corresponding extent node entries.
      
      This is done to prevent random uninitialized data from getting into
      the filesystem when the extent block is synced.
      
      This fixes CVE-2019-11833.
      Signed-off-by: NSriram Rajagopalan <sriramr@arista.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      25d010f4
    • J
      fs/writeback.c: use rcu_barrier() to wait for inflight wb switches going into workqueue when umount · 986d3453
      Jiufei Xue 提交于
      commit ec084de929e419e51bcdafaafe567d9e7d0273b7 upstream.
      
      synchronize_rcu() didn't wait for call_rcu() callbacks, so inode wb
      switch may not go to the workqueue after synchronize_rcu().  Thus
      previous scheduled switches was not finished even flushing the
      workqueue, which will cause a NULL pointer dereferenced followed below.
      
        VFS: Busy inodes after unmount of vdd. Self-destruct in 5 seconds.  Have a nice day...
        BUG: unable to handle kernel NULL pointer dereference at 0000000000000278
          evict+0xb3/0x180
          iput+0x1b0/0x230
          inode_switch_wbs_work_fn+0x3c0/0x6a0
          worker_thread+0x4e/0x490
          ? process_one_work+0x410/0x410
          kthread+0xe6/0x100
          ret_from_fork+0x39/0x50
      
      Replace the synchronize_rcu() call with a rcu_barrier() to wait for all
      pending callbacks to finish.  And inc isw_nr_in_flight after call_rcu()
      in inode_switch_wbs() to make more sense.
      
      Link: http://lkml.kernel.org/r/20190429024108.54150-1-jiufei.xue@linux.alibaba.comSigned-off-by: NJiufei Xue <jiufei.xue@linux.alibaba.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      Suggested-by: NTejun Heo <tj@kernel.org>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      986d3453
    • F
      Btrfs: do not start a transaction at iterate_extent_inodes() · 8a8f671b
      Filipe Manana 提交于
      commit bfc61c36260ca990937539cd648ede3cd749bc10 upstream.
      
      When finding out which inodes have references on a particular extent, done
      by backref.c:iterate_extent_inodes(), from the BTRFS_IOC_LOGICAL_INO (both
      v1 and v2) ioctl and from scrub we use the transaction join API to grab a
      reference on the currently running transaction, since in order to give
      accurate results we need to inspect the delayed references of the currently
      running transaction.
      
      However, if there is currently no running transaction, the join operation
      will create a new transaction. This is inefficient as the transaction will
      eventually be committed, doing unnecessary IO and introducing a potential
      point of failure that will lead to a transaction abort due to -ENOSPC, as
      recently reported [1].
      
      That's because the join, creates the transaction but does not reserve any
      space, so when attempting to update the root item of the root passed to
      btrfs_join_transaction(), during the transaction commit, we can end up
      failling with -ENOSPC. Users of a join operation are supposed to actually
      do some filesystem changes and reserve space by some means, which is not
      the case of iterate_extent_inodes(), it is a read-only operation for all
      contextes from which it is called.
      
      The reported [1] -ENOSPC failure stack trace is the following:
      
       heisenberg kernel: ------------[ cut here ]------------
       heisenberg kernel: BTRFS: Transaction aborted (error -28)
       heisenberg kernel: WARNING: CPU: 0 PID: 7137 at fs/btrfs/root-tree.c:136 btrfs_update_root+0x22b/0x320 [btrfs]
      (...)
       heisenberg kernel: CPU: 0 PID: 7137 Comm: btrfs-transacti Not tainted 4.19.0-4-amd64 #1 Debian 4.19.28-2
       heisenberg kernel: Hardware name: FUJITSU LIFEBOOK U757/FJNB2A5, BIOS Version 1.21 03/19/2018
       heisenberg kernel: RIP: 0010:btrfs_update_root+0x22b/0x320 [btrfs]
      (...)
       heisenberg kernel: RSP: 0018:ffffb5448828bd40 EFLAGS: 00010286
       heisenberg kernel: RAX: 0000000000000000 RBX: ffff8ed56bccef50 RCX: 0000000000000006
       heisenberg kernel: RDX: 0000000000000007 RSI: 0000000000000092 RDI: ffff8ed6bda166a0
       heisenberg kernel: RBP: 00000000ffffffe4 R08: 00000000000003df R09: 0000000000000007
       heisenberg kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff8ed63396a078
       heisenberg kernel: R13: ffff8ed092d7c800 R14: ffff8ed64f5db028 R15: ffff8ed6bd03d068
       heisenberg kernel: FS:  0000000000000000(0000) GS:ffff8ed6bda00000(0000) knlGS:0000000000000000
       heisenberg kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
       heisenberg kernel: CR2: 00007f46f75f8000 CR3: 0000000310a0a002 CR4: 00000000003606f0
       heisenberg kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
       heisenberg kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
       heisenberg kernel: Call Trace:
       heisenberg kernel:  commit_fs_roots+0x166/0x1d0 [btrfs]
       heisenberg kernel:  ? _cond_resched+0x15/0x30
       heisenberg kernel:  ? btrfs_run_delayed_refs+0xac/0x180 [btrfs]
       heisenberg kernel:  btrfs_commit_transaction+0x2bd/0x870 [btrfs]
       heisenberg kernel:  ? start_transaction+0x9d/0x3f0 [btrfs]
       heisenberg kernel:  transaction_kthread+0x147/0x180 [btrfs]
       heisenberg kernel:  ? btrfs_cleanup_transaction+0x530/0x530 [btrfs]
       heisenberg kernel:  kthread+0x112/0x130
       heisenberg kernel:  ? kthread_bind+0x30/0x30
       heisenberg kernel:  ret_from_fork+0x35/0x40
       heisenberg kernel: ---[ end trace 05de912e30e012d9 ]---
      
      So fix that by using the attach API, which does not create a transaction
      when there is currently no running transaction.
      
      [1] https://lore.kernel.org/linux-btrfs/b2a668d7124f1d3e410367f587926f622b3f03a4.camel@scientia.net/Reported-by: NZygo Blaxell <ce3g8jdj@umail.furryterror.org>
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: NFilipe Manana <fdmanana@suse.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8a8f671b
    • F
      Btrfs: do not start a transaction during fiemap · 0388d45a
      Filipe Manana 提交于
      commit 03628cdbc64db6262e50d0357960a4e9562676a1 upstream.
      
      During fiemap, for regular extents (non inline) we need to check if they
      are shared and if they are, set the shared bit. Checking if an extent is
      shared requires checking the delayed references of the currently running
      transaction, since some reference might have not yet hit the extent tree
      and be only in the in-memory delayed references.
      
      However we were using a transaction join for this, which creates a new
      transaction when there is no transaction currently running. That means
      that two more potential failures can happen: creating the transaction and
      committing it. Further, if no write activity is currently happening in the
      system, and fiemap calls keep being done, we end up creating and
      committing transactions that do nothing.
      
      In some extreme cases this can result in the commit of the transaction
      created by fiemap to fail with ENOSPC when updating the root item of a
      subvolume tree because a join does not reserve any space, leading to a
      trace like the following:
      
       heisenberg kernel: ------------[ cut here ]------------
       heisenberg kernel: BTRFS: Transaction aborted (error -28)
       heisenberg kernel: WARNING: CPU: 0 PID: 7137 at fs/btrfs/root-tree.c:136 btrfs_update_root+0x22b/0x320 [btrfs]
      (...)
       heisenberg kernel: CPU: 0 PID: 7137 Comm: btrfs-transacti Not tainted 4.19.0-4-amd64 #1 Debian 4.19.28-2
       heisenberg kernel: Hardware name: FUJITSU LIFEBOOK U757/FJNB2A5, BIOS Version 1.21 03/19/2018
       heisenberg kernel: RIP: 0010:btrfs_update_root+0x22b/0x320 [btrfs]
      (...)
       heisenberg kernel: RSP: 0018:ffffb5448828bd40 EFLAGS: 00010286
       heisenberg kernel: RAX: 0000000000000000 RBX: ffff8ed56bccef50 RCX: 0000000000000006
       heisenberg kernel: RDX: 0000000000000007 RSI: 0000000000000092 RDI: ffff8ed6bda166a0
       heisenberg kernel: RBP: 00000000ffffffe4 R08: 00000000000003df R09: 0000000000000007
       heisenberg kernel: R10: 0000000000000000 R11: 0000000000000001 R12: ffff8ed63396a078
       heisenberg kernel: R13: ffff8ed092d7c800 R14: ffff8ed64f5db028 R15: ffff8ed6bd03d068
       heisenberg kernel: FS:  0000000000000000(0000) GS:ffff8ed6bda00000(0000) knlGS:0000000000000000
       heisenberg kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
       heisenberg kernel: CR2: 00007f46f75f8000 CR3: 0000000310a0a002 CR4: 00000000003606f0
       heisenberg kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
       heisenberg kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
       heisenberg kernel: Call Trace:
       heisenberg kernel:  commit_fs_roots+0x166/0x1d0 [btrfs]
       heisenberg kernel:  ? _cond_resched+0x15/0x30
       heisenberg kernel:  ? btrfs_run_delayed_refs+0xac/0x180 [btrfs]
       heisenberg kernel:  btrfs_commit_transaction+0x2bd/0x870 [btrfs]
       heisenberg kernel:  ? start_transaction+0x9d/0x3f0 [btrfs]
       heisenberg kernel:  transaction_kthread+0x147/0x180 [btrfs]
       heisenberg kernel:  ? btrfs_cleanup_transaction+0x530/0x530 [btrfs]
       heisenberg kernel:  kthread+0x112/0x130
       heisenberg kernel:  ? kthread_bind+0x30/0x30
       heisenberg kernel:  ret_from_fork+0x35/0x40
       heisenberg kernel: ---[ end trace 05de912e30e012d9 ]---
      
      Since fiemap (and btrfs_check_shared()) is a read-only operation, do not do
      a transaction join to avoid the overhead of creating a new transaction (if
      there is currently no running transaction) and introducing a potential
      point of failure when the new transaction gets committed, instead use a
      transaction attach to grab a handle for the currently running transaction
      if any.
      Reported-by: NChristoph Anton Mitterer <calestyo@scientia.net>
      Link: https://lore.kernel.org/linux-btrfs/b2a668d7124f1d3e410367f587926f622b3f03a4.camel@scientia.net/
      Fixes: afce772e ("btrfs: fix check_shared for fiemap ioctl")
      CC: stable@vger.kernel.org # 4.14+
      Reviewed-by: NQu Wenruo <wqu@suse.com>
      Signed-off-by: NFilipe Manana <fdmanana@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      0388d45a
    • F
      Btrfs: send, flush dellaloc in order to avoid data loss · 74ca0a76
      Filipe Manana 提交于
      commit 9f89d5de8631c7930898a601b6612e271aa2261c upstream.
      
      When we set a subvolume to read-only mode we do not flush dellaloc for any
      of its inodes (except if the filesystem is mounted with -o flushoncommit),
      since it does not affect correctness for any subsequent operations - except
      for a future send operation. The send operation will not be able to see the
      delalloc data since the respective file extent items, inode item updates,
      backreferences, etc, have not hit yet the subvolume and extent trees.
      
      Effectively this means data loss, since the send stream will not contain
      any data from existing delalloc. Another problem from this is that if the
      writeback starts and finishes while the send operation is in progress, we
      have the subvolume tree being being modified concurrently which can result
      in send failing unexpectedly with EIO or hitting runtime errors, assertion
      failures or hitting BUG_ONs, etc.
      
      Simple reproducer:
      
        $ mkfs.btrfs -f /dev/sdb
        $ mount /dev/sdb /mnt
      
        $ btrfs subvolume create /mnt/sv
        $ xfs_io -f -c "pwrite -S 0xea 0 108K" /mnt/sv/foo
      
        $ btrfs property set /mnt/sv ro true
        $ btrfs send -f /tmp/send.stream /mnt/sv
      
        $ od -t x1 -A d /mnt/sv/foo
        0000000 ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea ea
        *
        0110592
      
        $ umount /mnt
        $ mkfs.btrfs -f /dev/sdc
        $ mount /dev/sdc /mnt
      
        $ btrfs receive -f /tmp/send.stream /mnt
        $ echo $?
        0
        $ od -t x1 -A d /mnt/sv/foo
        0000000
        # ---> empty file
      
      Since this a problem that affects send only, fix it in send by flushing
      dellaloc for all the roots used by the send operation before send starts
      to process the commit roots.
      
      This is a problem that affects send since it was introduced (commit
      31db9f7c ("Btrfs: introduce BTRFS_IOC_SEND for btrfs send/receive"))
      but backporting it to older kernels has some dependencies:
      
      - For kernels between 3.19 and 4.20, it depends on commit 3cd24c698004d2
        ("btrfs: use tagged writepage to mitigate livelock of snapshot") because
        the function btrfs_start_delalloc_snapshot() does not exist before that
        commit. So one has to either pick that commit or replace the calls to
        btrfs_start_delalloc_snapshot() in this patch with calls to
        btrfs_start_delalloc_inodes().
      
      - For kernels older than 3.19 it also requires commit e5fa8f86
        ("Btrfs: ensure send always works on roots without orphans") because
        it depends on the function ensure_commit_roots_uptodate() which that
        commits introduced.
      
      - No dependencies for 5.0+ kernels.
      
      A test case for fstests follows soon.
      
      CC: stable@vger.kernel.org # 3.19+
      Signed-off-by: NFilipe Manana <fdmanana@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      74ca0a76
    • N
      btrfs: Honour FITRIM range constraints during free space trim · 8b13bb91
      Nikolay Borisov 提交于
      commit c2d1b3aae33605a61cbab445d8ae1c708ccd2698 upstream.
      
      Up until now trimming the freespace was done irrespective of what the
      arguments of the FITRIM ioctl were. For example fstrim's -o/-l arguments
      will be entirely ignored. Fix it by correctly handling those paramter.
      This requires breaking if the found freespace extent is after the end of
      the passed range as well as completing trim after trimming
      fstrim_range::len bytes.
      
      Fixes: 499f377f ("btrfs: iterate over unused chunk space in FITRIM")
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: NNikolay Borisov <nborisov@suse.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      8b13bb91
    • N
      btrfs: Correctly free extent buffer in case btree_read_extent_buffer_pages fails · 87dcf0c6
      Nikolay Borisov 提交于
      commit 537f38f019fa0b762dbb4c0fc95d7fcce9db8e2d upstream.
      
      If a an eb fails to be read for whatever reason - it's corrupted on disk
      and parent transid/key validations fail or IO for eb pages fail then
      this buffer must be removed from the buffer cache. Currently the code
      calls free_extent_buffer if an error occurs. Unfortunately this doesn't
      achieve the desired behavior since btrfs_find_create_tree_block returns
      with eb->refs == 2.
      
      On the other hand free_extent_buffer will only decrement the refs once
      leaving it added to the buffer cache radix tree.  This enables later
      code to look up the buffer from the cache and utilize it potentially
      leading to a crash.
      
      The correct way to free the buffer is call free_extent_buffer_stale.
      This function will correctly call atomic_dec explicitly for the buffer
      and subsequently call release_extent_buffer which will decrement the
      final reference thus correctly remove the invalid buffer from buffer
      cache. This change affects only newly allocated buffers since they have
      eb->refs == 2.
      
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202755Reported-by: NJungyeon <jungyeon@gatech.edu>
      CC: stable@vger.kernel.org # 4.4+
      Signed-off-by: NNikolay Borisov <nborisov@suse.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      87dcf0c6
    • Q
      btrfs: Check the first key and level for cached extent buffer · d8925a1f
      Qu Wenruo 提交于
      commit 448de471cd4cab0cedd15770082567a69a784a11 upstream.
      
      [BUG]
      When reading a file from a fuzzed image, kernel can panic like:
      
        BTRFS warning (device loop0): csum failed root 5 ino 270 off 0 csum 0x98f94189 expected csum 0x00000000 mirror 1
        assertion failed: !memcmp_extent_buffer(b, &disk_key, offsetof(struct btrfs_leaf, items[0].key), sizeof(disk_key)), file: fs/btrfs/ctree.c, line: 2544
        ------------[ cut here ]------------
        kernel BUG at fs/btrfs/ctree.h:3500!
        invalid opcode: 0000 [#1] PREEMPT SMP NOPTI
        RIP: 0010:btrfs_search_slot.cold.24+0x61/0x63 [btrfs]
        Call Trace:
         btrfs_lookup_csum+0x52/0x150 [btrfs]
         __btrfs_lookup_bio_sums+0x209/0x640 [btrfs]
         btrfs_submit_bio_hook+0x103/0x170 [btrfs]
         submit_one_bio+0x59/0x80 [btrfs]
         extent_read_full_page+0x58/0x80 [btrfs]
         generic_file_read_iter+0x2f6/0x9d0
         __vfs_read+0x14d/0x1a0
         vfs_read+0x8d/0x140
         ksys_read+0x52/0xc0
         do_syscall_64+0x60/0x210
         entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      [CAUSE]
      The fuzzed image has a corrupted leaf whose first key doesn't match its
      parent:
      
        checksum tree key (CSUM_TREE ROOT_ITEM 0)
        node 29741056 level 1 items 14 free 107 generation 19 owner CSUM_TREE
        fs uuid 3381d111-94a3-4ac7-8f39-611bbbdab7e6
        chunk uuid 9af1c3c7-2af5-488b-8553-530bd515f14c
        	...
                key (EXTENT_CSUM EXTENT_CSUM 79691776) block 29761536 gen 19
      
        leaf 29761536 items 1 free space 1726 generation 19 owner CSUM_TREE
        leaf 29761536 flags 0x1(WRITTEN) backref revision 1
        fs uuid 3381d111-94a3-4ac7-8f39-611bbbdab7e6
        chunk uuid 9af1c3c7-2af5-488b-8553-530bd515f14c
                item 0 key (EXTENT_CSUM EXTENT_CSUM 8798638964736) itemoff 1751 itemsize 2244
                        range start 8798638964736 end 8798641262592 length 2297856
      
      When reading the above tree block, we have extent_buffer->refs = 2 in
      the context:
      
      - initial one from __alloc_extent_buffer()
        alloc_extent_buffer()
        |- __alloc_extent_buffer()
           |- atomic_set(&eb->refs, 1)
      
      - one being added to fs_info->buffer_radix
        alloc_extent_buffer()
        |- check_buffer_tree_ref()
           |- atomic_inc(&eb->refs)
      
      So if even we call free_extent_buffer() in read_tree_block or other
      similar situation, we only decrease the refs by 1, it doesn't reach 0
      and won't be freed right now.
      
      The staled eb and its corrupted content will still be kept cached.
      
      Furthermore, we have several extra cases where we either don't do first
      key check or the check is not proper for all callers:
      
      - scrub
        We just don't have first key in this context.
      
      - shared tree block
        One tree block can be shared by several snapshot/subvolume trees.
        In that case, the first key check for one subvolume doesn't apply to
        another.
      
      So for the above reasons, a corrupted extent buffer can sneak into the
      buffer cache.
      
      [FIX]
      Call verify_level_key in read_block_for_search to do another
      verification. For that purpose the function is exported.
      
      Due to above reasons, although we can free corrupted extent buffer from
      cache, we still need the check in read_block_for_search(), for scrub and
      shared tree blocks.
      
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202755
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202757
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202759
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202761
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202767
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=202769Reported-by: NYoon Jungyeon <jungyeon@gatech.edu>
      CC: stable@vger.kernel.org # 4.19+
      Signed-off-by: NQu Wenruo <wqu@suse.com>
      Reviewed-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NDavid Sterba <dsterba@suse.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d8925a1f
    • D
      ext4: fix ext4_show_options for file systems w/o journal · 45123ae5
      Debabrata Banerjee 提交于
      commit 50b29d8f033a7c88c5bc011abc2068b1691ab755 upstream.
      
      Instead of removing EXT4_MOUNT_JOURNAL_CHECKSUM from s_def_mount_opt as
      I assume was intended, all other options were blown away leading to
      _ext4_show_options() output being incorrect.
      
      Fixes: 1e381f60 ("ext4: do not allow journal_opts for fs w/o journal")
      Signed-off-by: NDebabrata Banerjee <dbanerje@akamai.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      45123ae5
    • K
      ext4: actually request zeroing of inode table after grow · f7952475
      Kirill Tkhai 提交于
      commit 310a997fd74de778b9a4848a64be9cda9f18764a upstream.
      
      It is never possible, that number of block groups decreases,
      since only online grow is supported.
      
      But after a growing occured, we have to zero inode tables
      for just created new block groups.
      
      Fixes: 19c5246d ("ext4: add new online resize interface")
      Signed-off-by: NKirill Tkhai <ktkhai@virtuozzo.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f7952475
    • B
      ext4: fix use-after-free race with debug_want_extra_isize · 2a18c9c7
      Barret Rhoden 提交于
      commit 7bc04c5c2cc467c5b40f2b03ba08da174a0d5fa7 upstream.
      
      When remounting with debug_want_extra_isize, we were not performing the
      same checks that we do during a normal mount.  That allowed us to set a
      value for s_want_extra_isize that reached outside the s_inode_size.
      
      Fixes: e2b911c5 ("ext4: clean up feature test macros with predicate functions")
      Reported-by: syzbot+f584efa0ac7213c226b7@syzkaller.appspotmail.com
      Reviewed-by: NJan Kara <jack@suse.cz>
      Signed-off-by: NBarret Rhoden <brho@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@vger.kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2a18c9c7
    • P
      ext4: avoid drop reference to iloc.bh twice · b12a8d80
      Pan Bian 提交于
      commit 8c380ab4b7b59c0c602743810be1b712514eaebc upstream.
      
      The reference to iloc.bh has been dropped in ext4_mark_iloc_dirty.
      However, the reference is dropped again if error occurs during
      ext4_handle_dirty_metadata, which may result in use-after-free bugs.
      
      Fixes: fb265c9cb49e("ext4: add ext4_sb_bread() to disambiguate ENOMEM cases")
      Signed-off-by: NPan Bian <bianpan2016@163.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b12a8d80
    • T
      ext4: ignore e_value_offs for xattrs with value-in-ea-inode · f0f805f8
      Theodore Ts'o 提交于
      commit e5d01196c0428a206f307e9ee5f6842964098ff0 upstream.
      
      In other places in fs/ext4/xattr.c, if e_value_inum is non-zero, the
      code ignores the value in e_value_offs.  The e_value_offs *should* be
      zero, but we shouldn't depend upon it, since it might not be true in a
      corrupted/fuzzed file system.
      
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202897
      Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202877Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f0f805f8
    • J
      ext4: make sanity check in mballoc more strict · 71478ef6
      Jan Kara 提交于
      commit 31562b954b60f02acb91b7349dc6432d3f8c3c5f upstream.
      
      The sanity check in mb_find_extent() only checked that returned extent
      does not extend past blocksize * 8, however it should not extend past
      EXT4_CLUSTERS_PER_GROUP(sb). This can happen when clusters_per_group <
      blocksize * 8 and the tail of the bitmap is not properly filled by 1s
      which happened e.g. when ancient kernels have grown the filesystem.
      Signed-off-by: NJan Kara <jack@suse.cz>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      71478ef6
    • J
      jbd2: check superblock mapped prior to committing · 001fe0da
      Jiufei Xue 提交于
      commit 742b06b5628f2cd23cb51a034cb54dc33c6162c5 upstream.
      
      We hit a BUG at fs/buffer.c:3057 if we detached the nbd device
      before unmounting ext4 filesystem.
      
      The typical chain of events leading to the BUG:
      jbd2_write_superblock
        submit_bh
          submit_bh_wbc
            BUG_ON(!buffer_mapped(bh));
      
      The block device is removed and all the pages are invalidated. JBD2
      was trying to write journal superblock to the block device which is
      no longer present.
      
      Fix this by checking the journal superblock's buffer head prior to
      submitting.
      Reported-by: NEric Ren <renzhen@linux.alibaba.com>
      Signed-off-by: NJiufei Xue <jiufei.xue@linux.alibaba.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Cc: stable@kernel.org
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      001fe0da
    • S
      ocfs2: fix ocfs2 read inode data panic in ocfs2_iget · 3574bc98
      Shuning Zhang 提交于
      commit e091eab028f9253eac5c04f9141bbc9d170acab3 upstream.
      
      In some cases, ocfs2_iget() reads the data of inode, which has been
      deleted for some reason.  That will make the system panic.  So We should
      judge whether this inode has been deleted, and tell the caller that the
      inode is a bad inode.
      
      For example, the ocfs2 is used as the backed of nfs, and the client is
      nfsv3.  This issue can be reproduced by the following steps.
      
      on the nfs server side,
      ..../patha/pathb
      
      Step 1: The process A was scheduled before calling the function fh_verify.
      
      Step 2: The process B is removing the 'pathb', and just completed the call
      to function dput.  Then the dentry of 'pathb' has been deleted from the
      dcache, and all ancestors have been deleted also.  The relationship of
      dentry and inode was deleted through the function hlist_del_init.  The
      following is the call stack.
      dentry_iput->hlist_del_init(&dentry->d_u.d_alias)
      
      At this time, the inode is still in the dcache.
      
      Step 3: The process A call the function ocfs2_get_dentry, which get the
      inode from dcache.  Then the refcount of inode is 1.  The following is the
      call stack.
      nfsd3_proc_getacl->fh_verify->exportfs_decode_fh->fh_to_dentry(ocfs2_get_dentry)
      
      Step 4: Dirty pages are flushed by bdi threads.  So the inode of 'patha'
      is evicted, and this directory was deleted.  But the inode of 'pathb'
      can't be evicted, because the refcount of the inode was 1.
      
      Step 5: The process A keep running, and call the function
      reconnect_path(in exportfs_decode_fh), which call function
      ocfs2_get_parent of ocfs2.  Get the block number of parent
      directory(patha) by the name of ...  Then read the data from disk by the
      block number.  But this inode has been deleted, so the system panic.
      
      Process A                                             Process B
      1. in nfsd3_proc_getacl                   |
      2.                                        |        dput
      3. fh_to_dentry(ocfs2_get_dentry)         |
      4. bdi flush dirty cache                  |
      5. ocfs2_iget                             |
      
      [283465.542049] OCFS2: ERROR (device sdp): ocfs2_validate_inode_block:
      Invalid dinode #580640: OCFS2_VALID_FL not set
      
      [283465.545490] Kernel panic - not syncing: OCFS2: (device sdp): panic forced
      after error
      
      [283465.546889] CPU: 5 PID: 12416 Comm: nfsd Tainted: G        W
      4.1.12-124.18.6.el6uek.bug28762940v3.x86_64 #2
      [283465.548382] Hardware name: VMware, Inc. VMware Virtual Platform/440BX
      Desktop Reference Platform, BIOS 6.00 09/21/2015
      [283465.549657]  0000000000000000 ffff8800a56fb7b8 ffffffff816e839c
      ffffffffa0514758
      [283465.550392]  000000000008dc20 ffff8800a56fb838 ffffffff816e62d3
      0000000000000008
      [283465.551056]  ffff880000000010 ffff8800a56fb848 ffff8800a56fb7e8
      ffff88005df9f000
      [283465.551710] Call Trace:
      [283465.552516]  [<ffffffff816e839c>] dump_stack+0x63/0x81
      [283465.553291]  [<ffffffff816e62d3>] panic+0xcb/0x21b
      [283465.554037]  [<ffffffffa04e66b0>] ocfs2_handle_error+0xf0/0xf0 [ocfs2]
      [283465.554882]  [<ffffffffa04e7737>] __ocfs2_error+0x67/0x70 [ocfs2]
      [283465.555768]  [<ffffffffa049c0f9>] ocfs2_validate_inode_block+0x229/0x230
      [ocfs2]
      [283465.556683]  [<ffffffffa047bcbc>] ocfs2_read_blocks+0x46c/0x7b0 [ocfs2]
      [283465.557408]  [<ffffffffa049bed0>] ? ocfs2_inode_cache_io_unlock+0x20/0x20
      [ocfs2]
      [283465.557973]  [<ffffffffa049f0eb>] ocfs2_read_inode_block_full+0x3b/0x60
      [ocfs2]
      [283465.558525]  [<ffffffffa049f5ba>] ocfs2_iget+0x4aa/0x880 [ocfs2]
      [283465.559082]  [<ffffffffa049146e>] ocfs2_get_parent+0x9e/0x220 [ocfs2]
      [283465.559622]  [<ffffffff81297c05>] reconnect_path+0xb5/0x300
      [283465.560156]  [<ffffffff81297f46>] exportfs_decode_fh+0xf6/0x2b0
      [283465.560708]  [<ffffffffa062faf0>] ? nfsd_proc_getattr+0xa0/0xa0 [nfsd]
      [283465.561262]  [<ffffffff810a8196>] ? prepare_creds+0x26/0x110
      [283465.561932]  [<ffffffffa0630860>] fh_verify+0x350/0x660 [nfsd]
      [283465.562862]  [<ffffffffa0637804>] ? nfsd_cache_lookup+0x44/0x630 [nfsd]
      [283465.563697]  [<ffffffffa063a8b9>] nfsd3_proc_getattr+0x69/0xf0 [nfsd]
      [283465.564510]  [<ffffffffa062cf60>] nfsd_dispatch+0xe0/0x290 [nfsd]
      [283465.565358]  [<ffffffffa05eb892>] ? svc_tcp_adjust_wspace+0x12/0x30
      [sunrpc]
      [283465.566272]  [<ffffffffa05ea652>] svc_process_common+0x412/0x6a0 [sunrpc]
      [283465.567155]  [<ffffffffa05eaa03>] svc_process+0x123/0x210 [sunrpc]
      [283465.568020]  [<ffffffffa062c90f>] nfsd+0xff/0x170 [nfsd]
      [283465.568962]  [<ffffffffa062c810>] ? nfsd_destroy+0x80/0x80 [nfsd]
      [283465.570112]  [<ffffffff810a622b>] kthread+0xcb/0xf0
      [283465.571099]  [<ffffffff810a6160>] ? kthread_create_on_node+0x180/0x180
      [283465.572114]  [<ffffffff816f11b8>] ret_from_fork+0x58/0x90
      [283465.573156]  [<ffffffff810a6160>] ? kthread_create_on_node+0x180/0x180
      
      Link: http://lkml.kernel.org/r/1554185919-3010-1-git-send-email-sunny.s.zhang@oracle.comSigned-off-by: NShuning Zhang <sunny.s.zhang@oracle.com>
      Reviewed-by: NJoseph Qi <jiangqi903@gmail.com>
      Cc: Mark Fasheh <mark@fasheh.com>
      Cc: Joel Becker <jlbec@evilplan.org>
      Cc: Junxiao Bi <junxiao.bi@oracle.com>
      Cc: Changwei Ge <gechangwei@live.cn>
      Cc: piaojun <piaojun@huawei.com>
      Cc: "Gang He" <ghe@suse.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3574bc98
    • M
      hugetlb: use same fault hash key for shared and private mappings · a3ccc156
      Mike Kravetz 提交于
      commit 1b426bac66e6cc83c9f2d92b96e4e72acf43419a upstream.
      
      hugetlb uses a fault mutex hash table to prevent page faults of the
      same pages concurrently.  The key for shared and private mappings is
      different.  Shared keys off address_space and file index.  Private keys
      off mm and virtual address.  Consider a private mappings of a populated
      hugetlbfs file.  A fault will map the page from the file and if needed
      do a COW to map a writable page.
      
      Hugetlbfs hole punch uses the fault mutex to prevent mappings of file
      pages.  It uses the address_space file index key.  However, private
      mappings will use a different key and could race with this code to map
      the file page.  This causes problems (BUG) for the page cache remove
      code as it expects the page to be unmapped.  A sample stack is:
      
      page dumped because: VM_BUG_ON_PAGE(page_mapped(page))
      kernel BUG at mm/filemap.c:169!
      ...
      RIP: 0010:unaccount_page_cache_page+0x1b8/0x200
      ...
      Call Trace:
      __delete_from_page_cache+0x39/0x220
      delete_from_page_cache+0x45/0x70
      remove_inode_hugepages+0x13c/0x380
      ? __add_to_page_cache_locked+0x162/0x380
      hugetlbfs_fallocate+0x403/0x540
      ? _cond_resched+0x15/0x30
      ? __inode_security_revalidate+0x5d/0x70
      ? selinux_file_permission+0x100/0x130
      vfs_fallocate+0x13f/0x270
      ksys_fallocate+0x3c/0x80
      __x64_sys_fallocate+0x1a/0x20
      do_syscall_64+0x5b/0x180
      entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      There seems to be another potential COW issue/race with this approach
      of different private and shared keys as noted in commit 8382d914
      ("mm, hugetlb: improve page-fault scalability").
      
      Since every hugetlb mapping (even anon and private) is actually a file
      mapping, just use the address_space index key for all mappings.  This
      results in potentially more hash collisions.  However, this should not
      be the common case.
      
      Link: http://lkml.kernel.org/r/20190328234704.27083-3-mike.kravetz@oracle.com
      Link: http://lkml.kernel.org/r/20190412165235.t4sscoujczfhuiyt@linux-r8p5
      Fixes: b5cec28d ("hugetlbfs: truncate_hugepages() takes a range of pages")
      Signed-off-by: NMike Kravetz <mike.kravetz@oracle.com>
      Reviewed-by: NNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>
      Reviewed-by: NDavidlohr Bueso <dbueso@suse.de>
      Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
      Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
      Cc: Michal Hocko <mhocko@kernel.org>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a3ccc156
    • D
      mm/huge_memory: fix vmf_insert_pfn_{pmd, pud}() crash, handle unaligned addresses · 58db3813
      Dan Williams 提交于
      commit fce86ff5802bac3a7b19db171aa1949ef9caac31 upstream.
      
      Starting with c6f3c5ee40c1 ("mm/huge_memory.c: fix modifying of page
      protection by insert_pfn_pmd()") vmf_insert_pfn_pmd() internally calls
      pmdp_set_access_flags().  That helper enforces a pmd aligned @address
      argument via VM_BUG_ON() assertion.
      
      Update the implementation to take a 'struct vm_fault' argument directly
      and apply the address alignment fixup internally to fix crash signatures
      like:
      
          kernel BUG at arch/x86/mm/pgtable.c:515!
          invalid opcode: 0000 [#1] SMP NOPTI
          CPU: 51 PID: 43713 Comm: java Tainted: G           OE     4.19.35 #1
          [..]
          RIP: 0010:pmdp_set_access_flags+0x48/0x50
          [..]
          Call Trace:
           vmf_insert_pfn_pmd+0x198/0x350
           dax_iomap_fault+0xe82/0x1190
           ext4_dax_huge_fault+0x103/0x1f0
           ? __switch_to_asm+0x40/0x70
           __handle_mm_fault+0x3f6/0x1370
           ? __switch_to_asm+0x34/0x70
           ? __switch_to_asm+0x40/0x70
           handle_mm_fault+0xda/0x200
           __do_page_fault+0x249/0x4f0
           do_page_fault+0x32/0x110
           ? page_fault+0x8/0x30
           page_fault+0x1e/0x30
      
      Link: http://lkml.kernel.org/r/155741946350.372037.11148198430068238140.stgit@dwillia2-desk3.amr.corp.intel.com
      Fixes: c6f3c5ee40c1 ("mm/huge_memory.c: fix modifying of page protection by insert_pfn_pmd()")
      Signed-off-by: NDan Williams <dan.j.williams@intel.com>
      Reported-by: NPiotr Balcer <piotr.balcer@intel.com>
      Tested-by: NYan Ma <yan.ma@intel.com>
      Tested-by: NPankaj Gupta <pagupta@redhat.com>
      Reviewed-by: NMatthew Wilcox <willy@infradead.org>
      Reviewed-by: NJan Kara <jack@suse.cz>
      Reviewed-by: NAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
      Cc: Chandan Rajendra <chandan@linux.ibm.com>
      Cc: Souptick Joarder <jrdr.linux@gmail.com>
      Cc: <stable@vger.kernel.org>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      58db3813
  2. 17 5月, 2019 2 次提交
  3. 08 5月, 2019 4 次提交
    • K
      fs: stream_open - opener for stream-like files so that read and write can run... · 04b4d5f7
      Kirill Smelkov 提交于
      fs: stream_open - opener for stream-like files so that read and write can run simultaneously without deadlock
      
      [ Upstream commit 10dce8af34226d90fa56746a934f8da5dcdba3df ]
      
      Commit 9c225f26 ("vfs: atomic f_pos accesses as per POSIX") added
      locking for file.f_pos access and in particular made concurrent read and
      write not possible - now both those functions take f_pos lock for the
      whole run, and so if e.g. a read is blocked waiting for data, write will
      deadlock waiting for that read to complete.
      
      This caused regression for stream-like files where previously read and
      write could run simultaneously, but after that patch could not do so
      anymore. See e.g. commit 581d21a2 ("xenbus: fix deadlock on writes
      to /proc/xen/xenbus") which fixes such regression for particular case of
      /proc/xen/xenbus.
      
      The patch that added f_pos lock in 2014 did so to guarantee POSIX thread
      safety for read/write/lseek and added the locking to file descriptors of
      all regular files. In 2014 that thread-safety problem was not new as it
      was already discussed earlier in 2006.
      
      However even though 2006'th version of Linus's patch was adding f_pos
      locking "only for files that are marked seekable with FMODE_LSEEK (thus
      avoiding the stream-like objects like pipes and sockets)", the 2014
      version - the one that actually made it into the tree as 9c225f26 -
      is doing so irregardless of whether a file is seekable or not.
      
      See
      
          https://lore.kernel.org/lkml/53022DB1.4070805@gmail.com/
          https://lwn.net/Articles/180387
          https://lwn.net/Articles/180396
      
      for historic context.
      
      The reason that it did so is, probably, that there are many files that
      are marked non-seekable, but e.g. their read implementation actually
      depends on knowing current position to correctly handle the read. Some
      examples:
      
      	kernel/power/user.c		snapshot_read
      	fs/debugfs/file.c		u32_array_read
      	fs/fuse/control.c		fuse_conn_waiting_read + ...
      	drivers/hwmon/asus_atk0110.c	atk_debugfs_ggrp_read
      	arch/s390/hypfs/inode.c		hypfs_read_iter
      	...
      
      Despite that, many nonseekable_open users implement read and write with
      pure stream semantics - they don't depend on passed ppos at all. And for
      those cases where read could wait for something inside, it creates a
      situation similar to xenbus - the write could be never made to go until
      read is done, and read is waiting for some, potentially external, event,
      for potentially unbounded time -> deadlock.
      
      Besides xenbus, there are 14 such places in the kernel that I've found
      with semantic patch (see below):
      
      	drivers/xen/evtchn.c:667:8-24: ERROR: evtchn_fops: .read() can deadlock .write()
      	drivers/isdn/capi/capi.c:963:8-24: ERROR: capi_fops: .read() can deadlock .write()
      	drivers/input/evdev.c:527:1-17: ERROR: evdev_fops: .read() can deadlock .write()
      	drivers/char/pcmcia/cm4000_cs.c:1685:7-23: ERROR: cm4000_fops: .read() can deadlock .write()
      	net/rfkill/core.c:1146:8-24: ERROR: rfkill_fops: .read() can deadlock .write()
      	drivers/s390/char/fs3270.c:488:1-17: ERROR: fs3270_fops: .read() can deadlock .write()
      	drivers/usb/misc/ldusb.c:310:1-17: ERROR: ld_usb_fops: .read() can deadlock .write()
      	drivers/hid/uhid.c:635:1-17: ERROR: uhid_fops: .read() can deadlock .write()
      	net/batman-adv/icmp_socket.c:80:1-17: ERROR: batadv_fops: .read() can deadlock .write()
      	drivers/media/rc/lirc_dev.c:198:1-17: ERROR: lirc_fops: .read() can deadlock .write()
      	drivers/leds/uleds.c:77:1-17: ERROR: uleds_fops: .read() can deadlock .write()
      	drivers/input/misc/uinput.c:400:1-17: ERROR: uinput_fops: .read() can deadlock .write()
      	drivers/infiniband/core/user_mad.c:985:7-23: ERROR: umad_fops: .read() can deadlock .write()
      	drivers/gnss/core.c:45:1-17: ERROR: gnss_fops: .read() can deadlock .write()
      
      In addition to the cases above another regression caused by f_pos
      locking is that now FUSE filesystems that implement open with
      FOPEN_NONSEEKABLE flag, can no longer implement bidirectional
      stream-like files - for the same reason as above e.g. read can deadlock
      write locking on file.f_pos in the kernel.
      
      FUSE's FOPEN_NONSEEKABLE was added in 2008 in a7c1b990 ("fuse:
      implement nonseekable open") to support OSSPD. OSSPD implements /dev/dsp
      in userspace with FOPEN_NONSEEKABLE flag, with corresponding read and
      write routines not depending on current position at all, and with both
      read and write being potentially blocking operations:
      
      See
      
          https://github.com/libfuse/osspd
          https://lwn.net/Articles/308445
      
          https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1406
          https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1438-L1477
          https://github.com/libfuse/osspd/blob/14a9cff0/osspd.c#L1479-L1510
      
      Corresponding libfuse example/test also describes FOPEN_NONSEEKABLE as
      "somewhat pipe-like files ..." with read handler not using offset.
      However that test implements only read without write and cannot exercise
      the deadlock scenario:
      
          https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L124-L131
          https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L146-L163
          https://github.com/libfuse/libfuse/blob/fuse-3.4.2-3-ga1bff7d/example/poll.c#L209-L216
      
      I've actually hit the read vs write deadlock for real while implementing
      my FUSE filesystem where there is /head/watch file, for which open
      creates separate bidirectional socket-like stream in between filesystem
      and its user with both read and write being later performed
      simultaneously. And there it is semantically not easy to split the
      stream into two separate read-only and write-only channels:
      
          https://lab.nexedi.com/kirr/wendelin.core/blob/f13aa600/wcfs/wcfs.go#L88-169
      
      Let's fix this regression. The plan is:
      
      1. We can't change nonseekable_open to include &~FMODE_ATOMIC_POS -
         doing so would break many in-kernel nonseekable_open users which
         actually use ppos in read/write handlers.
      
      2. Add stream_open() to kernel to open stream-like non-seekable file
         descriptors. Read and write on such file descriptors would never use
         nor change ppos. And with that property on stream-like files read and
         write will be running without taking f_pos lock - i.e. read and write
         could be running simultaneously.
      
      3. With semantic patch search and convert to stream_open all in-kernel
         nonseekable_open users for which read and write actually do not
         depend on ppos and where there is no other methods in file_operations
         which assume @offset access.
      
      4. Add FOPEN_STREAM to fs/fuse/ and open in-kernel file-descriptors via
         steam_open if that bit is present in filesystem open reply.
      
         It was tempting to change fs/fuse/ open handler to use stream_open
         instead of nonseekable_open on just FOPEN_NONSEEKABLE flags, but
         grepping through Debian codesearch shows users of FOPEN_NONSEEKABLE,
         and in particular GVFS which actually uses offset in its read and
         write handlers
      
      	https://codesearch.debian.net/search?q=-%3Enonseekable+%3D
      	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1080
      	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1247-1346
      	https://gitlab.gnome.org/GNOME/gvfs/blob/1.40.0-6-gcbc54396/client/gvfsfusedaemon.c#L1399-1481
      
         so if we would do such a change it will break a real user.
      
      5. Add stream_open and FOPEN_STREAM handling to stable kernels starting
         from v3.14+ (the kernel where 9c225f26 first appeared).
      
         This will allow to patch OSSPD and other FUSE filesystems that
         provide stream-like files to return FOPEN_STREAM | FOPEN_NONSEEKABLE
         in their open handler and this way avoid the deadlock on all kernel
         versions. This should work because fs/fuse/ ignores unknown open
         flags returned from a filesystem and so passing FOPEN_STREAM to a
         kernel that is not aware of this flag cannot hurt. In turn the kernel
         that is not aware of FOPEN_STREAM will be < v3.14 where just
         FOPEN_NONSEEKABLE is sufficient to implement streams without read vs
         write deadlock.
      
      This patch adds stream_open, converts /proc/xen/xenbus to it and adds
      semantic patch to automatically locate in-kernel places that are either
      required to be converted due to read vs write deadlock, or that are just
      safe to be converted because read and write do not use ppos and there
      are no other funky methods in file_operations.
      
      Regarding semantic patch I've verified each generated change manually -
      that it is correct to convert - and each other nonseekable_open instance
      left - that it is either not correct to convert there, or that it is not
      converted due to current stream_open.cocci limitations.
      
      The script also does not convert files that should be valid to convert,
      but that currently have .llseek = noop_llseek or generic_file_llseek for
      unknown reason despite file being opened with nonseekable_open (e.g.
      drivers/input/mousedev.c)
      
      Cc: Michael Kerrisk <mtk.manpages@gmail.com>
      Cc: Yongzhi Pan <panyongzhi@gmail.com>
      Cc: Jonathan Corbet <corbet@lwn.net>
      Cc: David Vrabel <david.vrabel@citrix.com>
      Cc: Juergen Gross <jgross@suse.com>
      Cc: Miklos Szeredi <miklos@szeredi.hu>
      Cc: Tejun Heo <tj@kernel.org>
      Cc: Kirill Tkhai <ktkhai@virtuozzo.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Julia Lawall <Julia.Lawall@lip6.fr>
      Cc: Nikolaus Rath <Nikolaus@rath.org>
      Cc: Han-Wen Nienhuys <hanwen@google.com>
      Signed-off-by: NKirill Smelkov <kirr@nexedi.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      04b4d5f7
    • M
      hugetlbfs: fix memory leak for resv_map · b51fdcbe
      Mike Kravetz 提交于
      [ Upstream commit 58b6e5e8f1addd44583d61b0a03c0f5519527e35 ]
      
      When mknod is used to create a block special file in hugetlbfs, it will
      allocate an inode and kmalloc a 'struct resv_map' via resv_map_alloc().
      inode->i_mapping->private_data will point the newly allocated resv_map.
      However, when the device special file is opened bd_acquire() will set
      inode->i_mapping to bd_inode->i_mapping.  Thus the pointer to the
      allocated resv_map is lost and the structure is leaked.
      
      Programs to reproduce:
              mount -t hugetlbfs nodev hugetlbfs
              mknod hugetlbfs/dev b 0 0
              exec 30<> hugetlbfs/dev
              umount hugetlbfs/
      
      resv_map structures are only needed for inodes which can have associated
      page allocations.  To fix the leak, only allocate resv_map for those
      inodes which could possibly be associated with page allocations.
      
      Link: http://lkml.kernel.org/r/20190401213101.16476-1-mike.kravetz@oracle.comSigned-off-by: NMike Kravetz <mike.kravetz@oracle.com>
      Reviewed-by: NAndrew Morton <akpm@linux-foundation.org>
      Reported-by: NYufen Yu <yuyufen@huawei.com>
      Suggested-by: NYufen Yu <yuyufen@huawei.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      b51fdcbe
    • A
      debugfs: fix use-after-free on symlink traversal · f0112b64
      Al Viro 提交于
      [ Upstream commit 93b919da64c15b90953f96a536e5e61df896ca57 ]
      
      symlink body shouldn't be freed without an RCU delay.  Switch debugfs to
      ->destroy_inode() and use of call_rcu(); free both the inode and symlink
      body in the callback.  Similar to solution for bpf, only here it's even
      more obvious that ->evict_inode() can be dropped.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      f0112b64
    • A
      jffs2: fix use-after-free on symlink traversal · e22c11da
      Al Viro 提交于
      [ Upstream commit 4fdcfab5b5537c21891e22e65996d4d0dd8ab4ca ]
      
      free the symlink body after the same RCU delay we have for freeing the
      struct inode itself, so that traversal during RCU pathwalk wouldn't step
      into freed memory.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      e22c11da
  4. 04 5月, 2019 3 次提交
  5. 02 5月, 2019 8 次提交
    • A
      Fix aio_poll() races · e9e47779
      Al Viro 提交于
      commit af5c72b1fc7a00aa484e90b0c4e0eeb582545634 upstream.
      
      aio_poll() has to cope with several unpleasant problems:
      	* requests that might stay around indefinitely need to
      be made visible for io_cancel(2); that must not be done to
      a request already completed, though.
      	* in cases when ->poll() has placed us on a waitqueue,
      wakeup might have happened (and request completed) before ->poll()
      returns.
      	* worse, in some early wakeup cases request might end
      up re-added into the queue later - we can't treat "woken up and
      currently not in the queue" as "it's not going to stick around
      indefinitely"
      	* ... moreover, ->poll() might have decided not to
      put it on any queues to start with, and that needs to be distinguished
      from the previous case
      	* ->poll() might have tried to put us on more than one queue.
      Only the first will succeed for aio poll, so we might end up missing
      wakeups.  OTOH, we might very well notice that only after the
      wakeup hits and request gets completed (all before ->poll() gets
      around to the second poll_wait()).  In that case it's too late to
      decide that we have an error.
      
      req->woken was an attempt to deal with that.  Unfortunately, it was
      broken.  What we need to keep track of is not that wakeup has happened -
      the thing might come back after that.  It's that async reference is
      already gone and won't come back, so we can't (and needn't) put the
      request on the list of cancellables.
      
      The easiest case is "request hadn't been put on any waitqueues"; we
      can tell by seeing NULL apt.head, and in that case there won't be
      anything async.  We should either complete the request ourselves
      (if vfs_poll() reports anything of interest) or return an error.
      
      In all other cases we get exclusion with wakeups by grabbing the
      queue lock.
      
      If request is currently on queue and we have something interesting
      from vfs_poll(), we can steal it and complete the request ourselves.
      
      If it's on queue and vfs_poll() has not reported anything interesting,
      we either put it on the cancellable list, or, if we know that it
      hadn't been put on all queues ->poll() wanted it on, we steal it and
      return an error.
      
      If it's _not_ on queue, it's either been already dealt with (in which
      case we do nothing), or there's aio_poll_complete_work() about to be
      executed.  In that case we either put it on the cancellable list,
      or, if we know it hadn't been put on all queues ->poll() wanted it on,
      simulate what cancel would've done.
      
      It's a lot more convoluted than I'd like it to be.  Single-consumer APIs
      suck, and unfortunately aio is not an exception...
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e9e47779
    • A
      aio: store event at final iocb_put() · aab66dfb
      Al Viro 提交于
      commit 2bb874c0d873d13bd9b9b9c6d7b7c4edab18c8b4 upstream.
      
      Instead of having aio_complete() set ->ki_res.{res,res2}, do that
      explicitly in its callers, drop the reference (as aio_complete()
      used to do) and delay the rest until the final iocb_put().
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      aab66dfb
    • A
      aio: keep io_event in aio_kiocb · c20202c5
      Al Viro 提交于
      commit a9339b7855094ba11a97e8822ae038135e879e79 upstream.
      
      We want to separate forming the resulting io_event from putting it
      into the ring buffer.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c20202c5
    • A
      aio: fold lookup_kiocb() into its sole caller · 592ea630
      Al Viro 提交于
      commit 833f4154ed560232120bc475935ee1d6a20e159f upstream.
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      592ea630
    • L
      pin iocb through aio. · c7f2525a
      Linus Torvalds 提交于
      commit b53119f13a04879c3bf502828d99d13726639ead upstream.
      
      aio_poll() is not the only case that needs file pinned; worse, while
      aio_read()/aio_write() can live without pinning iocb itself, the
      proof is rather brittle and can easily break on later changes.
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c7f2525a
    • L
      aio: simplify - and fix - fget/fput for io_submit() · d6b2615f
      Linus Torvalds 提交于
      commit 84c4e1f89fefe70554da0ab33be72c9be7994379 upstream.
      
      Al Viro root-caused a race where the IOCB_CMD_POLL handling of
      fget/fput() could cause us to access the file pointer after it had
      already been freed:
      
       "In more details - normally IOCB_CMD_POLL handling looks so:
      
         1) io_submit(2) allocates aio_kiocb instance and passes it to
            aio_poll()
      
         2) aio_poll() resolves the descriptor to struct file by req->file =
            fget(iocb->aio_fildes)
      
         3) aio_poll() sets ->woken to false and raises ->ki_refcnt of that
            aio_kiocb to 2 (bumps by 1, that is).
      
         4) aio_poll() calls vfs_poll(). After sanity checks (basically,
            "poll_wait() had been called and only once") it locks the queue.
            That's what the extra reference to iocb had been for - we know we
            can safely access it.
      
         5) With queue locked, we check if ->woken has already been set to
            true (by aio_poll_wake()) and, if it had been, we unlock the
            queue, drop a reference to aio_kiocb and bugger off - at that
            point it's a responsibility to aio_poll_wake() and the stuff
            called/scheduled by it. That code will drop the reference to file
            in req->file, along with the other reference to our aio_kiocb.
      
         6) otherwise, we see whether we need to wait. If we do, we unlock the
            queue, drop one reference to aio_kiocb and go away - eventual
            wakeup (or cancel) will deal with the reference to file and with
            the other reference to aio_kiocb
      
         7) otherwise we remove ourselves from waitqueue (still under the
            queue lock), so that wakeup won't get us. No async activity will
            be happening, so we can safely drop req->file and iocb ourselves.
      
        If wakeup happens while we are in vfs_poll(), we are fine - aio_kiocb
        won't get freed under us, so we can do all the checks and locking
        safely. And we don't touch ->file if we detect that case.
      
        However, vfs_poll() most certainly *does* touch the file it had been
        given. So wakeup coming while we are still in ->poll() might end up
        doing fput() on that file. That case is not too rare, and usually we
        are saved by the still present reference from descriptor table - that
        fput() is not the final one.
      
        But if another thread closes that descriptor right after our fget()
        and wakeup does happen before ->poll() returns, we are in trouble -
        final fput() done while we are in the middle of a method:
      
      Al also wrote a patch to take an extra reference to the file descriptor
      to fix this, but I instead suggested we just streamline the whole file
      pointer handling by submit_io() so that the generic aio submission code
      simply keeps the file pointer around until the aio has completed.
      
      Fixes: bfe4037e ("aio: implement IOCB_CMD_POLL")
      Acked-by: NAl Viro <viro@zeniv.linux.org.uk>
      Reported-by: syzbot+503d4cc169fcec1cb18c@syzkaller.appspotmail.com
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d6b2615f
    • M
      aio: initialize kiocb private in case any filesystems expect it. · 2afa01cd
      Mike Marshall 提交于
      commit ec51f8ee1e63498e9f521ec0e5a6d04622bb2c67 upstream.
      
      A recent optimization had left private uninitialized.
      
      Fixes: 2bc4ca9bb600 ("aio: don't zero entire aio_kiocb aio_get_req()")
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NMike Marshall <hubcap@omnibond.com>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2afa01cd
    • J
      aio: abstract out io_event filler helper · a812f7b6
      Jens Axboe 提交于
      commit 875736bb3f3ded168469f6a14df7a938416a99d5 upstream.
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NJens Axboe <axboe@kernel.dk>
      Cc: Guenter Roeck <linux@roeck-us.net>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a812f7b6