1. 21 3月, 2022 1 次提交
  2. 17 2月, 2022 2 次提交
  3. 06 12月, 2021 1 次提交
  4. 09 4月, 2021 2 次提交
  5. 12 11月, 2020 2 次提交
  6. 17 9月, 2020 1 次提交
    • J
      nfs: Fix security label length not being reset · d33030e2
      Jeffrey Mitchell 提交于
      nfs_readdir_page_filler() iterates over entries in a directory, reusing
      the same security label buffer, but does not reset the buffer's length.
      This causes decode_attr_security_label() to return -ERANGE if an entry's
      security label is longer than the previous one's. This error, in
      nfs4_decode_dirent(), only gets passed up as -EAGAIN, which causes another
      failed attempt to copy into the buffer. The second error is ignored and
      the remaining entries do not show up in ls, specifically the getdents64()
      syscall.
      
      Reproduce by creating multiple files in NFS and giving one of the later
      files a longer security label. ls will not see that file nor any that are
      added afterwards, though they will exist on the backend.
      
      In nfs_readdir_page_filler(), reset security label buffer length before
      every reuse
      Signed-off-by: NJeffrey Mitchell <jeffrey.mitchell@starlab.io>
      Fixes: b4487b93 ("nfs: Fix getxattr kernel panic and memory overflow")
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      d33030e2
  7. 24 8月, 2020 1 次提交
  8. 14 7月, 2020 2 次提交
  9. 07 4月, 2020 1 次提交
  10. 16 3月, 2020 4 次提交
    • G
      nfs: Replace zero-length array with flexible-array member · 5601cda8
      Gustavo A. R. Silva 提交于
      The current codebase makes use of the zero-length array language
      extension to the C90 standard, but the preferred mechanism to declare
      variable-length types such as these ones is a flexible array member[1][2],
      introduced in C99:
      
      struct foo {
              int stuff;
              struct boo array[];
      };
      
      By making use of the mechanism above, we will get a compiler warning
      in case the flexible array does not occur last in the structure, which
      will help us prevent some kind of undefined behavior bugs from being
      inadvertently introduced[3] to the codebase from now on.
      
      Also, notice that, dynamic memory allocations won't be affected by
      this change:
      
      "Flexible array members have incomplete type, and so the sizeof operator
      may not be applied. As a quirk of the original implementation of
      zero-length arrays, sizeof evaluates to zero."[1]
      
      This issue was found with the help of Coccinelle.
      
      [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
      [2] https://github.com/KSPP/linux/issues/21
      [3] commit 76497732 ("cxgb3/l2t: Fix undefined behaviour")
      Signed-off-by: NGustavo A. R. Silva <gustavo@embeddedor.com>
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      5601cda8
    • Z
      NFS:remove redundant call to nfs_do_access · eb095c14
      Zhouyi Zhou 提交于
      In function nfs_permission:
      1. the rcu_read_lock and rcu_read_unlock around nfs_do_access
      is unnecessary because the rcu critical data structure is already
      protected in subsidiary function nfs_access_get_cached_rcu. No other
      data structure needs rcu_read_lock in nfs_do_access.
      
      2. call nfs_do_access once is enough, because:
      2-1. when mask has MAY_NOT_BLOCK bit
      The second call to nfs_do_access will not happen.
      
      2-2. when mask has no MAY_NOT_BLOCK bit
      The second call to nfs_do_access will happen if res == -ECHILD, which
      means the first nfs_do_access goes out after statement if (!may_block).
      The second call to nfs_do_access will go through this procedure once
      again except continue the work after if (!may_block).
      But above work can be performed by only one call to nfs_do_access
      without mangling the mask flag.
      
      Tested in x86_64
      Signed-off-by: NZhouyi Zhou <zhouzhouyi@gmail.com>
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      eb095c14
    • T
      NFS: Limit the size of the access cache by default · a8b373ee
      Trond Myklebust 提交于
      Currently, we have no real limit on the access cache size (we set it
      to ULONG_MAX). That can lead to credentials getting pinned for a
      very long time on lots of files if you have a system with a lot of
      memory.
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      a8b373ee
    • T
      NFS: Use the 64-bit server readdir cookies when possible · 59e356a9
      Trond Myklebust 提交于
      When we're running as a 64-bit architecture and are not running in
      32-bit compatibility mode, it is better to use the 64-bit readdir
      cookies that supplied by the server. Doing so improves the accuracy
      of telldir()/seekdir(), particularly when the directory is changing,
      for instance, when doing 'rm -rf'.
      
      We still fall back to using the 32-bit offsets on 32-bit architectures
      and when in compatibility mode.
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      59e356a9
  11. 21 2月, 2020 1 次提交
  12. 13 2月, 2020 1 次提交
  13. 10 2月, 2020 1 次提交
  14. 04 2月, 2020 6 次提交
  15. 25 1月, 2020 1 次提交
  16. 15 1月, 2020 2 次提交
  17. 21 9月, 2019 2 次提交
  18. 19 8月, 2019 1 次提交
  19. 13 7月, 2019 1 次提交
    • M
      Revert "NFS: readdirplus optimization by cache mechanism" (memleak) · db531db9
      Max Kellermann 提交于
      This reverts commit be4c2d47.
      
      That commit caused a severe memory leak in nfs_readdir_make_qstr().
      
      When listing a directory with more than 100 files (this is how many
      struct nfs_cache_array_entry elements fit in one 4kB page), all
      allocated file name strings past those 100 leak.
      
      The root of the leakage is that those string pointers are managed in
      pages which are never linked into the page cache.
      
      fs/nfs/dir.c puts pages into the page cache by calling
      read_cache_page(); the callback function nfs_readdir_filler() will
      then fill the given page struct which was passed to it, which is
      already linked in the page cache (by do_read_cache_page() calling
      add_to_page_cache_lru()).
      
      Commit be4c2d47 added another (local) array of allocated pages, to
      be filled with more data, instead of discarding excess items received
      from the NFS server.  Those additional pages can be used by the next
      nfs_readdir_filler() call (from within the same nfs_readdir() call).
      
      The leak happens when some of those additional pages are never used
      (copied to the page cache using copy_highpage()).  The pages will be
      freed by nfs_readdir_free_pages(), but their contents will not.  The
      commit did not invoke nfs_readdir_clear_array() (and doing so would
      have been dangerous, because it did not track which of those pages
      were already copied to the page cache, risking double free bugs).
      
      How to reproduce the leak:
      
      - Use a kernel with CONFIG_SLUB_DEBUG_ON.
      
      - Create a directory on a NFS mount with more than 100 files with
        names long enough to use the "kmalloc-32" slab (so we can easily
        look up the allocation counts):
      
        for i in `seq 110`; do touch ${i}_0123456789abcdef; done
      
      - Drop all caches:
      
        echo 3 >/proc/sys/vm/drop_caches
      
      - Check the allocation counter:
      
        grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
        30564391 nfs_readdir_add_to_array+0x73/0xd0 age=534558/4791307/6540952 pid=370-1048386 cpus=0-47 nodes=0-1
      
      - Request a directory listing and check the allocation counters again:
      
        ls
        [...]
        grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
        30564511 nfs_readdir_add_to_array+0x73/0xd0 age=207/4792999/6542663 pid=370-1048386 cpus=0-47 nodes=0-1
      
      There are now 120 new allocations.
      
      - Drop all caches and check the counters again:
      
        echo 3 >/proc/sys/vm/drop_caches
        grep nfs_readdir /sys/kernel/slab/kmalloc-32/alloc_calls
        30564401 nfs_readdir_add_to_array+0x73/0xd0 age=735/4793524/6543176 pid=370-1048386 cpus=0-47 nodes=0-1
      
      110 allocations are gone, but 10 have leaked and will never be freed.
      
      Unhelpfully, those allocations are explicitly excluded from KMEMLEAK,
      that's why my initial attempts with KMEMLEAK were not successful:
      
      	/*
      	 * Avoid a kmemleak false positive. The pointer to the name is stored
      	 * in a page cache page which kmemleak does not scan.
      	 */
      	kmemleak_not_leak(string->name);
      
      It would be possible to solve this bug without reverting the whole
      commit:
      
      - keep track of which pages were not used, and call
        nfs_readdir_clear_array() on them, or
      - manually link those pages into the page cache
      
      But for now I have decided to just revert the commit, because the real
      fix would require complex considerations, risking more dangerous
      (crash) bugs, which may seem unsuitable for the stable branches.
      Signed-off-by: NMax Kellermann <mk@cm4all.com>
      Cc: stable@vger.kernel.org # v5.1+
      Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
      db531db9
  20. 07 7月, 2019 1 次提交
  21. 21 5月, 2019 1 次提交
  22. 10 5月, 2019 1 次提交
  23. 21 2月, 2019 4 次提交