lkml.org 
[lkml]   [2022]   [May]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 063/102] firmware_loader: use kernel credentials when reading firmware
    Date
    From: Thiébaud Weksteen <tweek@google.com>

    commit 581dd69830341d299b0c097fc366097ab497d679 upstream.

    Device drivers may decide to not load firmware when probed to avoid
    slowing down the boot process should the firmware filesystem not be
    available yet. In this case, the firmware loading request may be done
    when a device file associated with the driver is first accessed. The
    credentials of the userspace process accessing the device file may be
    used to validate access to the firmware files requested by the driver.
    Ensure that the kernel assumes the responsibility of reading the
    firmware.

    This was observed on Android for a graphic driver loading their firmware
    when the device file (e.g. /dev/mali0) was first opened by userspace
    (i.e. surfaceflinger). The security context of surfaceflinger was used
    to validate the access to the firmware file (e.g.
    /vendor/firmware/mali.bin).

    Previously, Android configurations were not setting up the
    firmware_class.path command line argument and were relying on the
    userspace fallback mechanism. In this case, the security context of the
    userspace daemon (i.e. ueventd) was consistently used to read firmware
    files. More Android devices are now found to set firmware_class.path
    which gives the kernel the opportunity to read the firmware directly
    (via kernel_read_file_from_path_initns). In this scenario, the current
    process credentials were used, even if unrelated to the loading of the
    firmware file.

    Signed-off-by: Thiébaud Weksteen <tweek@google.com>
    Cc: <stable@vger.kernel.org> # 5.10
    Reviewed-by: Paul Moore <paul@paul-moore.com>
    Acked-by: Luis Chamberlain <mcgrof@kernel.org>
    Link: https://lore.kernel.org/r/20220502004952.3970800-1-tweek@google.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/base/firmware_loader/main.c | 17 +++++++++++++++++
    1 file changed, 17 insertions(+)

    --- a/drivers/base/firmware_loader/main.c
    +++ b/drivers/base/firmware_loader/main.c
    @@ -795,6 +795,8 @@ _request_firmware(const struct firmware
    size_t offset, u32 opt_flags)
    {
    struct firmware *fw = NULL;
    + struct cred *kern_cred = NULL;
    + const struct cred *old_cred;
    bool nondirect = false;
    int ret;

    @@ -811,6 +813,18 @@ _request_firmware(const struct firmware
    if (ret <= 0) /* error or already assigned */
    goto out;

    + /*
    + * We are about to try to access the firmware file. Because we may have been
    + * called by a driver when serving an unrelated request from userland, we use
    + * the kernel credentials to read the file.
    + */
    + kern_cred = prepare_kernel_cred(NULL);
    + if (!kern_cred) {
    + ret = -ENOMEM;
    + goto out;
    + }
    + old_cred = override_creds(kern_cred);
    +
    ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL);

    /* Only full reads can support decompression, platform, and sysfs. */
    @@ -836,6 +850,9 @@ _request_firmware(const struct firmware
    } else
    ret = assign_fw(fw, device);

    + revert_creds(old_cred);
    + put_cred(kern_cred);
    +
    out:
    if (ret < 0) {
    fw_abort_batch_reqs(fw);

    \
     
     \ /
      Last update: 2022-05-16 22:17    [W:4.118 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site