Skip to content
Snippets Groups Projects
  1. Dec 31, 2022
    • Chen Zhongjin's avatar
      configfs: fix possible memory leak in configfs_create_dir() · c72eb6e6
      Chen Zhongjin authored
      
      [ Upstream commit c65234b2 ]
      
      kmemleak reported memory leaks in configfs_create_dir():
      
      unreferenced object 0xffff888009f6af00 (size 192):
        comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s)
        backtrace:
          kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273)
          new_fragment (./include/linux/slab.h:600 fs/configfs/dir.c:163)
          configfs_register_subsystem (fs/configfs/dir.c:1857)
          basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic
          do_one_initcall (init/main.c:1296)
          do_init_module (kernel/module/main.c:2455)
          ...
      
      unreferenced object 0xffff888003ba7180 (size 96):
        comm "modprobe", pid 3777, jiffies 4295537735 (age 233.784s)
        backtrace:
          kmem_cache_alloc (mm/slub.c:3250 mm/slub.c:3256 mm/slub.c:3263 mm/slub.c:3273)
          configfs_new_dirent (./include/linux/slab.h:723 fs/configfs/dir.c:194)
          configfs_make_dirent (fs/configfs/dir.c:248)
          configfs_create_dir (fs/configfs/dir.c:296)
          configfs_attach_group.isra.28 (fs/configfs/dir.c:816 fs/configfs/dir.c:852)
          configfs_register_subsystem (fs/configfs/dir.c:1881)
          basic_write (drivers/hwtracing/stm/p_basic.c:14) stm_p_basic
          do_one_initcall (init/main.c:1296)
          do_init_module (kernel/module/main.c:2455)
          ...
      
      This is because the refcount is not correct in configfs_make_dirent().
      For normal stage, the refcount is changing as:
      
      configfs_register_subsystem()
        configfs_create_dir()
          configfs_make_dirent()
            configfs_new_dirent() # set s_count = 1
            dentry->d_fsdata = configfs_get(sd); # s_count = 2
      ...
      configfs_unregister_subsystem()
        configfs_remove_dir()
          remove_dir()
            configfs_remove_dirent() # s_count = 1
          dput() ...
            *dentry_unlink_inode()*
              configfs_d_iput() # s_count = 0, release
      
      However, if we failed in configfs_create():
      
      configfs_register_subsystem()
        configfs_create_dir()
          configfs_make_dirent() # s_count = 2
          ...
          configfs_create() # fail
          ->out_remove:
          configfs_remove_dirent(dentry)
            configfs_put(sd) # s_count = 1
            return PTR_ERR(inode);
      
      There is no inode in the error path, so the configfs_d_iput() is lost
      and makes sd and fragment memory leaked.
      
      To fix this, when we failed in configfs_create(), manually call
      configfs_put(sd) to keep the refcount correct.
      
      Fixes: 7063fbf2 ("[PATCH] configfs: User-driven configuration filesystem")
      Signed-off-by: default avatarChen Zhongjin <chenzhongjin@huawei.com>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
      c72eb6e6
  2. Feb 22, 2022
    • ChenXiaoSong's avatar
      configfs: fix a race in configfs_{,un}register_subsystem() · 84ec758f
      ChenXiaoSong authored
      
      When configfs_register_subsystem() or configfs_unregister_subsystem()
      is executing link_group() or unlink_group(),
      it is possible that two processes add or delete list concurrently.
      Some unfortunate interleavings of them can cause kernel panic.
      
      One of cases is:
      A --> B --> C --> D
      A <-- B <-- C <-- D
      
           delete list_head *B        |      delete list_head *C
      --------------------------------|-----------------------------------
      configfs_unregister_subsystem   |   configfs_unregister_subsystem
        unlink_group                  |     unlink_group
          unlink_obj                  |       unlink_obj
            list_del_init             |         list_del_init
              __list_del_entry        |           __list_del_entry
                __list_del            |             __list_del
                  // next == C        |
                  next->prev = prev   |
                                      |               next->prev = prev
                  prev->next = next   |
                                      |                 // prev == B
                                      |                 prev->next = next
      
      Fix this by adding mutex when calling link_group() or unlink_group(),
      but parent configfs_subsystem is NULL when config_item is root.
      So I create a mutex configfs_subsystem_mutex.
      
      Fixes: 7063fbf2 ("[PATCH] configfs: User-driven configuration filesystem")
      Signed-off-by: default avatarChenXiaoSong <chenxiaosong2@huawei.com>
      Signed-off-by: default avatarLaibin Qiu <qiulaibin@huawei.com>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      84ec758f
  3. Jan 24, 2022
  4. Aug 25, 2021
  5. Aug 09, 2021
  6. Jul 13, 2021
    • Bart Van Assche's avatar
      configfs: fix the read and write iterators · 420405ec
      Bart Van Assche authored
      
      Commit 7fe1e79b ("configfs: implement the .read_iter and .write_iter
      methods") changed the simple_read_from_buffer() calls into copy_to_iter()
      calls and the simple_write_to_buffer() calls into copy_from_iter() calls.
      The simple*buffer() methods update the file offset (*ppos) but the read
      and write iterators not yet. Make the read and write iterators update the
      file offset (iocb->ki_pos).
      
      This patch has been tested as follows:
      
       # modprobe target_core_user
       # dd if=/sys/kernel/config/target/dbroot bs=1
      /var/target
      12+0 records in
      12+0 records out
      12 bytes copied, 9.5539e-05 s, 126 kB/s
      
       # cd /sys/kernel/config/acpi/table
       # mkdir test
       # cd test
       # dmesg -c >/dev/null; printf 'SSDT\x8\0\0\0abcdefghijklmnopqrstuvwxyz' | dd of=aml bs=1; dmesg -c
      34+0 records in
      34+0 records out
      34 bytes copied, 0.010627 s, 3.2 kB/s
      [  261.056551] ACPI configfs: invalid table length
      
      Reported-by: default avatarYanko Kaneti <yaneti@declera.com>
      Cc: Yanko Kaneti <yaneti@declera.com>
      Fixes: 7fe1e79b ("configfs: implement the .read_iter and .write_iter methods")
      Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      420405ec
  7. Jun 29, 2021
  8. Jun 22, 2021
  9. May 25, 2021
  10. May 07, 2021
  11. Mar 11, 2021
    • Daiyue Zhang's avatar
      configfs: fix a use-after-free in __configfs_open_file · 14fbbc82
      Daiyue Zhang authored
      
      Commit b0841eef ("configfs: provide exclusion between IO and removals")
      uses ->frag_dead to mark the fragment state, thus no bothering with extra
      refcount on config_item when opening a file. The configfs_get_config_item
      was removed in __configfs_open_file, but not with config_item_put. So the
      refcount on config_item will lost its balance, causing use-after-free
      issues in some occasions like this:
      
      Test:
      1. Mount configfs on /config with read-only items:
      drwxrwx--- 289 root   root            0 2021-04-01 11:55 /config
      drwxr-xr-x   2 root   root            0 2021-04-01 11:54 /config/a
      --w--w--w-   1 root   root         4096 2021-04-01 11:53 /config/a/1.txt
      ......
      
      2. Then run:
      for file in /config
      do
      echo $file
      grep -R 'key' $file
      done
      
      3. __configfs_open_file will be called in parallel, the first one
      got called will do:
      if (file->f_mode & FMODE_READ) {
      	if (!(inode->i_mode & S_IRUGO))
      		goto out_put_module;
      			config_item_put(buffer->item);
      				kref_put()
      					package_details_release()
      						kfree()
      
      the other one will run into use-after-free issues like this:
      BUG: KASAN: use-after-free in __configfs_open_file+0x1bc/0x3b0
      Read of size 8 at addr fffffff155f02480 by task grep/13096
      CPU: 0 PID: 13096 Comm: grep VIP: 00 Tainted: G        W       4.14.116-kasan #1
      TGID: 13096 Comm: grep
      Call trace:
      dump_stack+0x118/0x160
      kasan_report+0x22c/0x294
      __asan_load8+0x80/0x88
      __configfs_open_file+0x1bc/0x3b0
      configfs_open_file+0x28/0x34
      do_dentry_open+0x2cc/0x5c0
      vfs_open+0x80/0xe0
      path_openat+0xd8c/0x2988
      do_filp_open+0x1c4/0x2fc
      do_sys_open+0x23c/0x404
      SyS_openat+0x38/0x48
      
      Allocated by task 2138:
      kasan_kmalloc+0xe0/0x1ac
      kmem_cache_alloc_trace+0x334/0x394
      packages_make_item+0x4c/0x180
      configfs_mkdir+0x358/0x740
      vfs_mkdir2+0x1bc/0x2e8
      SyS_mkdirat+0x154/0x23c
      el0_svc_naked+0x34/0x38
      
      Freed by task 13096:
      kasan_slab_free+0xb8/0x194
      kfree+0x13c/0x910
      package_details_release+0x524/0x56c
      kref_put+0xc4/0x104
      config_item_put+0x24/0x34
      __configfs_open_file+0x35c/0x3b0
      configfs_open_file+0x28/0x34
      do_dentry_open+0x2cc/0x5c0
      vfs_open+0x80/0xe0
      path_openat+0xd8c/0x2988
      do_filp_open+0x1c4/0x2fc
      do_sys_open+0x23c/0x404
      SyS_openat+0x38/0x48
      el0_svc_naked+0x34/0x38
      
      To fix this issue, remove the config_item_put in
      __configfs_open_file to balance the refcount of config_item.
      
      Fixes: b0841eef ("configfs: provide exclusion between IO and removals")
      Signed-off-by: default avatarDaiyue Zhang <zhangdaiyue1@huawei.com>
      Signed-off-by: default avatarYi Chen <chenyi77@huawei.com>
      Signed-off-by: default avatarGe Qiu <qiuge@huawei.com>
      Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
      Acked-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      14fbbc82
  12. Jan 24, 2021
  13. Nov 14, 2020
  14. Oct 16, 2020
  15. Aug 23, 2020
  16. May 05, 2020
  17. Apr 27, 2020
    • Xiyu Yang's avatar
      configfs: fix config_item refcnt leak in configfs_rmdir() · 8aebfffa
      Xiyu Yang authored
      
      configfs_rmdir() invokes configfs_get_config_item(), which returns a
      reference of the specified config_item object to "parent_item" with
      increased refcnt.
      
      When configfs_rmdir() returns, local variable "parent_item" becomes
      invalid, so the refcount should be decreased to keep refcount balanced.
      
      The reference counting issue happens in one exception handling path of
      configfs_rmdir(). When down_write_killable() fails, the function forgets
      to decrease the refcnt increased by configfs_get_config_item(), causing
      a refcnt leak.
      
      Fix this issue by calling config_item_put() when down_write_killable()
      fails.
      
      Signed-off-by: default avatarXiyu Yang <xiyuyang19@fudan.edu.cn>
      Signed-off-by: default avatarXin Tan <tanxin.ctf@gmail.com>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      8aebfffa
  18. Dec 09, 2019
  19. Nov 06, 2019
    • Honggang Li's avatar
      configfs: calculate the depth of parent item · e2f238f7
      Honggang Li authored
      
      When create symbolic link, create_link should calculate the depth
      of the parent item. However, both the first and second parameters
      of configfs_get_target_path had been set to the target. Broken
      symbolic link created.
      
      $ targetcli ls /
      o- / ............................................................. [...]
        o- backstores .................................................. [...]
        | o- block ...................................... [Storage Objects: 0]
        | o- fileio ..................................... [Storage Objects: 2]
        | | o- vdev0 .......... [/dev/ramdisk1 (16.0MiB) write-thru activated]
        | | | o- alua ....................................... [ALUA Groups: 1]
        | | |   o- default_tg_pt_gp ........... [ALUA state: Active/optimized]
        | | o- vdev1 .......... [/dev/ramdisk2 (16.0MiB) write-thru activated]
        | |   o- alua ....................................... [ALUA Groups: 1]
        | |     o- default_tg_pt_gp ........... [ALUA state: Active/optimized]
        | o- pscsi ...................................... [Storage Objects: 0]
        | o- ramdisk .................................... [Storage Objects: 0]
        o- iscsi ................................................ [Targets: 0]
        o- loopback ............................................. [Targets: 0]
        o- srpt ................................................. [Targets: 2]
        | o- ib.e89a8f91cb3200000000000000000000 ............... [no-gen-acls]
        | | o- acls ................................................ [ACLs: 2]
        | | | o- ib.e89a8f91cb3200000000000000000000 ........ [Mapped LUNs: 2]
        | | | | o- mapped_lun0 ............................. [BROKEN LUN LINK]
        | | | | o- mapped_lun1 ............................. [BROKEN LUN LINK]
        | | | o- ib.e89a8f91cb3300000000000000000000 ........ [Mapped LUNs: 2]
        | | |   o- mapped_lun0 ............................. [BROKEN LUN LINK]
        | | |   o- mapped_lun1 ............................. [BROKEN LUN LINK]
        | | o- luns ................................................ [LUNs: 2]
        | |   o- lun0 ...... [fileio/vdev0 (/dev/ramdisk1) (default_tg_pt_gp)]
        | |   o- lun1 ...... [fileio/vdev1 (/dev/ramdisk2) (default_tg_pt_gp)]
        | o- ib.e89a8f91cb3300000000000000000000 ............... [no-gen-acls]
        |   o- acls ................................................ [ACLs: 0]
        |   o- luns ................................................ [LUNs: 0]
        o- vhost ................................................ [Targets: 0]
      
      Fixes: e9c03af2 ("configfs: calculate the symlink target only once")
      Signed-off-by: default avatarHonggang Li <honli@redhat.com>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      e2f238f7
  20. Sep 11, 2019
  21. Sep 04, 2019
    • Al Viro's avatar
      configfs: provide exclusion between IO and removals · b0841eef
      Al Viro authored
      
      Make sure that attribute methods are not called after the item
      has been removed from the tree.  To do so, we
      	* at the point of no return in removals, grab ->frag_sem
      exclusive and mark the fragment dead.
      	* call the methods of attributes with ->frag_sem taken
      shared and only after having verified that the fragment is still
      alive.
      
      	The main benefit is for method instances - they are
      guaranteed that the objects they are accessing *and* all ancestors
      are still there.  Another win is that we don't need to bother
      with extra refcount on config_item when opening a file -
      the item will be alive for as long as it stays in the tree, and
      we won't touch it/attributes/any associated data after it's
      been removed from the tree.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
      b0841eef
  22. Sep 02, 2019
  23. Aug 30, 2019
    • Deepa Dinamani's avatar
      timestamp_truncate: Replace users of timespec64_trunc · 3818c190
      Deepa Dinamani authored
      
      Update the inode timestamp updates to use timestamp_truncate()
      instead of timespec64_trunc().
      
      The change was mostly generated by the following coccinelle
      script.
      
      virtual context
      virtual patch
      
      @r1 depends on patch forall@
      struct inode *inode;
      identifier i_xtime =~ "^i_[acm]time$";
      expression e;
      @@
      
      inode->i_xtime =
      - timespec64_trunc(
      + timestamp_truncate(
      ...,
      - e);
      + inode);
      
      Signed-off-by: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
      Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Acked-by: default avatarJeff Layton <jlayton@kernel.org>
      Cc: adrian.hunter@intel.com
      Cc: dedekind1@gmail.com
      Cc: gregkh@linuxfoundation.org
      Cc: hch@lst.de
      Cc: jaegeuk@kernel.org
      Cc: jlbec@evilplan.org
      Cc: richard@nod.at
      Cc: tj@kernel.org
      Cc: yuchao0@huawei.com
      Cc: linux-f2fs-devel@lists.sourceforge.net
      Cc: linux-ntfs-dev@lists.sourceforge.net
      Cc: linux-mtd@lists.infradead.org
      3818c190
  24. Jul 05, 2019
  25. Jun 20, 2019
    • Amir Goldstein's avatar
      configfs: call fsnotify_rmdir() hook · 6146e78c
      Amir Goldstein authored
      
      This will allow generating fsnotify delete events on unregister
      of group/subsystem after the fsnotify_nameremove() hook is removed
      from d_delete().
      
      The rest of the d_delete() calls from this filesystem are either
      called recursively from within debugfs_unregister_{group,subsystem},
      called from a vfs function that already has delete hooks or are
      called from shutdown/cleanup code.
      
      Cc: Joel Becker <jlbec@evilplan.org>
      Cc: Christoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
      Signed-off-by: default avatarJan Kara <jack@suse.cz>
      6146e78c
  26. May 30, 2019
  27. May 28, 2019
  28. May 21, 2019
Loading