lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 22 Apr 2022 07:37:10 -0700
From:   Luis Chamberlain <mcgrof@...nel.org>
To:     Thiébaud Weksteen <tweek@...gle.com>
Cc:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Jeffrey Vander Stoep <jeffv@...gle.com>,
        Saravana Kannan <saravanak@...gle.com>,
        Alistair Delva <adelva@...gle.com>,
        Adam Shih <adamshih@...gle.com>, selinux@...r.kernel.org,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] firmware_loader: use kernel credentials when reading
 firmware

On Fri, Apr 22, 2022 at 11:32:15AM +1000, Thiébaud Weksteen wrote:
> 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).
> 
> Because previous configurations were relying on the userspace fallback
> mechanism, the security context of the userspace daemon (i.e. ueventd)
> was consistently used to read firmware files. More devices are found to
> use the command line argument firmware_class.path which gives the kernel
> the opportunity to read the firmware directly, hence surfacing this
> misattribution.

Can you elaborate on the last sentence? It's unclear how what you
describe is used exactly to allow driver to use direct filesystem
firmware loading.

And, given the feedback from Android it would seem this is a fix
which likely may be desirable to backport to some stable kernels?

Otherwise looks good

Reviewed-by: Luis Chamberlain <mcgrof@...nel.org>

> Signed-off-by: Thiébaud Weksteen <tweek@...gle.com>
> ---
> v2: Add comment
> 
>  drivers/base/firmware_loader/main.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
> index 94d1789a233e..8f3c2b2cfc61 100644
> --- a/drivers/base/firmware_loader/main.c
> +++ b/drivers/base/firmware_loader/main.c
> @@ -735,6 +735,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
>  		  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;
>  
> @@ -751,6 +753,18 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
>  	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. */
> @@ -776,6 +790,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
>  	} else
>  		ret = assign_fw(fw, device);
>  
> +	revert_creds(old_cred);
> +
>   out:
>  	if (ret < 0) {
>  		fw_abort_batch_reqs(fw);
> -- 
> 2.36.0.rc2.479.g8af0fa9b8e-goog
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