A recent vulnerability in the Linux kernel has been resolved. The issue revolved around the media aspeed, which affected the clock handling logic. The problem led to unintended DMA memory transfers resulting in random and sporadic memory corruption. The issue was extremely hard to debug due to the infrequent occurrence, making it a critical kernel panic.

Original References

1. Linux Kernel Commit (media: aspeed: fix clock handling logic)
2. Linux Kernel Commit (clk: ast260: fix reset settings for eclk and vclk)

Vulnerability and Exploit Details

In the Linux kernel, the video engine uses eclk (external clock) and vclk (typically the video memory clock) as its clock sources. The reset control is coupled with eclk, causing an improper reset in the video engine hardware. Consequently, the hardware generated unexpected DMA (Direct Memory Access) transfers that led to memory corruption.

The issue was observed on some specific AST250 System on Chips (SoCs), and it would cause a critical kernel panic. The problem is extremely hard to debug due to its sporadic nature and various shapes of signatures. The issue could also be observed when the video engine was not actively used, since udevd would turn on the video engine hardware for a short time during every boot.

The Fix

In order to resolve this issue, the clock handling logic was changed to ensure that the reset de-assertion is triggered after enabling both eclk and vclk. Additionally, a clk_unprepare call was added in case the probe fails.

Regarding the reset settings for eclk and vclk, the video engine reset setting is now coupled with eclk to match it with the setting for previous Aspeed SoCs, which is defined in clk-aspeed.c. Additionally, reset bit 6 is defined as 'Video Engine' reset in the datasheet and should be de-asserted when eclk is enabled. This commit fixes these settings.

Code Snippet

Here's a brief code snippet showcasing the changes made to fix the clock handling logic in the Linux kernel:

- clk_prepare_enable(smc->eclk);
+ clk_prepare_enable(smc->vclk);
+ clk_prepare_enable(smc->eclk);
reset_control_deassert(smc->rst_w);
mdelay(10);
- clk_prepare_enable(smc->vclk);
...
+ clk_disable_unprepare(smc->vclk);
...

Conclusion

The Linux kernel vulnerability, CVE-2020-36787, has been resolved by fixing the clock handling logic and reset settings in the media aspeed component. This fix ensures proper reset assertion and prevents random and sporadic memory corruption due to improper DMA memory transfers.

Timeline

Published on: 02/28/2024 09:15:37 UTC
Last modified on: 02/28/2024 14:06:45 UTC