A recent vulnerability found in the Linux kernel has been successfully resolved. The vulnerability was specifically related to the serial SC16IS7XX integrated circuit (IC) and the regmap functions used for managing FIFO operations. In this post, we will discuss the details of the vulnerability, the changes made to resolve it, and the relevant code snippet explaining the solution.

Vulnerability Background

The SC16IS7XX IC supports a burst mode for accessing the FIFOs (First In First Out memory buffer). In this mode, the initial register address (value $00) is sent, followed by all the FIFO data without resending the register address for each R/W (read/write) byte. This means that the IC does not increment the register address for each byte read/write operation.

The functions regmap_raw_read() and regmap_raw_write() were used to perform IO operations over multiple registers. Although these functions were working correctly in burst mode on the SPI (Serial Peripheral Interface) bus, they would corrupt the regmap cache if it was not manually disabled. This corruption was caused by the assumption these functions made when the read/write size was more than one byte, namely that the register address was incremented for each byte, which is not the case in burst mode.

Solution

To rectify this vulnerability, the FIFO read/write functions were converted to use the regmap _noinc_ versions. This change frees developers from having to manually disable cache control, which was previously required when using the _raw_ versions. The FIFO registers are now properly declared as volatile, ensuring that cache will not be used/updated during FIFO access operations.

Code Snippet for the Solution

/* Replace the original regmap_raw_read() function */
ret = regmap_noinc_read(map, UART_SC16IS7XX_FIFO_REG, buf, len);

/* Replace the original regmap_raw_write() function */
ret = regmap_noinc_write(map, UART_SC16IS7XX_FIFO_REG, buf, len);

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bbdfb3e5fd6b5cc7dddb6f3ed7d1f6b81fd9e1ee

Exploit Details

Before the implementation of the _noinc_ regmap functions, the regmap cache could be corrupted due to the incorrect handling of multiple R/W byte operations in burst mode. This could potentially lead to system instability, incorrect data being read or written, and possible denial of service attacks. By converting to the _noinc_ functions, the regmap cache is properly maintained and secured, eliminating these risks.

Conclusion

The vulnerability in the Linux kernel with the serial SC16IS7XX IC has been resolved by converting the FIFO read/write functions to use the more appropriate _noinc_ regmap functions. The solution provided ensures that cache corruption does not occur in burst mode, improving overall system stability and security.

Timeline

Published on: 03/11/2024 18:15:16 UTC
Last modified on: 04/13/2024 12:15:11 UTC