dln2_spi_get_cs_num() stores the chip select count reported by the device
straight into host->num_chipselect, and dln2_spi_cs_enable_all() then
evaluates GENMASK(num_chipselect - 1, 0), whose shift exponent is out of
bounds whenever that count is zero or larger than BITS_PER_LONG. The
resulting mask is handed back to the device in a u8 field, so any count
outside 1..8 is invalid regardless. Reject such counts with -EPROTO in
dln2_spi_get_cs_num(), where the value is first read.
Closes: https://lore.kernel.org/all/CA+0ovCioY634b646jDcs2cFmg_1q2UMN4wuTQ1V26Gy+Dm_c+A@mail.gmail.com/
Signed-off-by: Farhad Alemi <farhad.alemi@berkeley.edu>
---
The device was emulated.
--- a/drivers/spi/spi-dln2.c
+++ b/drivers/spi/spi-dln2.c
@@ -71,6 +71,8 @@
#define DLN2_SPI_GET_MAX_DELAY_BETWEEN_FRAMES DLN2_SPI_CMD(0x4C)
#define DLN2_SPI_MAX_XFER_SIZE 256
+/* The CS bitmask is carried in a u8 on the wire, so 8 lines is the ceiling. */
+#define DLN2_SPI_MAX_CS 8
#define DLN2_SPI_BUF_SIZE (DLN2_SPI_MAX_XFER_SIZE + 16)
#define DLN2_SPI_ATTR_LEAVE_SS_LOW BIT(0)
#define DLN2_TRANSFERS_WAIT_COMPLETE 1
@@ -201,6 +203,8 @@ static int dln2_spi_get_cs_num(struct dln2_spi
*dln2, u16 *cs_num)
return -EPROTO;
*cs_num = le16_to_cpu(rx.cs_count);
+ if (*cs_num == 0 || *cs_num > DLN2_SPI_MAX_CS)
+ return -EPROTO;
dev_dbg(&dln2->pdev->dev, "cs_num = %d\n", *cs_num);
On Thu, Sep 10, 2026 at 09:43:38PM +0000, Farhad Alemi wrote: > dln2_spi_get_cs_num() stores the chip select count reported by the device > straight into host->num_chipselect, and dln2_spi_cs_enable_all() then > evaluates GENMASK(num_chipselect - 1, 0), whose shift exponent is out of This doesn't apply against current code, please check and resend.
On Thu, Sep 10, 2026 at 09:43:38PM +0000, Farhad Alemi wrote: > dln2_spi_get_cs_num() stores the chip select count reported by the device > straight into host->num_chipselect, and dln2_spi_cs_enable_all() then > evaluates GENMASK(num_chipselect - 1, 0), whose shift exponent is out of > bounds whenever that count is zero or larger than BITS_PER_LONG. The > resulting mask is handed back to the device in a u8 field, so any count > outside 1..8 is invalid regardless. Reject such counts with -EPROTO in > dln2_spi_get_cs_num(), where the value is first read. You need to check with the datasheet. It says that only 4 SS lines can be programmed. The reserved bits must be held in 1. So, all in all, the _MAX_CS should be 4. > Closes: https://lore.kernel.org/all/CA+0ovCioY634b646jDcs2cFmg_1q2UMN4wuTQ1V26Gy+Dm_c+A@mail.gmail.com/ > Signed-off-by: Farhad Alemi <farhad.alemi@berkeley.edu> > --- Datasheet: https://diolan.com/media/wysiwyg/downloads/dln-api-manual.pdf -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.