23 Jul, 2020

1 commit

  • Since debugfs include sensitive information it need to be treated
    carefully. But it also has many very useful debug functions for userspace.
    With this option we can have same configuration for system with
    need of debugfs and a way to turn it off. This gives a extra protection
    for exposure on systems where user-space services with system
    access are attacked.

    It is controlled by a configurable default value that can be override
    with a kernel command line parameter. (debugfs=)

    It can be on or off, but also internally on but not seen from user-space.
    This no-mount mode do not register a debugfs as filesystem, but client can
    register their parts in the internal structures. This data can be readed
    with a debugger or saved with a crashkernel. When it is off clients
    get EPERM error when accessing the functions for registering their
    components.

    Signed-off-by: Peter Enderborg
    Link: https://lore.kernel.org/r/20200716071511.26864-3-peter.enderborg@sony.com
    Signed-off-by: Greg Kroah-Hartman

    Peter Enderborg
     

23 Apr, 2020

1 commit

  • This patch corrects the SPDX License Identifier style in
    header file related to debugfs File System support.
    For C header files Documentation/process/license-rules.rst
    mandates C-like comments (opposed to C source files where
    C++ style should be used).

    Changes made by using a script provided by Joe Perches here:
    https://lkml.org/lkml/2019/2/7/46.

    Suggested-by: Joe Perches
    Signed-off-by: Nishad Kamdar
    Link: https://lore.kernel.org/r/20200419144852.GA9206@nishad
    Signed-off-by: Greg Kroah-Hartman

    Nishad Kamdar
     

08 Nov, 2017

5 commits

  • 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
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     
  • 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
    Cc: Kate Stewart
    Cc: Philippe Ombredanne
    Cc: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Greg Kroah-Hartman
     
  • 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: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange
     
  • Since commit 49d200deaa68 ("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: 49d200deaa68 ("debugfs: prevent access to removed files' private data")
    Reported-by: Johannes Berg
    Signed-off-by: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange
     
  • 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: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange
     

31 Aug, 2016

1 commit

  • debugfs_create_file_unsafe() is declared twice in exactly the same
    manner each: once in fs/debugfs/internal.h and once in
    include/linux/debugfs.h

    All files that include the former also include the latter and thus,
    the declaration in fs/debugfs/internal.h is superfluous.

    Remove it.

    Signed-off-by: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange
     

13 Apr, 2016

2 commits

  • 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: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange
     
  • 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: Nicolai Stange
    Signed-off-by: Greg Kroah-Hartman

    Nicolai Stange