~sforshee/ubuntu/+source/linux/+git/xenial:lockdown-updates

Last commit made on 2020-06-19
Get this branch:
git clone -b lockdown-updates https://git.launchpad.net/~sforshee/ubuntu/+source/linux/+git/xenial
Only Seth Forshee can upload to this branch. If you are Seth Forshee please log in for upload directions.

Branch merges

Branch information

Name:
lockdown-updates
Repository:
lp:~sforshee/ubuntu/+source/linux/+git/xenial

Recent commits

09045d1... by David Howells

UBUNTU: SAUCE: (efi-lockdown) debugfs: Disallow use of debugfs files when the kernel is locked down

BugLink: https://bugs.launchpad.net/bugs/1884159

Disallow opening of debugfs files when the kernel is locked down as various
drivers give raw access to hardware through debugfs.

Accesses to tracefs should use /sys/kernel/tracing/ rather than
/sys/kernel/debug/tracing/. Possibly a symlink should be emplaced.

Normal device interaction should be done through configfs or a miscdev, not
debugfs.

Note that this makes it unnecessary to specifically lock down show_dsts(),
show_devs() and show_call() in the asus-wmi driver.

Signed-off-by: David Howells <email address hidden>
cc: Andy Shevchenko <email address hidden>
cc: <email address hidden>
cc: <email address hidden>
cc: Matthew Garrett <email address hidden>
cc: Thomas Gleixner <email address hidden>
(backported from commit 125da2e1c5d0a6aca5faafba336c8e8506a4e000
 git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/fedora.git)
Signed-off-by: Seth Forshee <email address hidden>

410a64d... by Nicolai Stange <email address hidden>

debugfs: open_proxy_open(): avoid double fops release

BugLink: https://bugs.launchpad.net/bugs/1884159

Debugfs' open_proxy_open(), the ->open() installed at all inodes created
through debugfs_create_file_unsafe(),
- grabs a reference to the original file_operations instance passed to
  debugfs_create_file_unsafe() via fops_get(),
- installs it at the file's ->f_op by means of replace_fops()
- and calls fops_put() on it.

Since the semantics of replace_fops() are such that the reference's
ownership is transferred, the subsequent fops_put() will result in a double
release when the file is eventually closed.

Currently, this is not an issue since fops_put() basically does a
module_put() on the file_operations' ->owner only and there don't exist any
modules calling debugfs_create_file_unsafe() yet. This is expected to
change in the future though, c.f. commit c64688081490 ("debugfs: add
support for self-protecting attribute file fops").

Remove the call to fops_put() from open_proxy_open().

Fixes: 9fd4dcece43a ("debugfs: prevent access to possibly dead
                      file_operations at file open")
Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit 75f0b68b75dabb3ff551440163fd67b3fc62901a)
Signed-off-by: Seth Forshee <email address hidden>

59343a8... by Nicolai Stange <email address hidden>

debugfs: full_proxy_open(): free proxy on ->open() failure

BugLink: https://bugs.launchpad.net/bugs/1884159

Debugfs' full_proxy_open(), the ->open() installed at all inodes created
through debugfs_create_file(),
- grabs a reference to the original struct file_operations instance passed
  to debugfs_create_file(),
- dynamically allocates a proxy struct file_operations instance wrapping
  the original
- and installs this at the file's ->f_op.

Afterwards, it calls the original ->open() and passes its return value back
to the VFS layer.

Now, if that return value indicates failure, the VFS layer won't ever call
->release() and thus, neither the reference to the original file_operations
nor the memory for the proxy file_operations will get released, i.e. both
are leaked.

Upon failure of the original fops' ->open(), undo the proxy installation.
That is:
- Set the struct file ->f_op to what it had been when full_proxy_open()
  was entered.
- Drop the reference to the original file_operations.
- Free the memory holding the proxy file_operations.

Fixes: 49d200deaa68 ("debugfs: prevent access to removed files' private
                      data")
Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit b10e3e90485e32e4cea9e35d2295ee7bffaeff73)
Signed-off-by: Seth Forshee <email address hidden>

f733b1e... by Nicolai Stange <email address hidden>

debugfs: unproxify files created through debugfs_create_u32_array()

BugLink: https://bugs.launchpad.net/bugs/1884159

The struct file_operations u32_array_fops associated with files created
through debugfs_create_u32_array() has been lifetime aware already:
everything needed for subsequent operation is copied to a ->f_private
buffer at file opening time in u32_array_open(). Now, ->open() is always
protected against file removal issues by the debugfs core.

There is no need for the debugfs core to wrap the u32_array_fops
with a file lifetime managing proxy.

Make debugfs_create_u32_array() create its files in non-proxying operation
mode by means of debugfs_create_file_unsafe().

Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit c4a74f63dfd2e75e7d40a9aaa4052b0ef26e617c)
Signed-off-by: Seth Forshee <email address hidden>

