CVE-2021-47549 - Resolving sata_fsl UAF Vulnerability in Linux Kernel

In the Linux kernel, a use-after-free (UAF) vulnerability has been resolved which affected the sata_fsl Port Stop function used within the PPC64 GNU/Linux distribution. This vulnerability could lead to data corruption or even a kernel panic; however, it has been patched, minimizing the potential risks. In this article, we will discuss the details and the resolution of this issue.

The vulnerability (CVE-2021-47549) specifically impacted the sata_fsl_port_stop function in the Linux kernel when the rmmod sata_fsl.ko command was executed. The bug that was reported is shown below:

BUG: Unable to handle kernel data access on read at x80000800805b502c
Oops: Kernel access of bad area, sig: 11 [#1]
NIP [c0000000000388a4] .ioread32+x4/x20
LR [80000000000c6034] .sata_fsl_port_stop+x44/xe [sata_fsl]
Call Trace:
.free_irq+x1c/x4e (unreliable)
.ata_host_stop+x74/xd [libata]
.release_nodes+x330/x3f
.device_release_driver_internal+x178/x2c
.driver_detach+x64/xd
.bus_remove_driver+x70/xf
.driver_unregister+x38/x80
.platform_driver_unregister+x14/x30
.fsl_sata_driver_exit+x18/xa20 [sata_fsl]
.__se_sys_delete_module+x1ec/x2d
.system_call_exception+xfc/x1f
system_call_common+xf8/x200

Upon examining the stack trace, one can see that the BUG is triggered from the following

driver_detach
  device_release_driver_internal
    __device_release_driver
      drv->remove(dev) --> platform_drv_remove/platform_remove
        drv->remove(dev) --> sata_fsl_remove
          iounmap(host_priv->hcr_base);                  <---- unmap
          kfree(host_priv);                               <---- free
      devres_release_all
        release_nodes
          dr->node.release(dev, dr->data) --> ata_host_stop
            ap->ops->port_stop(ap) --> sata_fsl_port_stop
                ioread32(hcr_base + HCONTROL)             <---- UAF
            host->ops->host_stop(host)

The iounmap(host_priv->hcr_base) and kfree(host_priv) functions should not be executed in drv->remove. These functions should be executed in host_stop after port_stop. To resolve this issue, these functions have been moved to a new function called sata_fsl_host_stop and bind it to host_stop.

To better understand the issue and its resolution, please refer to the Linux kernel repository on GitHub, which contains the relevant commit that resolves the UAF vulnerability in the sata_fsl_port_stop function.

By applying the necessary changes to the Linux kernel, maintainers have successfully patched the UAF vulnerability and ensured improved stability and security in the affected Linux distributions.

Timeline

Published on: 05/24/2024 15:15:19 UTC
Last modified on: 12/19/2024 07:44:36 UTC