Bit 7 of the 'Device Type 2' (0Bh) register is reserved in the FSA9480 device, but is used by the FSA880 and TSU6111 devices.
From FSA9480 datasheet, Table 18. Device Type 2:
Reset Value: x0000000 =========================================================================== Bit # | Name | Size (Bits) | Description --------------------------------------------------------------------------- 7 | Reserved | 1 | NA
From FSA880 datasheet, Table 13. Device Type 2:
Reset Value: 0xxx0000 =========================================================================== Bit # | Name | Size (Bits) | Description --------------------------------------------------------------------------- 7 | Unknown | 1 | 1: Any accessory detected as unknown | Accessory | | or an accessory that cannot be | | | detected as being valid even | | | though ID_CON is not floating | | | 0: Unknown accessory not detected
From TSU6111 datasheet, Device Type 2:
Reset Value:x0000000 =========================================================================== Bit # | Name | Size (Bits) | Description --------------------------------------------------------------------------- 7 | Audio Type 3 | 1 | Audio device type 3
So the value obtained from the FSA9480_REG_DEV_T2 register in the fsa9480_detect_dev() function may have the 7th bit set. In this case, the 'dev' parameter in the fsa9480_handle_change() function will be 15. And this will cause the 'cable_types' array to overflow when accessed at this index.
Extend the 'cable_types' array with a new value 'DEV_RESERVED' as specified in the FSA9480 datasheet. Do not use it as it serves for various purposes in the listed devices.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: bad5b5e707a5 ("extcon: Add fsa9480 extcon driver") Cc: stable@vger.kernel.org Signed-off-by: Vladimir Moskovkin Vladimir.Moskovkin@kaspersky.com --- drivers/extcon/extcon-fsa9480.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/extcon/extcon-fsa9480.c b/drivers/extcon/extcon-fsa9480.c index b11b43171063..30972a7214f7 100644 --- a/drivers/extcon/extcon-fsa9480.c +++ b/drivers/extcon/extcon-fsa9480.c @@ -68,6 +68,7 @@ #define DEV_T1_CHARGER_MASK (DEV_DEDICATED_CHG | DEV_USB_CHG)
/* Device Type 2 */ +#define DEV_RESERVED 15 #define DEV_AV 14 #define DEV_TTY 13 #define DEV_PPD 12 @@ -133,6 +134,7 @@ static const u64 cable_types[] = { [DEV_USB] = BIT_ULL(EXTCON_USB) | BIT_ULL(EXTCON_CHG_USB_SDP), [DEV_AUDIO_2] = BIT_ULL(EXTCON_JACK_LINE_OUT), [DEV_AUDIO_1] = BIT_ULL(EXTCON_JACK_LINE_OUT), + [DEV_RESERVED] = 0, [DEV_AV] = BIT_ULL(EXTCON_JACK_LINE_OUT) | BIT_ULL(EXTCON_JACK_VIDEO_OUT), [DEV_TTY] = BIT_ULL(EXTCON_JIG), @@ -228,7 +230,7 @@ static void fsa9480_detect_dev(struct fsa9480_usbsw *usbsw) dev_err(usbsw->dev, "%s: failed to read registers", __func__); return; } - val = val2 << 8 | val1; + val = val2 << 8 | (val1 & 0xFF);
dev_info(usbsw->dev, "dev1: 0x%x, dev2: 0x%x\n", val1, val2);