19d6ffc... by Nicolai Stange <email address hidden>

debugfs: unproxify files created through debugfs_create_blob()

BugLink: https://bugs.launchpad.net/bugs/1884159

Currently, the struct file_operations fops_blob associated with files
created through the debugfs_create_blob() helpers are not file
lifetime aware.

Thus, a lifetime managing proxy is created around fops_blob each time such
a file is opened which is an unnecessary waste of resources.

Implement file lifetime management for the fops_bool file_operations.
Namely, make read_file_blob() safe gainst file removals by means of
debugfs_use_file_start() and debugfs_use_file_finish().

Make debugfs_create_blob() create its files in non-proxying operation mode
by means of debugfs_create_file_unsafe().

Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit 83b711cbf4ff42a9996c5f092762b3967d307d73)
Signed-off-by: Seth Forshee <email address hidden>

42a1811... by Nicolai Stange <email address hidden>

debugfs: unproxify files created through debugfs_create_bool()

BugLink: https://bugs.launchpad.net/bugs/1884159

Currently, the struct file_operations fops_bool associated with files
created through the debugfs_create_bool() helpers are not file
lifetime aware.

Thus, a lifetime managing proxy is created around fops_bool each time such
a file is opened which is an unnecessary waste of resources.

Implement file lifetime management for the fops_bool file_operations.
Namely, make debugfs_read_file_bool() and debugfs_write_file_bool() safe
against file removals by means of debugfs_use_file_start() and
debugfs_use_file_finish().

Make debugfs_create_bool() create its files in non-proxying operation mode
through debugfs_create_mode_unsafe().

Finally, purge debugfs_create_mode() as debugfs_create_bool() had been its
last user.

Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit 4d45f7974ccf0aa783034fef2661573b3a28609e)
Signed-off-by: Seth Forshee <email address hidden>

82e4c7a... by Nicolai Stange <email address hidden>

debugfs: unproxify integer attribute files

BugLink: https://bugs.launchpad.net/bugs/1884159

Currently, the struct file_operations associated with the integer attribute
style files created through the debugfs_create_*() helpers are not file
lifetime aware as they are defined by means of DEFINE_SIMPLE_ATTRIBUTE().

Thus, a lifetime managing proxy is created around the original fops each
time such a file is opened which is an unnecessary waste of resources.

Migrate all usages of DEFINE_SIMPLE_ATTRIBUTE() within debugfs itself
to DEFINE_DEBUGFS_ATTRIBUTE() in order to implement file lifetime managing
within the struct file_operations thus defined.

Introduce the debugfs_create_mode_unsafe() helper, analogous to
debugfs_create_mode(), but distinct in that it creates the files in
non-proxying operation mode through debugfs_create_file_unsafe().

Feed all struct file_operations migrated to DEFINE_DEBUGFS_ATTRIBUTE()
into debugfs_create_mode_unsafe() instead of former debugfs_create_mode().

Signed-off-by: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit 4909f168104b24f592fb8d502e2a6520346a3927)
Signed-off-by: Seth Forshee <email address hidden>

39da340... by Nicolai Stange <email address hidden>

debugfs: add support for self-protecting attribute file fops

BugLink: https://bugs.launchpad.net/bugs/1884159

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: Nicolai Stange <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(cherry picked from commit c64688081490321f2d23a292ef24e60bb321f3f1)
Signed-off-by: Seth Forshee <email address hidden>

81b3ade... by Nicolai Stange <email address hidden>

debugfs: prevent access to removed files' private data

BugLink: https://bugs.launchpad.net/bugs/1884159

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 <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(backported from commit 49d200deaa680501f19a247b1fffb29301e51d2b)
Signed-off-by: Seth Forshee <email address hidden>

4833bba... by Nicolai Stange <email address hidden>

debugfs: prevent access to possibly dead file_operations at file open

BugLink: https://bugs.launchpad.net/bugs/1884159

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://<email address hidden>
  ("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 <email address hidden>
Signed-off-by: Greg Kroah-Hartman <email address hidden>
(backported from commit 9fd4dcece43a53e5a9e65a973df5693702ee6401)
Signed-off-by: Seth Forshee <email address hidden>