1. 08 Nov, 2017 6 commits
  2. 02 Nov, 2017 24 commits
  3. 27 Oct, 2017 10 commits
    • Greg Kroah-Hartman's avatar
      Linux 4.9.59 · d785062e
      Greg Kroah-Hartman authored
      d785062e
    • Eric Biggers's avatar
      FS-Cache: fix dereference of NULL user_key_payload · d2d576e2
      Eric Biggers authored
      commit d124b2c5 upstream.
      
      When the file /proc/fs/fscache/objects (available with
      CONFIG_FSCACHE_OBJECT_LIST=y) is opened, we request a user key with
      description "fscache:objlist", then access its payload.  However, a
      revoked key has a NULL payload, and we failed to check for this.
      request_key() *does* skip revoked keys, but there is still a window
      where the key can be revoked before we access its payload.
      
      Fix it by checking for a NULL payload, treating it like a key which was
      already revoked at the time it was requested.
      
      Fixes: 4fbf4291 ("FS-Cache: Allow the current state of all objects to be dumped")
      Reviewed-by: default avatarJames Morris <james.l.morris@oracle.com>
      Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d2d576e2
    • David Howells's avatar
      KEYS: Fix race between updating and finding a negative key · 63c8e452
      David Howells authored
      commit 363b02da upstream.
      
      Consolidate KEY_FLAG_INSTANTIATED, KEY_FLAG_NEGATIVE and the rejection
      error into one field such that:
      
       (1) The instantiation state can be modified/read atomically.
      
       (2) The error can be accessed atomically with the state.
      
       (3) The error isn't stored unioned with the payload pointers.
      
      This deals with the problem that the state is spread over three different
      objects (two bits and a separate variable) and reading or updating them
      atomically isn't practical, given that not only can uninstantiated keys
      change into instantiated or rejected keys, but rejected keys can also turn
      into instantiated keys - and someone accessing the key might not be using
      any locking.
      
      The main side effect of this problem is that what was held in the payload
      may change, depending on the state.  For instance, you might observe the
      key to be in the rejected state.  You then read the cached error, but if
      the key semaphore wasn't locked, the key might've become instantiated
      between the two reads - and you might now have something in hand that isn't
      actually an error code.
      
      The state is now KEY_IS_UNINSTANTIATED, KEY_IS_POSITIVE or a negative error
      code if the key is negatively instantiated.  The key_is_instantiated()
      function is replaced with key_is_positive() to avoid confusion as negative
      keys are also 'instantiated'.
      
      Additionally, barriering is included:
      
       (1) Order payload-set before state-set during instantiation.
      
       (2) Order state-read before payload-read when using the key.
      
      Further separate barriering is necessary if RCU is being used to access the
      payload content after reading the payload pointers.
      
      Fixes: 146aa8b1 ("KEYS: Merge the type-specific data with the payload data")
      Reported-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      63c8e452
    • Eric Biggers's avatar
      fscrypt: fix dereference of NULL user_key_payload · b2ac5d45
      Eric Biggers authored
      commit d60b5b78 upstream.
      
      When an fscrypt-encrypted file is opened, we request the file's master
      key from the keyrings service as a logon key, then access its payload.
      However, a revoked key has a NULL payload, and we failed to check for
      this.  request_key() *does* skip revoked keys, but there is still a
      window where the key can be revoked before we acquire its semaphore.
      
      Fix it by checking for a NULL payload, treating it like a key which was
      already revoked at the time it was requested.
      
      Fixes: 88bd6ccd ("ext4 crypto: add encryption key management facilities")
      Reviewed-by: default avatarJames Morris <james.l.morris@oracle.com>
      Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      
      b2ac5d45
    • Brian Foster's avatar
      xfs: trim writepage mapping to within eof · f374505b
      Brian Foster authored
      commit 40214d12 upstream.
      
      The writeback rework in commit fbcc0256 ("xfs: Introduce
      writeback context for writepages") introduced a subtle change in
      behavior with regard to the block mapping used across the
      ->writepages() sequence. The previous xfs_cluster_write() code would
      only flush pages up to EOF at the time of the writepage, thus
      ensuring that any pages due to file-extending writes would be
      handled on a separate cycle and with a new, updated block mapping.
      
      The updated code establishes a block mapping in xfs_writepage_map()
      that could extend beyond EOF if the file has post-eof preallocation.
      Because we now use the generic writeback infrastructure and pass the
      cached mapping to each writepage call, there is no implicit EOF
      limit in place. If eofblocks trimming occurs during ->writepages(),
      any post-eof portion of the cached mapping becomes invalid. The
      eofblocks code has no means to serialize against writeback because
      there are no pages associated with post-eof blocks. Therefore if an
      eofblocks trim occurs and is followed by a file-extending buffered
      write, not only has the mapping become invalid, but we could end up
      writing a page to disk based on the invalid mapping.
      
      Consider the following sequence of events:
      
      - A buffered write creates a delalloc extent and post-eof
        speculative preallocation.
      - Writeback starts and on the first writepage cycle, the delalloc
        extent is converted to real blocks (including the post-eof blocks)
        and the mapping is cached.
      - The file is closed and xfs_release() trims post-eof blocks. The
        cached writeback mapping is now invalid.
      - Another buffered write appends the file with a delalloc extent.
      - The concurrent writeback cycle picks up the just written page
        because the writeback range end is LLONG_MAX. xfs_writepage_map()
        attributes it to the (now invalid) cached mapping and writes the
        data to an incorrect location on disk (and where the file offset is
        still backed by a delalloc extent).
      
      This problem is reproduced by xfstests test generic/464, which
      triggers racing writes, appends, open/closes and writeback requests.
      
      To address this problem, trim the mapping used during writeback to
      within EOF when the mapping is validated. This ensures the mapping
      is revalidated for any pages encountered beyond EOF as of the time
      the current mapping was cached or last validated.
      Reported-by: default avatarEryu Guan <eguan@redhat.com>
      Diagnosed-by: default avatarEryu Guan <eguan@redhat.com>
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f374505b
    • Dave Chinner's avatar
      xfs: cancel dirty pages on invalidation · 245262c6
      Dave Chinner authored
      commit 793d7dbe upstream.
      
      Recently we've had warnings arise from the vm handing us pages
      without bufferheads attached to them. This should not ever occur
      in XFS, but we don't defend against it properly if it does. The only
      place where we remove bufferheads from a page is in
      xfs_vm_releasepage(), but we can't tell the difference here between
      "page is dirty so don't release" and "page is dirty but is being
      invalidated so release it".
      
      In some places that are invalidating pages ask for pages to be
      released and follow up afterward calling ->releasepage by checking
      whether the page was dirty and then aborting the invalidation. This
      is a possible vector for releasing buffers from a page but then
      leaving it in the mapping, so we really do need to avoid dirty pages
      in xfs_vm_releasepage().
      
      To differentiate between invalidated pages and normal pages, we need
      to clear the page dirty flag when invalidating the pages. This can
      be done through xfs_vm_invalidatepage(), and will result
      xfs_vm_releasepage() seeing the page as clean which matches the
      bufferhead state on the page after calling block_invalidatepage().
      
      Hence we can re-add the page dirty check in xfs_vm_releasepage to
      catch the case where we might be releasing a page that is actually
      dirty and so should not have the bufferheads on it removed. This
      will remove one possible vector of "dirty page with no bufferheads"
      and so help narrow down the search for the root cause of that
      problem.
      Signed-Off-By: default avatarDave Chinner <dchinner@redhat.com>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      245262c6
    • Eric Sandeen's avatar
      xfs: handle error if xfs_btree_get_bufs fails · 67d73f41
      Eric Sandeen authored
      commit 93e8befc upstream.
      
      Jason reported that a corrupted filesystem failed to replay
      the log with a metadata block out of bounds warning:
      
      XFS (dm-2): _xfs_buf_find: Block out of range: block 0x80270fff8, EOFS 0x9c40000
      
      _xfs_buf_find() and xfs_btree_get_bufs() return NULL if
      that happens, and then when xfs_alloc_fix_freelist() calls
      xfs_trans_binval() on that NULL bp, we oops with:
      
      BUG: unable to handle kernel NULL pointer dereference at 00000000000000f8
      
      We don't handle _xfs_buf_find errors very well, every
      caller higher up the stack gets to guess at why it failed.
      But we should at least handle it somehow, so return
      EFSCORRUPTED here.
      Reported-by: default avatarJason L Tibbitts III <tibbs@math.uh.edu>
      Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      67d73f41
    • Brian Foster's avatar
      xfs: reinit btree pointer on attr tree inactivation walk · fee940a8
      Brian Foster authored
      commit f35c5e10 upstream.
      
      xfs_attr3_root_inactive() walks the attr fork tree to invalidate the
      associated blocks. xfs_attr3_node_inactive() recursively descends
      from internal blocks to leaf blocks, caching block address values
      along the way to revisit parent blocks, locate the next entry and
      descend down that branch of the tree.
      
      The code that attempts to reread the parent block is unsafe because
      it assumes that the local xfs_da_node_entry pointer remains valid
      after an xfs_trans_brelse() and re-read of the parent buffer. Under
      heavy memory pressure, it is possible that the buffer has been
      reclaimed and reallocated by the time the parent block is reread.
      This means that 'btree' can point to an invalid memory address, lead
      to a random/garbage value for child_fsb and cause the subsequent
      read of the attr fork to go off the rails and return a NULL buffer
      for an attr fork offset that is most likely not allocated.
      
      Note that this problem can be manufactured by setting
      XFS_ATTR_BTREE_REF to 0 to prevent LRU caching of attr buffers,
      creating a file with a multi-level attr fork and removing it to
      trigger inactivation.
      
      To address this problem, reinit the node/btree pointers to the
      parent buffer after it has been re-read. This ensures btree points
      to a valid record and allows the walk to proceed.
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      fee940a8
    • Dave Chinner's avatar
      xfs: don't change inode mode if ACL update fails · 0fe7d85b
      Dave Chinner authored
      commit 67f2ffe3 upstream.
      
      If we get ENOSPC half way through setting the ACL, the inode mode
      can still be changed even though the ACL does not exist. Reorder the
      operation to only change the mode of the inode if the ACL is set
      correctly.
      
      Whilst this does not fix the problem with crash consistency (that requires
      attribute addition to be a deferred op) it does prevent ENOSPC and other
      non-fatal errors setting an xattr to be handled sanely.
      
      This fixes xfstests generic/449.
      Signed-Off-By: default avatarDave Chinner <dchinner@redhat.com>
      Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      0fe7d85b
    • Dave Chinner's avatar
      xfs: move more RT specific code under CONFIG_XFS_RT · 3a5a338a
      Dave Chinner authored
      commit bb9c2e54 upstream.
      
      Various utility functions and interfaces that iterate internal
      devices try to reference the realtime device even when RT support is
      not compiled into the kernel.
      
      Make sure this code is excluded from the CONFIG_XFS_RT=n build,
      and where appropriate stub functions to return fatal errors if
      they ever get called when RT support is not present.
      Signed-Off-By: default avatarDave Chinner <dchinner@redhat.com>
      Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3a5a338a