1. 13 Jun, 2018 1 commit
  2. 14 May, 2018 1 commit
    • Thomas Richter's avatar
      debugfs: inode: debugfs_create_dir uses mode permission from parent · 95cde3c5
      Thomas Richter authored
      Currently function debugfs_create_dir() creates a new
      directory in the debugfs (usually mounted /sys/kernel/debug)
      with permission rwxr-xr-x. This is hard coded.
      
      Change this to use the parent directory permission.
      
      Output before the patch:
      root@s8360047 ~]# tree -dp -L 1 /sys/kernel/debug/
      /sys/kernel/debug/
      ├── [drwxr-xr-x]  bdi
      ├── [drwxr-xr-x]  block
      ├── [drwxr-xr-x]  dasd
      ├── [drwxr-xr-x]  device_component
      ├── [drwxr-xr-x]  extfrag
      ├── [drwxr-xr-x]  hid
      ├── [drwxr-xr-x]  kprobes
      ├── [drwxr-xr-x]  kvm
      ├── [drwxr-xr-x]  memblock
      ├── [drwxr-xr-x]  pm_qos
      ├── [drwxr-xr-x]  qdio
      ├── [drwxr-xr-x]  s390
      ├── [drwxr-xr-x]  s390dbf
      └── [drwx------]  tracing
      
      14 directories
      [root@s8360047 linux]#
      
      Output after the patch:
      [root@s8360047 ~]# tree -dp -L 1 /sys/kernel/debug/
      sys/kernel/debug/
      ├── [drwx------]  bdi
      ├── [drwx------]  block
      ├── [drwx------]  dasd
      ├── [drwx------]  device_component
      ├── [drwx------]  extfrag
      ├── [drwx------]  hid
      ├── [drwx------]  kprobes
      ├── [drwx------]  kvm
      ├── [drwx------]  memblock
      ├── [drwx------]  pm_qos
      ├── [drwx------]  qdio
      ├── [drwx------]  s390
      ├── [drwx------]  s390dbf
      └── [drwx------]  tracing
      
      14 directories
      [root@s8360047 linux]#
      
      Here is the full diff output done with:
      [root@s8360047 ~]# diff -u treefull.before treefull.after |
      	sed 's-^- # -' > treefull.diff
       # --- treefull.before	2018-04-27 13:22:04.532824564 +0200
       # +++ treefull.after	2018-04-27 13:24:12.106182062 +0200
       # @@ -1,55 +1,55 @@
       #  /sys/kernel/debug/
       # -├── [drwxr-xr-x]  bdi
       # -│   ├── [drwxr-xr-x]  1:0
       # -│   ├── [drwxr-xr-x]  1:1
       # -│   ├── [drwxr-xr-x]  1:10
       # -│   ├── [drwxr-xr-x]  1:11
       # -│   ├── [drwxr-xr-x]  1:12
       # -│   ├── [drwxr-xr-x]  1:13
       # -│   ├── [drwxr-xr-x]  1:14
       # -│   ├── [drwxr-xr-x]  1:15
       # -│   ├── [drwxr-xr-x]  1:2
       # -│   ├── [drwxr-xr-x]  1:3
       # -│   ├── [drwxr-xr-x]  1:4
       # -│   ├── [drwxr-xr-x]  1:5
       # -│   ├── [drwxr-xr-x]  1:6
       # -│   ├── [drwxr-xr-x]  1:7
       # -│   ├── [drwxr-xr-x]  1:8
       # -│   ├── [drwxr-xr-x]  1:9
       # -│   └── [drwxr-xr-x]  94:0
       # -├── [drwxr-xr-x]  block
       # -├── [drwxr-xr-x]  dasd
       # -│   ├── [drwxr-xr-x]  0.0.e18a
       # -│   ├── [drwxr-xr-x]  dasda
       # -│   └── [drwxr-xr-x]  global
       # -├── [drwxr-xr-x]  device_component
       # -├── [drwxr-xr-x]  extfrag
       # -├── [drwxr-xr-x]  hid
       # -├── [drwxr-xr-x]  kprobes
       # -├── [drwxr-xr-x]  kvm
       # -├── [drwxr-xr-x]  memblock
       # -├── [drwxr-xr-x]  pm_qos
       # -├── [drwxr-xr-x]  qdio
       # -│   └── [drwxr-xr-x]  0.0.f5f2
       # -├── [drwxr-xr-x]  s390
       # -│   └── [drwxr-xr-x]  stsi
       # -├── [drwxr-xr-x]  s390dbf
       # -│   ├── [drwxr-xr-x]  0.0.e18a
       # -│   ├── [drwxr-xr-x]  cio_crw
       # -│   ├── [drwxr-xr-x]  cio_msg
       # -│   ├── [drwxr-xr-x]  cio_trace
       # -│   ├── [drwxr-xr-x]  dasd
       # -│   ├── [drwxr-xr-x]  kvm-trace
       # -│   ├── [drwxr-xr-x]  lgr
       # -│   ├── [drwxr-xr-x]  qdio_0.0.f5f2
       # -│   ├── [drwxr-xr-x]  qdio_error
       # -│   ├── [drwxr-xr-x]  qdio_setup
       # -│   ├── [drwxr-xr-x]  qeth_card_0.0.f5f0
       # -│   ├── [drwxr-xr-x]  qeth_control
       # -│   ├── [drwxr-xr-x]  qeth_msg
       # -│   ├── [drwxr-xr-x]  qeth_setup
       # -│   ├── [drwxr-xr-x]  vmcp
       # -│   └── [drwxr-xr-x]  vmur
       # +├── [drwx------]  bdi
       # +│   ├── [drwx------]  1:0
       # +│   ├── [drwx------]  1:1
       # +│   ├── [drwx------]  1:10
       # +│   ├── [drwx------]  1:11
       # +│   ├── [drwx------]  1:12
       # +│   ├── [drwx------]  1:13
       # +│   ├── [drwx------]  1:14
       # +│   ├── [drwx------]  1:15
       # +│   ├── [drwx------]  1:2
       # +│   ├── [drwx------]  1:3
       # +│   ├── [drwx------]  1:4
       # +│   ├── [drwx------]  1:5
       # +│   ├── [drwx------]  1:6
       # +│   ├── [drwx------]  1:7
       # +│   ├── [drwx------]  1:8
       # +│   ├── [drwx------]  1:9
       # +│   └── [drwx------]  94:0
       # +├── [drwx------]  block
       # +├── [drwx------]  dasd
       # +│   ├── [drwx------]  0.0.e18a
       # +│   ├── [drwx------]  dasda
       # +│   └── [drwx------]  global
       # +├── [drwx------]  device_component
       # +├── [drwx------]  extfrag
       # +├── [drwx------]  hid
       # +├── [drwx------]  kprobes
       # +├── [drwx------]  kvm
       # +├── [drwx------]  memblock
       # +├── [drwx------]  pm_qos
       # +├── [drwx------]  qdio
       # +│   └── [drwx------]  0.0.f5f2
       # +├── [drwx------]  s390
       # +│   └── [drwx------]  stsi
       # +├── [drwx------]  s390dbf
       # +│   ├── [drwx------]  0.0.e18a
       # +│   ├── [drwx------]  cio_crw
       # +│   ├── [drwx------]  cio_msg
       # +│   ├── [drwx------]  cio_trace
       # +│   ├── [drwx------]  dasd
       # +│   ├── [drwx------]  kvm-trace
       # +│   ├── [drwx------]  lgr
       # +│   ├── [drwx------]  qdio_0.0.f5f2
       # +│   ├── [drwx------]  qdio_error
       # +│   ├── [drwx------]  qdio_setup
       # +│   ├── [drwx------]  qeth_card_0.0.f5f0
       # +│   ├── [drwx------]  qeth_control
       # +│   ├── [drwx------]  qeth_msg
       # +│   ├── [drwx------]  qeth_setup
       # +│   ├── [drwx------]  vmcp
       # +│   └── [drwx------]  vmur
       #  └── [drwx------]  tracing
       #      ├── [drwxr-xr-x]  events
       #      │   ├── [drwxr-xr-x]  alarmtimer
      
      Fixes: edac65ea ("debugfs: take mode-dependent parts of debugfs_get_inode() into callers")
      Signed-off-by: default avatarThomas Richter <tmricht@linux.ibm.com>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      95cde3c5
  3. 29 Mar, 2018 1 commit
  4. 07 Nov, 2017 6 commits
    • Greg Kroah-Hartman's avatar
      debugfs: Remove redundant license text · 2b2d8788
      Greg Kroah-Hartman authored
      Now that the SPDX tag is in all debugfs files, that identifies the
      license in a specific and legally-defined manner.  So the extra GPL text
      wording can be removed as it is no longer needed at all.
      
      This is done on a quest to remove the 700+ different ways that files in
      the kernel describe the GPL license text.  And there's unneeded stuff
      like the address (sometimes incorrect) for the FSF which is never
      needed.
      
      No copyright headers or other non-license-description text was removed.
      
      Cc: Nicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2b2d8788
    • Greg Kroah-Hartman's avatar
      debugfs: add SPDX identifiers to all debugfs files · 3bce94fd
      Greg Kroah-Hartman authored
      It's good to have SPDX identifiers in all files to make it easier to
      audit the kernel tree for correct licenses.
      
      Update the debugfs files files with the correct SPDX license identifier
      based on the license text in the file itself.  The SPDX identifier is a
      legally binding shorthand, which can be used instead of the full boiler
      plate text.
      
      This work is based on a script and data from Thomas Gleixner, Philippe
      Ombredanne, and Kate Stewart.
      
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Kate Stewart <kstewart@linuxfoundation.org>
      Cc: Philippe Ombredanne <pombredanne@nexb.com>
      Cc: Nicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      3bce94fd
    • Nicolai Stange's avatar
      debugfs: defer debugfs_fsdata allocation to first usage · 7d39bc50
      Nicolai Stange authored
      Currently, __debugfs_create_file allocates one struct debugfs_fsdata
      instance for every file created. However, there are potentially many
      debugfs file around, most of which are never touched by userspace.
      
      Thus, defer the allocations to the first usage, i.e. to the first
      debugfs_file_get().
      
      A dentry's ->d_fsdata starts out to point to the "real", user provided
      fops. After a debugfs_fsdata instance has been allocated (and the real
      fops pointer has been moved over into its ->real_fops member),
      ->d_fsdata is changed to point to it from then on. The two cases are
      distinguished by setting BIT(0) for the real fops case.
      
      struct debugfs_fsdata's foremost purpose is to track active users and to
      make debugfs_remove() block until they are done. Since no debugfs_fsdata
      instance means no active users, make debugfs_remove() return immediately
      in this case.
      
      Take care of possible races between debugfs_file_get() and
      debugfs_remove(): either debugfs_remove() must see a debugfs_fsdata
      instance and thus wait for possible active users or debugfs_file_get() must
      see a dead dentry and return immediately.
      
      Make a dentry's ->d_release(), i.e. debugfs_release_dentry(), check whether
      ->d_fsdata is actually a debugfs_fsdata instance before kfree()ing it.
      
      Similarly, make debugfs_real_fops() check whether ->d_fsdata is actually
      a debugfs_fsdata instance before returning it, otherwise emit a warning.
      
      The set of possible error codes returned from debugfs_file_get() has grown
      from -EIO to -EIO and -ENOMEM. Make open_proxy_open() and full_proxy_open()
      pass the -ENOMEM onwards to their callers.
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7d39bc50
    • Nicolai Stange's avatar
      debugfs: purge obsolete SRCU based removal protection · c9afbec2
      Nicolai Stange authored
      Purge the SRCU based file removal race protection in favour of the new,
      refcount based debugfs_file_get()/debugfs_file_put() API.
      
      Fixes: 49d200de ("debugfs: prevent access to removed files' private data")
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c9afbec2
    • Nicolai Stange's avatar
      debugfs: implement per-file removal protection · e9117a5a
      Nicolai Stange authored
      Since commit 49d200de ("debugfs: prevent access to removed files'
      private data"), accesses to a file's private data are protected from
      concurrent removal by covering all file_operations with a SRCU read section
      and sychronizing with those before returning from debugfs_remove() by means
      of synchronize_srcu().
      
      As pointed out by Johannes Berg, there are debugfs files with forever
      blocking file_operations. Their corresponding SRCU read side sections would
      block any debugfs_remove() forever as well, even unrelated ones. This
      results in a livelock. Because a remover can't cancel any indefinite
      blocking within foreign files, this is a problem.
      
      Resolve this by introducing support for more granular protection on a
      per-file basis.
      
      This is implemented by introducing an  'active_users' refcount_t to the
      per-file struct debugfs_fsdata state. At file creation time, it is set to
      one and a debugfs_remove() will drop that initial reference. The new
      debugfs_file_get() and debugfs_file_put(), intended to be used in place of
      former debugfs_use_file_start() and debugfs_use_file_finish(), increment
      and decrement it respectively. Once the count drops to zero,
      debugfs_file_put() will signal a completion which is possibly being waited
      for from debugfs_remove().
      Thus, as long as there is a debugfs_file_get() not yet matched by a
      corresponding debugfs_file_put() around, debugfs_remove() will block.
      
      Actual users of debugfs_use_file_start() and -finish() will get converted
      to the new debugfs_file_get() and debugfs_file_put() by followup patches.
      
      Fixes: 49d200de ("debugfs: prevent access to removed files' private data")
      Reported-by: default avatarJohannes Berg <johannes@sipsolutions.net>
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e9117a5a
    • Nicolai Stange's avatar
      debugfs: add support for more elaborate ->d_fsdata · 7c8d4698
      Nicolai Stange authored
      Currently, the user provided fops, "real_fops", are stored directly into
      ->d_fsdata.
      
      In order to be able to store more per-file state and thus prepare for more
      granular file removal protection, wrap the real_fops into a dynamically
      allocated container struct, debugfs_fsdata.
      
      A struct debugfs_fsdata gets allocated at file creation and freed from the
      newly intoduced ->d_release().
      
      Finally, move the implementation of debugfs_real_fops() out of the public
      debugfs header such that struct debugfs_fsdata's declaration can be kept
      private.
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7c8d4698
  5. 08 Jul, 2017 1 commit
    • Al Viro's avatar
      dentry name snapshots · 49d31c2f
      Al Viro authored
      take_dentry_name_snapshot() takes a safe snapshot of dentry name;
      if the name is a short one, it gets copied into caller-supplied
      structure, otherwise an extra reference to external name is grabbed
      (those are never modified).  In either case the pointer to stable
      string is stored into the same structure.
      
      dentry must be held by the caller of take_dentry_name_snapshot(),
      but may be freely dropped afterwards - the snapshot will stay
      until destroyed by release_dentry_name_snapshot().
      
      Intended use:
      	struct name_snapshot s;
      
      	take_dentry_name_snapshot(&s, dentry);
      	...
      	access s.name
      	...
      	release_dentry_name_snapshot(&s);
      
      Replaces fsnotify_oldname_...(), gets used in fsnotify to obtain the name
      to pass down with event.
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      49d31c2f
  6. 06 Jul, 2017 1 commit
    • David Howells's avatar
      VFS: Don't use save/replace_mount_options if not using generic_show_options · c3d98ea0
      David Howells authored
      btrfs, debugfs, reiserfs and tracefs call save_mount_options() and reiserfs
      calls replace_mount_options(), but they then implement their own
      ->show_options() methods and don't touch s_options, rendering the saved
      options unnecessary.  I'm trying to eliminate s_options to make it easier
      to implement a context-based mount where the mount options can be passed
      individually over a file descriptor.
      
      Remove the calls to save/replace_mount_options() call in these cases.
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      cc: Chris Mason <clm@fb.com>
      cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      cc: Steven Rostedt <rostedt@goodmis.org>
      cc: linux-btrfs@vger.kernel.org
      cc: reiserfs-devel@vger.kernel.org
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      c3d98ea0
  7. 16 May, 2017 1 commit
  8. 27 Apr, 2017 1 commit
  9. 02 Feb, 2017 1 commit
    • Omar Sandoval's avatar
      debugfs: add debugfs_lookup() · a7c5437b
      Omar Sandoval authored
      We don't always have easy access to the dentry of a file or directory we
      created in debugfs. Add a helper which allows us to get a dentry we
      previously created.
      
      The motivation for this change is a problem with blktrace and the blk-mq
      debugfs entries introduced in 07e4fead ("blk-mq: create debugfs
      directory tree"). Namely, in some cases, the directory that blktrace
      needs to create may already exist, but in other cases, it may not. We
      _could_ rely on a bunch of implied knowledge to decide whether to create
      the directory or not, but it's much cleaner on our end to just look it
      up.
      Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
      Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: default avatarJens Axboe <axboe@fb.com>
      a7c5437b
  10. 01 Feb, 2017 1 commit
    • Eric W. Biederman's avatar
      fs: Better permission checking for submounts · 93faccbb
      Eric W. Biederman authored
      To support unprivileged users mounting filesystems two permission
      checks have to be performed: a test to see if the user allowed to
      create a mount in the mount namespace, and a test to see if
      the user is allowed to access the specified filesystem.
      
      The automount case is special in that mounting the original filesystem
      grants permission to mount the sub-filesystems, to any user who
      happens to stumble across the their mountpoint and satisfies the
      ordinary filesystem permission checks.
      
      Attempting to handle the automount case by using override_creds
      almost works.  It preserves the idea that permission to mount
      the original filesystem is permission to mount the sub-filesystem.
      Unfortunately using override_creds messes up the filesystems
      ordinary permission checks.
      
      Solve this by being explicit that a mount is a submount by introducing
      vfs_submount, and using it where appropriate.
      
      vfs_submount uses a new mount internal mount flags MS_SUBMOUNT, to let
      sget and friends know that a mount is a submount so they can take appropriate
      action.
      
      sget and sget_userns are modified to not perform any permission checks
      on submounts.
      
      follow_automount is modified to stop using override_creds as that
      has proven problemantic.
      
      do_mount is modified to always remove the new MS_SUBMOUNT flag so
      that we know userspace will never by able to specify it.
      
      autofs4 is modified to stop using current_real_cred that was put in
      there to handle the previous version of submount permission checking.
      
      cifs is modified to pass the mountpoint all of the way down to vfs_submount.
      
      debugfs is modified to pass the mountpoint all of the way down to
      trace_automount by adding a new parameter.  To make this change easier
      a new typedef debugfs_automount_t is introduced to capture the type of
      the debugfs automount function.
      
      Cc: stable@vger.kernel.org
      Fixes: 069d5ac9 ("autofs:  Fix automounts by using current_real_cred()->uid")
      Fixes: aeaa4a79 ("fs: Call d_automount with the filesystems creds")
      Reviewed-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
      Reviewed-by: default avatarSeth Forshee <seth.forshee@canonical.com>
      Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
      93faccbb
  11. 28 Sep, 2016 1 commit
  12. 27 Sep, 2016 1 commit
  13. 29 May, 2016 1 commit
  14. 12 Apr, 2016 4 commits
    • Seth Forshee's avatar
      debugfs: Make automount point inodes permanently empty · 87243deb
      Seth Forshee authored
      Starting with 4.1 the tracing subsystem has its own filesystem
      which is automounted in the tracing subdirectory of debugfs.
      Prior to this debugfs could be bind mounted in a cloned mount
      namespace, but if tracefs has been mounted under debugfs this
      now fails because there is a locked child mount. This creates
      a regression for container software which bind mounts debugfs
      to satisfy the assumption of some userspace software.
      
      In other pseudo filesystems such as proc and sysfs we're already
      creating mountpoints like this in such a way that no dirents can
      be created in the directories, allowing them to be exceptions to
      some MNT_LOCKED tests. In fact we're already do this for the
      tracefs mountpoint in sysfs.
      
      Do the same in debugfs_create_automount(), since the intention
      here is clearly to create a mountpoint. This fixes the regression,
      as locked child mounts on permanently empty directories do not
      cause a bind mount to fail.
      
      Cc: stable@vger.kernel.org # v4.1+
      Signed-off-by: default avatarSeth Forshee <seth.forshee@canonical.com>
      Acked-by: default avatarSerge Hallyn <serge.hallyn@canonical.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      87243deb
    • Nicolai Stange's avatar
      debugfs: add support for self-protecting attribute file fops · c6468808
      Nicolai Stange authored
      In order to protect them against file removal issues, debugfs_create_file()
      creates a lifetime managing proxy around each struct file_operations
      handed in.
      
      In cases where this struct file_operations is able to manage file lifetime
      by itself already, the proxy created by debugfs is a waste of resources.
      
      The most common class of struct file_operations given to debugfs are those
      defined by means of the DEFINE_SIMPLE_ATTRIBUTE() macro.
      
      Introduce a DEFINE_DEBUGFS_ATTRIBUTE() macro to allow any
      struct file_operations of this class to be easily made file lifetime aware
      and thus, to be operated unproxied.
      
      Specifically, introduce debugfs_attr_read() and debugfs_attr_write()
      which wrap simple_attr_read() and simple_attr_write() under the protection
      of a debugfs_use_file_start()/debugfs_use_file_finish() pair.
      
      Make DEFINE_DEBUGFS_ATTRIBUTE() set the defined struct file_operations'
      ->read() and ->write() members to these wrappers.
      
      Export debugfs_create_file_unsafe() in order to allow debugfs users to
      create their files in non-proxying operation mode.
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c6468808
    • Nicolai Stange's avatar
      debugfs: prevent access to removed files' private data · 49d200de
      Nicolai Stange authored
      Upon return of debugfs_remove()/debugfs_remove_recursive(), it might
      still be attempted to access associated private file data through
      previously opened struct file objects. If that data has been freed by
      the caller of debugfs_remove*() in the meanwhile, the reading/writing
      process would either encounter a fault or, if the memory address in
      question has been reassigned again, unrelated data structures could get
      overwritten.
      
      However, since debugfs files are seldomly removed, usually from module
      exit handlers only, the impact is very low.
      
      Currently, there are ~1000 call sites of debugfs_create_file() spread
      throughout the whole tree and touching all of those struct file_operations
      in order to make them file removal aware by means of checking the result of
      debugfs_use_file_start() from within their methods is unfeasible.
      
      Instead, wrap the struct file_operations by a lifetime managing proxy at
      file open:
      - In debugfs_create_file(), the original fops handed in has got stashed
        away in ->d_fsdata already.
      - In debugfs_create_file(), install a proxy file_operations factory,
        debugfs_full_proxy_file_operations, at ->i_fop.
      
      This proxy factory has got an ->open() method only. It carries out some
      lifetime checks and if successful, dynamically allocates and sets up a new
      struct file_operations proxy at ->f_op. Afterwards, it forwards to the
      ->open() of the original struct file_operations in ->d_fsdata, if any.
      
      The dynamically set up proxy at ->f_op has got a lifetime managing wrapper
      set for each of the methods defined in the original struct file_operations
      in ->d_fsdata.
      
      Its ->release()er frees the proxy again and forwards to the original
      ->release(), if any.
      
      In order not to mislead the VFS layer, it is strictly necessary to leave
      those fields blank in the proxy that have been NULL in the original
      struct file_operations also, i.e. aren't supported. This is why there is a
      need for dynamically allocated proxies. The choice made not to allocate a
      proxy instance for every dentry at file creation, but for every
      struct file object instantiated thereof is justified by the expected usage
      pattern of debugfs, namely that in general very few files get opened more
      than once at a time.
      
      The wrapper methods set in the struct file_operations implement lifetime
      managing by means of the SRCU protection facilities already in place for
      debugfs:
      They set up a SRCU read side critical section and check whether the dentry
      is still alive by means of debugfs_use_file_start(). If so, they forward
      the call to the original struct file_operation stored in ->d_fsdata, still
      under the protection of the SRCU read side critical section.
      This SRCU read side critical section prevents any pending debugfs_remove()
      and friends to return to their callers. Since a file's private data must
      only be freed after the return of debugfs_remove(), the ongoing proxied
      call is guarded against any file removal race.
      
      If, on the other hand, the initial call to debugfs_use_file_start() detects
      that the dentry is dead, the wrapper simply returns -EIO and does not
      forward the call. Note that the ->poll() wrapper is special in that its
      signature does not allow for the return of arbitrary -EXXX values and thus,
      POLLHUP is returned here.
      
      In order not to pollute debugfs with wrapper definitions that aren't ever
      needed, I chose not to define a wrapper for every struct file_operations
      method possible. Instead, a wrapper is defined only for the subset of
      methods which are actually set by any debugfs users.
      Currently, these are:
      
        ->llseek()
        ->read()
        ->write()
        ->unlocked_ioctl()
        ->poll()
      
      The ->release() wrapper is special in that it does not protect the original
      ->release() in any way from dead files in order not to leak resources.
      Thus, any ->release() handed to debugfs must implement file lifetime
      management manually, if needed.
      For only 33 out of a total of 434 releasers handed in to debugfs, it could
      not be verified immediately whether they access data structures that might
      have been freed upon a debugfs_remove() return in the meanwhile.
      
      Export debugfs_use_file_start() and debugfs_use_file_finish() in order to
      allow any ->release() to manually implement file lifetime management.
      
      For a set of common cases of struct file_operations implemented by the
      debugfs_core itself, future patches will incorporate file lifetime
      management directly within those in order to allow for their unproxied
      operation. Rename the original, non-proxying "debugfs_create_file()" to
      "debugfs_create_file_unsafe()" and keep it for future internal use by
      debugfs itself. Factor out code common to both into the new
      __debugfs_create_file().
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      49d200de
    • Nicolai Stange's avatar
      debugfs: prevent access to possibly dead file_operations at file open · 9fd4dcec
      Nicolai Stange authored
      Nothing prevents a dentry found by path lookup before a return of
      __debugfs_remove() to actually get opened after that return. Now, after
      the return of __debugfs_remove(), there are no guarantees whatsoever
      regarding the memory the corresponding inode's file_operations object
      had been kept in.
      
      Since __debugfs_remove() is seldomly invoked, usually from module exit
      handlers only, the race is hard to trigger and the impact is very low.
      
      A discussion of the problem outlined above as well as a suggested
      solution can be found in the (sub-)thread rooted at
      
        http://lkml.kernel.org/g/20130401203445.GA20862@ZenIV.linux.org.uk
        ("Yet another pipe related oops.")
      
      Basically, Greg KH suggests to introduce an intermediate fops and
      Al Viro points out that a pointer to the original ones may be stored in
      ->d_fsdata.
      
      Follow this line of reasoning:
      - Add SRCU as a reverse dependency of DEBUG_FS.
      - Introduce a srcu_struct object for the debugfs subsystem.
      - In debugfs_create_file(), store a pointer to the original
        file_operations object in ->d_fsdata.
      - Make debugfs_remove() and debugfs_remove_recursive() wait for a
        SRCU grace period after the dentry has been delete()'d and before they
        return to their callers.
      - Introduce an intermediate file_operations object named
        "debugfs_open_proxy_file_operations". It's ->open() functions checks,
        under the protection of a SRCU read lock, whether the dentry is still
        alive, i.e. has not been d_delete()'d and if so, tries to acquire a
        reference on the owning module.
        On success, it sets the file object's ->f_op to the original
        file_operations and forwards the ongoing open() call to the original
        ->open().
      - For clarity, rename the former debugfs_file_operations to
        debugfs_noop_file_operations -- they are in no way canonical.
      
      The choice of SRCU over "normal" RCU is justified by the fact, that the
      former may also be used to protect ->i_private data from going away
      during the execution of a file's readers and writers which may (and do)
      sleep.
      
      Finally, introduce the fs/debugfs/internal.h header containing some
      declarations internal to the debugfs implementation.
      Signed-off-by: default avatarNicolai Stange <nicstange@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      9fd4dcec
  15. 29 Mar, 2016 2 commits
    • Deepa Dinamani's avatar
      fs: debugfs: Replace CURRENT_TIME by current_fs_time() · 1b48b530
      Deepa Dinamani authored
      CURRENT_TIME macro is not appropriate for filesystems as it
      doesn't use the right granularity for filesystem timestamps.
      Use current_fs_time() instead.
      Signed-off-by: default avatarDeepa Dinamani <deepa.kernel@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1b48b530
    • Roman Pen's avatar
      debugfs: fix inode i_nlink references for automount dentry · a8f324a4
      Roman Pen authored
      Directory inodes should start off with i_nlink == 2 (one extra ref
      for "." entry).  debugfs_create_automount() increases neither the
      i_nlink reference for current inode nor for parent inode.
      
      On attempt to remove the automount dentry, kernel complains:
      
        [   86.288070] WARNING: CPU: 1 PID: 3616 at fs/inode.c:273 drop_nlink+0x3e/0x50()
        [   86.288461] Modules linked in: debugfs_example2(O-)
        [   86.288745] CPU: 1 PID: 3616 Comm: rmmod Tainted: G           O    4.4.0-rc3-next-20151207+ #135
        [   86.289197] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.2-20150617_082717-anatol 04/01/2014
        [   86.289696]  ffffffff81be05c9 ffff8800b9e6fda0 ffffffff81352e2c 0000000000000000
        [   86.290110]  ffff8800b9e6fdd8 ffffffff81065142 ffff8801399175e8 ffff8800bb78b240
        [   86.290507]  ffff8801399175e8 ffff8800b73d7898 ffff8800b73d7840 ffff8800b9e6fde8
        [   86.290933] Call Trace:
        [   86.291080]  [<ffffffff81352e2c>] dump_stack+0x4e/0x82
        [   86.291340]  [<ffffffff81065142>] warn_slowpath_common+0x82/0xc0
        [   86.291640]  [<ffffffff8106523a>] warn_slowpath_null+0x1a/0x20
        [   86.291932]  [<ffffffff811ae62e>] drop_nlink+0x3e/0x50
        [   86.292208]  [<ffffffff811ba35b>] simple_unlink+0x4b/0x60
        [   86.292481]  [<ffffffff811ba3a7>] simple_rmdir+0x37/0x50
        [   86.292748]  [<ffffffff812d9808>] __debugfs_remove.part.16+0xa8/0xd0
        [   86.293082]  [<ffffffff812d9a0b>] debugfs_remove_recursive+0xdb/0x1c0
        [   86.293406]  [<ffffffffa00004dd>] cleanup_module+0x2d/0x3b [debugfs_example2]
        [   86.293762]  [<ffffffff810d959b>] SyS_delete_module+0x16b/0x220
        [   86.294077]  [<ffffffff818ef857>] entry_SYSCALL_64_fastpath+0x12/0x6a
        [   86.294405] ---[ end trace c9fc53353fe14a36 ]---
        [   86.294639] ------------[ cut here ]------------
      
      To reproduce the issue it is enough to invoke these lines:
      
           autom = debugfs_create_automount("automount", NULL, vfsmount_cb, data);
           BUG_ON(IS_ERR_OR_NULL(autom));
           debugfs_remove(autom);
      
      The issue is fixed by increasing inode i_nlink references for current
      and parent inodes.
      Signed-off-by: default avatarRoman Pen <r.peniaev@gmail.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      a8f324a4
  16. 22 Jan, 2016 1 commit
    • Al Viro's avatar
      wrappers for ->i_mutex access · 5955102c
      Al Viro authored
      parallel to mutex_{lock,unlock,trylock,is_locked,lock_nested},
      inode_foo(inode) being mutex_foo(&inode->i_mutex).
      
      Please, use those for access to ->i_mutex; over the coming cycle
      ->i_mutex will become rwsem, with ->lookup() done with it held
      only shared.
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      5955102c
  17. 11 Nov, 2015 1 commit
    • Daniel Borkmann's avatar
      debugfs: fix refcount imbalance in start_creating · 0ee9608c
      Daniel Borkmann authored
      In debugfs' start_creating(), we pin the file system to safely access
      its root. When we failed to create a file, we unpin the file system via
      failed_creating() to release the mount count and eventually the reference
      of the vfsmount.
      
      However, when we run into an error during lookup_one_len() when still
      in start_creating(), we only release the parent's mutex but not so the
      reference on the mount. Looks like it was done in the past, but after
      splitting portions of __create_file() into start_creating() and
      end_creating() via 190afd81 ("debugfs: split the beginning and the
      end of __create_file() off"), this seemed missed. Noticed during code
      review.
      
      Fixes: 190afd81 ("debugfs: split the beginning and the end of __create_file() off")
      Cc: stable@vger.kernel.org # v4.0+
      Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      0ee9608c
  18. 04 Oct, 2015 1 commit
  19. 29 Sep, 2015 1 commit
  20. 01 Jul, 2015 1 commit
  21. 23 Jun, 2015 1 commit
  22. 11 May, 2015 1 commit
  23. 15 Apr, 2015 2 commits
  24. 03 Apr, 2015 1 commit
  25. 22 Feb, 2015 2 commits
    • Al Viro's avatar
      debugfs: leave freeing a symlink body until inode eviction · 0db59e59
      Al Viro authored
      As it is, we have debugfs_remove() racing with symlink traversals.
      Supply ->evict_inode() and do freeing there - inode will remain
      pinned until we are done with the symlink body.
      
      And rip the idiocy with checking if dentry is positive right after
      we'd verified debugfs_positive(), which is a stronger check...
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      0db59e59
    • David Howells's avatar
      VFS: (Scripted) Convert S_ISLNK/DIR/REG(dentry->d_inode) to d_is_*(dentry) · e36cb0b8
      David Howells authored
      Convert the following where appropriate:
      
       (1) S_ISLNK(dentry->d_inode) to d_is_symlink(dentry).
      
       (2) S_ISREG(dentry->d_inode) to d_is_reg(dentry).
      
       (3) S_ISDIR(dentry->d_inode) to d_is_dir(dentry).  This is actually more
           complicated than it appears as some calls should be converted to
           d_can_lookup() instead.  The difference is whether the directory in
           question is a real dir with a ->lookup op or whether it's a fake dir with
           a ->d_automount op.
      
      In some circumstances, we can subsume checks for dentry->d_inode not being
      NULL into this, provided we the code isn't in a filesystem that expects
      d_inode to be NULL if the dirent really *is* negative (ie. if we're going to
      use d_inode() rather than d_backing_inode() to get the inode pointer).
      
      Note that the dentry type field may be set to something other than
      DCACHE_MISS_TYPE when d_inode is NULL in the case of unionmount, where the VFS
      manages the fall-through from a negative dentry to a lower layer.  In such a
      case, the dentry type of the negative union dentry is set to the same as the
      type of the lower dentry.
      
      However, if you know d_inode is not NULL at the call site, then you can use
      the d_is_xxx() functions even in a filesystem.
      
      There is one further complication: a 0,0 chardev dentry may be labelled
      DCACHE_WHITEOUT_TYPE rather than DCACHE_SPECIAL_TYPE.  Strictly, this was
      intended for special directory entry types that don't have attached inodes.
      
      The following perl+coccinelle script was used:
      
      use strict;
      
      my @callers;
      open($fd, 'git grep -l \'S_IS[A-Z].*->d_inode\' |') ||
          die "Can't grep for S_ISDIR and co. callers";
      @callers = <$fd>;
      close($fd);
      unless (@callers) {
          print "No matches\n";
          exit(0);
      }
      
      my @cocci = (
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISLNK(E->d_inode->i_mode)',
          '+ d_is_symlink(E)',
          '',
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISDIR(E->d_inode->i_mode)',
          '+ d_is_dir(E)',
          '',
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISREG(E->d_inode->i_mode)',
          '+ d_is_reg(E)' );
      
      my $coccifile = "tmp.sp.cocci";
      open($fd, ">$coccifile") || die $coccifile;
      print($fd "$_\n") || die $coccifile foreach (@cocci);
      close($fd);
      
      foreach my $file (@callers) {
          chomp $file;
          print "Processing ", $file, "\n";
          system("spatch", "--sp-file", $coccifile, $file, "--in-place", "--no-show-diff") == 0 ||
      	die "spatch failed";
      }
      
      [AV: overlayfs parts skipped]
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      e36cb0b8
  26. 17 Feb, 2015 1 commit
  27. 26 Jan, 2015 1 commit
  28. 25 Jan, 2015 2 commits