Update: [SRU][OEM-5.17][PATCH 0/1] CVE-2022-40307

Yuxuan Luo yuxuan.luo at canonical.com
Wed Apr 5 16:01:35 UTC 2023


On 4/4/23 16:23, Yuxuan Luo wrote:
> [Impact]
> There is a race condition that occurs in drivers/firmware/efi, between the
> efi_capsule_write() and efi_capsule_flush() functions of efi_capsule_fops,
> which ultimately results in UAF.
>
> [Backport]
> It is a clean cherry pick.
>
> [Test]
> Compile and boot tested.
> There is a proof of concept for this CVE, though, the prerequisite command,
> installing the efi_capsule_loader, fails as "No such device", indicating a
> requirement for physical hardware.
> The link to the PoC: https://lore.kernel.org/all/20220907102920.GA88602@ubuntu/

It turns out that what it needs is EFI firmware support. For virsh, this 
could be enabled by editing the XML:

```XML

<os firmware='efi'>
   <firmware>
     <feature enabled='no' name='secure-boot'/>
   </firmware>
</os>

```

Then, `modprobe capsule_loader` succeeds. However, after running the 
PoC, dmesg shows that

`efi: capsule not supported`, and the related code is:

```C

     /* Check if the capsule binary supported */
     ret = efi_capsule_supported(cap_info->header.guid,
                     cap_info->header.flags,
                     cap_info->header.imagesize,
                     &cap_info->reset_type);
     if (ret) {
         pr_err("capsule not supported\n");
         return ret;
     }

```

which indicates that the firmware support is not enough on tiano core.

Even though, the PoC still reveals a different behavior. On the 
vulnerable kernel, the `return();` function returns -1,

while the fixed kernel returns 0 for the step 5 in the PoC. And a 
warning, `efi: capsule upload not complete`, is popped

on the vulnerable kernel where it didn't on the fixed kernel. 
Corresponding code:

```C

/**
  * efi_capsule_flush - called by file close or file flush
  * @file: file pointer
  * @id: not used
  *
  *    If a capsule is being partially uploaded then calling this function
  *    will be treated as upload termination and will free those completed
  *    buffer pages and -ECANCELED will be returned.
  **/
static int efi_capsule_flush(struct file *file, fl_owner_t id)
{
     int ret = 0;
     struct capsule_info *cap_info = file->private_data;

     if (cap_info->index > 0) {
         pr_err("capsule upload not complete\n");
         efi_free_all_buff_pages(cap_info);
         ret = -ECANCELED;
     }
```

>
> [Potential Regression]
> Should be trivial.
>
> Hyunwoo Kim (1):
>    efi: capsule-loader: Fix use-after-free in efi_capsule_write
>
>   drivers/firmware/efi/capsule-loader.c | 31 ++++++---------------------
>   1 file changed, 7 insertions(+), 24 deletions(-)
>



More information about the kernel-team mailing list