On Mon, Apr 04, 2022 at 03:46:42PM +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. > > Signed-off-by: Thiébaud Weksteen <tweek@xxxxxxxxxx> > --- > drivers/base/firmware_loader/main.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c > index 94d1789a233e..416ee3cc6584 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,13 @@ _request_firmware(const struct firmware **firmware_p, const char *name, > if (ret <= 0) /* error or already assigned */ > goto out; > > + kern_cred = prepare_kernel_cred(NULL); > + if (!kern_cred) { > + ret = -ENOMEM; > + goto out; > + } > + old_cred = override_creds(kern_cred); Can you add a comment here before the call to prepare_kernel_cred() to say why you are doing this and what it is for? Otherwise it is not obvious at all. thanks, greg k-h