Linux GPIO subsystem development
 help / color / mirror / Atom feed
* [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling
@ 2026-11-03 21:29 Lee Jones
  2026-11-03 21:29 ` [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs Lee Jones
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Matthias Brugger, AngeloGioacchino Del Regno, linux-kernel,
	linux-arm-kernel, linux-mediatek
  Cc: Aaron Kling, Ajay Kishore, Andreas Färber, Andreas Kemnade,
	Andre Przywara, Bartosz Golaszewski, Bjorn Andersson,
	Chen-Yu Tsai, Christian Marangi, Daniel Golle, Hao Chang,
	H. Nikolaus Schaller, James Tai, Jernej Skrabec, Jonathan Hunter,
	Linus Walleij, linux-arm-msm, linux-gpio, linux-mips,
	linux-realtek-soc, linux-sunxi, linux-tegra, Paul Boddie,
	Paul Cercueil, Qingliang Li, Rob Herring, Ryder.Lee, Sam Shih,
	Samuel Holland, Sean Wang, Thierry Reding, Tzuyi Chang,
	Yu-Chun Lin, zhouyanjie

These issues were reported by Sashiko.

Cc: Aaron Kling <webgeek1234@gmail.com>
Cc: Ajay Kishore <akisho@codeaurora.org>
Cc: "Andreas Färber" <afaerber@suse.com>
Cc: Andreas Kemnade <andreas@kemnade.info>
Cc: Andre Przywara <andre.przywara@arm.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Bjorn Andersson <andersson@kernel.org>
Cc: Chen-Yu Tsai <wens@kernel.org>
Cc: Christian Marangi <ansuelsmth@gmail.com>
Cc: Daniel Golle <daniel@makrotopia.org>
Cc: Hao Chang <ot_chhao.chang@mediatek.com>
Cc: "H. Nikolaus Schaller" <hns@goldelico.com>
Cc: James Tai <james.tai@realtek.com>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-arm-msm@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-mediatek@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-realtek-soc@lists.infradead.org
Cc: linux-sunxi@lists.linux.dev
Cc: linux-tegra@vger.kernel.org
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: Paul Boddie <paul@boddie.org.uk>
Cc: Paul Cercueil <paul@crapouillou.net>
Cc: Qingliang Li <qingliang.li@mediatek.com>
Cc: Rob Herring <robh@kernel.org>
Cc: "Ryder.Lee" <ryder.lee@mediatek.com>
Cc: Sam Shih <sam.shih@mediatek.com>
Cc: Samuel Holland <samuel@sholland.org>
Cc: Sean Wang <sean.wang@kernel.org>
Cc: Thierry Reding <thierry.reding@kernel.org>
Cc: Tzuyi Chang <tychang@realtek.com>
Cc: Yu-Chun Lin <eleanor.lin@realtek.com>
Cc: zhouyanjie@wanyeetech.com

Lee Jones (10):
  pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has
    no IRQs
  pinctrl: tegra186: Fix out-of-bounds register bank index for AON drive
    groups
  pinctrl: ingenic: Fix element type of x1600_sfc_funcs array
  pinctrl: mediatek: mt7981: Add missing entries to mt7981_ant_sel_funcs
  pinctrl: realtek: Prevent out-of-bounds access in
    rtd_pinctrl_find_config()
  pinctrl: realtek: Fix bit shift when configuring RTD_HIGH_VIL
  pinctrl: realtek: Initialise omitted offset fields to NA in config
    macros
  pinctrl: mediatek: Clean up partially initialised hw->eint on error
  pinctrl: mediatek: Prevent divide-by-zero for pins with fixed drive
    strength
  pinctrl: qcom: Check qcom_scm_io_readl() return value in
    msm_gpio_irq_set_type()

 drivers/pinctrl/mediatek/pinctrl-mt7981.c     |   2 +-
 .../pinctrl/mediatek/pinctrl-mtk-common-v2.c  |  24 ++++-
 drivers/pinctrl/pinctrl-ingenic.c             |   2 +-
 drivers/pinctrl/qcom/pinctrl-msm.c            |  10 +-
 drivers/pinctrl/realtek/pinctrl-rtd.c         |   5 +-
 drivers/pinctrl/realtek/pinctrl-rtd.h         |   5 +
 drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c      |  11 +-
 drivers/pinctrl/tegra/pinctrl-tegra186.c      | 102 +++++++++---------
 8 files changed, 93 insertions(+), 68 deletions(-)

-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:42   ` sashiko-bot
  2026-11-03 21:29 ` [PATCH 02/10] pinctrl: tegra186: Fix out-of-bounds register bank index for AON drive groups Lee Jones
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Linus Walleij, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	Andre Przywara, linux-gpio, linux-arm-kernel, linux-sunxi,
	linux-kernel
  Cc: stable

In prepare_function_table(), irq_bank and last_bank are initialised to 0
and last_bank is updated on every bank regardless of whether it supports
interrupts.  On SoCs where bank 0 (PA) has no pins or does not support
interrupts (such as Allwinner A523 and A733), the first IRQ-capable bank
has bank > 0, which causes irq_bank to be incremented to 1 instead of
starting at 0.  As a result, the final IRQ bank receives irq_bank equal
to desc->irq_banks and writes out-of-bounds past pctl->irq_array during
sunxi_pinctrl_build_state().

Initialise irq_bank and last_bank to -1 and only update last_bank when
processing an IRQ-capable bank so that irq_bank always starts at 0 and
increments sequentially across IRQ-capable banks.

Fixes: f5e2cd34b12f ("pinctrl: sunxi: allow reading mux values from DT")
Closes: https://sashiko.dev/#/bug/linux-9c4dd832-02d4-4096-9e91-a03c1d4d85b3
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
index 8bcd566593ae..79ca1a7c4837 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
@@ -208,8 +208,8 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
 	 * Assign the function's memory and fill in GPIOs, IRQ and a sentinel.
 	 * The extra functions will be filled in later.
 	 */
-	irq_bank = 0;
-	last_bank = 0;
+	irq_bank = -1;
+	last_bank = -1;
 	for (i = 0; i < npins; i++) {
 		struct sunxi_desc_pin *pin = &pins[i];
 		int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;
@@ -222,17 +222,16 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
 		func[1].muxval = 1;
 
 		if (irq_mux) {
-			if (bank > last_bank)
+			if (bank > last_bank) {
 				irq_bank++;
+				last_bank = bank;
+			}
 			func[lastfunc].muxval = irq_mux;
 			func[lastfunc].irqbank = irq_bank;
 			func[lastfunc].irqnum = pin->pin.number % PINS_PER_BANK;
 			func[lastfunc].name = "irq";
 		}
 
-		if (bank > last_bank)
-			last_bank = bank;
-
 		pin->functions = func;
 
 		/* Skip over the other needed functions and the sentinel. */
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/10] pinctrl: tegra186: Fix out-of-bounds register bank index for AON drive groups
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
  2026-11-03 21:29 ` [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array Lee Jones
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Linus Walleij, Thierry Reding, Jonathan Hunter, Aaron Kling,
	linux-gpio, linux-tegra, linux-kernel
  Cc: stable

The Tegra186 AON pinmux controller has only a single register bank
(nbanks = 1, indexed at 0), and all PINGROUP entries in tegra186_aon_groups
accordingly specify bank 0.  However, all 51 AON drive_* macro definitions
pass drv_bank = 1 as the final argument to DRV_PINGROUP_ENTRY_Y, causing
any drive configuration read or write on an AON drive group to index
pmx->regs[1] out-of-bounds.

Update the AON drive_* macro definitions to use register bank 0.

Fixes: 542baf77f092 ("pinctrl: tegra: Add Tegra186 pinmux driver")
Closes: https://sashiko.dev/#/bug/linux-a9a7165c-c5eb-463a-b7b1-24a30416b33b
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/tegra/pinctrl-tegra186.c | 102 +++++++++++------------
 1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/drivers/pinctrl/tegra/pinctrl-tegra186.c b/drivers/pinctrl/tegra/pinctrl-tegra186.c
index 4a1d6476af9b..3bf1814dbd24 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra186.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra186.c
@@ -1585,57 +1585,57 @@ static const char * const tegra186_functions[] = {
 #define drive_qspi_comp                 DRV_PINGROUP_ENTRY_N(no_entry)
 
 /* AON drive pin groups */
-#define drive_touch_clk_pee2            DRV_PINGROUP_ENTRY_Y(0x2004,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart3_cts_pw5             DRV_PINGROUP_ENTRY_Y(0x200c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart3_rts_pw4             DRV_PINGROUP_ENTRY_Y(0x2014,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart3_rx_pw3              DRV_PINGROUP_ENTRY_Y(0x201c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart3_tx_pw2              DRV_PINGROUP_ENTRY_Y(0x2024,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gen8_i2c_sda_pw1          DRV_PINGROUP_ENTRY_Y(0x202c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gen8_i2c_scl_pw0          DRV_PINGROUP_ENTRY_Y(0x2034,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart7_rx_pw7              DRV_PINGROUP_ENTRY_Y(0x203c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_uart7_tx_pw6              DRV_PINGROUP_ENTRY_Y(0x2044,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen0_pv0             DRV_PINGROUP_ENTRY_Y(0x204c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen1_pv1             DRV_PINGROUP_ENTRY_Y(0x2054,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen2_pv2             DRV_PINGROUP_ENTRY_Y(0x205c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen3_pv3             DRV_PINGROUP_ENTRY_Y(0x2064,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen4_pv4             DRV_PINGROUP_ENTRY_Y(0x206c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen5_pv5             DRV_PINGROUP_ENTRY_Y(0x2074,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen6_pv6             DRV_PINGROUP_ENTRY_Y(0x207c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen7_pv7             DRV_PINGROUP_ENTRY_Y(0x2084,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen8_pee0            DRV_PINGROUP_ENTRY_Y(0x208c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sen9_pee1            DRV_PINGROUP_ENTRY_Y(0x2094,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_can_gpio7_paa7            DRV_PINGROUP_ENTRY_Y(0x3004,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can1_dout_pz0             DRV_PINGROUP_ENTRY_Y(0x300C,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can1_din_pz1              DRV_PINGROUP_ENTRY_Y(0x3014,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can0_dout_pz2             DRV_PINGROUP_ENTRY_Y(0x301c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can0_din_pz3              DRV_PINGROUP_ENTRY_Y(0x3024,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio0_paa0            DRV_PINGROUP_ENTRY_Y(0x302c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio1_paa1            DRV_PINGROUP_ENTRY_Y(0x3034,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio2_paa2            DRV_PINGROUP_ENTRY_Y(0x303c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio3_paa3            DRV_PINGROUP_ENTRY_Y(0x3044,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio4_paa4            DRV_PINGROUP_ENTRY_Y(0x304c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio5_paa5            DRV_PINGROUP_ENTRY_Y(0x3054,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_can_gpio6_paa6            DRV_PINGROUP_ENTRY_Y(0x305c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	1)
-#define drive_gpio_sw1_pff1             DRV_PINGROUP_ENTRY_Y(0x1004,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sw2_pff2             DRV_PINGROUP_ENTRY_Y(0x100c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sw3_pff3             DRV_PINGROUP_ENTRY_Y(0x1014,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_sw4_pff4             DRV_PINGROUP_ENTRY_Y(0x101c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_shutdown                  DRV_PINGROUP_ENTRY_Y(0x1024,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_pmu_int                   DRV_PINGROUP_ENTRY_Y(0x102C,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_safe_state_ps3            DRV_PINGROUP_ENTRY_Y(0x1034,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_vcomp_alert_ps4           DRV_PINGROUP_ENTRY_Y(0x103c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_soc_pwr_req               DRV_PINGROUP_ENTRY_Y(0x1044,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_batt_oc_ps2               DRV_PINGROUP_ENTRY_Y(0x104c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_clk_32k_in                DRV_PINGROUP_ENTRY_Y(0x1054,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_power_on_pff0             DRV_PINGROUP_ENTRY_Y(0x105c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_pwr_i2c_scl_ps0           DRV_PINGROUP_ENTRY_Y(0x1064,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_pwr_i2c_sda_ps1           DRV_PINGROUP_ENTRY_Y(0x106c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis0_pu0             DRV_PINGROUP_ENTRY_Y(0x1084,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis1_pu1             DRV_PINGROUP_ENTRY_Y(0x108c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis2_pu2             DRV_PINGROUP_ENTRY_Y(0x1094,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis3_pu3             DRV_PINGROUP_ENTRY_Y(0x109c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis4_pu4             DRV_PINGROUP_ENTRY_Y(0x10a4,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
-#define drive_gpio_dis5_pu5             DRV_PINGROUP_ENTRY_Y(0x10ac,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	1)
+#define drive_touch_clk_pee2            DRV_PINGROUP_ENTRY_Y(0x2004,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart3_cts_pw5             DRV_PINGROUP_ENTRY_Y(0x200c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart3_rts_pw4             DRV_PINGROUP_ENTRY_Y(0x2014,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart3_rx_pw3              DRV_PINGROUP_ENTRY_Y(0x201c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart3_tx_pw2              DRV_PINGROUP_ENTRY_Y(0x2024,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gen8_i2c_sda_pw1          DRV_PINGROUP_ENTRY_Y(0x202c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gen8_i2c_scl_pw0          DRV_PINGROUP_ENTRY_Y(0x2034,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart7_rx_pw7              DRV_PINGROUP_ENTRY_Y(0x203c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_uart7_tx_pw6              DRV_PINGROUP_ENTRY_Y(0x2044,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen0_pv0             DRV_PINGROUP_ENTRY_Y(0x204c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen1_pv1             DRV_PINGROUP_ENTRY_Y(0x2054,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen2_pv2             DRV_PINGROUP_ENTRY_Y(0x205c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen3_pv3             DRV_PINGROUP_ENTRY_Y(0x2064,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen4_pv4             DRV_PINGROUP_ENTRY_Y(0x206c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen5_pv5             DRV_PINGROUP_ENTRY_Y(0x2074,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen6_pv6             DRV_PINGROUP_ENTRY_Y(0x207c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen7_pv7             DRV_PINGROUP_ENTRY_Y(0x2084,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen8_pee0            DRV_PINGROUP_ENTRY_Y(0x208c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sen9_pee1            DRV_PINGROUP_ENTRY_Y(0x2094,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_can_gpio7_paa7            DRV_PINGROUP_ENTRY_Y(0x3004,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can1_dout_pz0             DRV_PINGROUP_ENTRY_Y(0x300C,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can1_din_pz1              DRV_PINGROUP_ENTRY_Y(0x3014,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can0_dout_pz2             DRV_PINGROUP_ENTRY_Y(0x301c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can0_din_pz3              DRV_PINGROUP_ENTRY_Y(0x3024,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio0_paa0            DRV_PINGROUP_ENTRY_Y(0x302c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio1_paa1            DRV_PINGROUP_ENTRY_Y(0x3034,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio2_paa2            DRV_PINGROUP_ENTRY_Y(0x303c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio3_paa3            DRV_PINGROUP_ENTRY_Y(0x3044,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio4_paa4            DRV_PINGROUP_ENTRY_Y(0x304c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio5_paa5            DRV_PINGROUP_ENTRY_Y(0x3054,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_can_gpio6_paa6            DRV_PINGROUP_ENTRY_Y(0x305c,	-1,	-1,	-1,	-1,	28,	2,	30,	2,	0)
+#define drive_gpio_sw1_pff1             DRV_PINGROUP_ENTRY_Y(0x1004,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sw2_pff2             DRV_PINGROUP_ENTRY_Y(0x100c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sw3_pff3             DRV_PINGROUP_ENTRY_Y(0x1014,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_sw4_pff4             DRV_PINGROUP_ENTRY_Y(0x101c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_shutdown                  DRV_PINGROUP_ENTRY_Y(0x1024,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_pmu_int                   DRV_PINGROUP_ENTRY_Y(0x102C,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_safe_state_ps3            DRV_PINGROUP_ENTRY_Y(0x1034,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_vcomp_alert_ps4           DRV_PINGROUP_ENTRY_Y(0x103c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_soc_pwr_req               DRV_PINGROUP_ENTRY_Y(0x1044,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_batt_oc_ps2               DRV_PINGROUP_ENTRY_Y(0x104c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_clk_32k_in                DRV_PINGROUP_ENTRY_Y(0x1054,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_power_on_pff0             DRV_PINGROUP_ENTRY_Y(0x105c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_pwr_i2c_scl_ps0           DRV_PINGROUP_ENTRY_Y(0x1064,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_pwr_i2c_sda_ps1           DRV_PINGROUP_ENTRY_Y(0x106c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis0_pu0             DRV_PINGROUP_ENTRY_Y(0x1084,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis1_pu1             DRV_PINGROUP_ENTRY_Y(0x108c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis2_pu2             DRV_PINGROUP_ENTRY_Y(0x1094,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis3_pu3             DRV_PINGROUP_ENTRY_Y(0x109c,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis4_pu4             DRV_PINGROUP_ENTRY_Y(0x10a4,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
+#define drive_gpio_dis5_pu5             DRV_PINGROUP_ENTRY_Y(0x10ac,	12,	5,	20,	5,	-1,	-1,	-1,	-1,	0)
 
 #define PINGROUP(pg_name, f0, f1, f2, f3, r, bank, pupd, e_io_hv, e_lpbk, e_input, e_lpdr, e_pbias_buf, \
 			gpio_sfio_sel, e_od, schmitt_b, drvtype, epreemp, io_reset, rfu_in)		\
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
  2026-11-03 21:29 ` [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs Lee Jones
  2026-11-03 21:29 ` [PATCH 02/10] pinctrl: tegra186: Fix out-of-bounds register bank index for AON drive groups Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 22:00   ` H. Nikolaus Schaller
  2026-11-03 21:29 ` [PATCH 04/10] pinctrl: mediatek: mt7981: Add missing entries to mt7981_ant_sel_funcs Lee Jones
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Paul Cercueil, Linus Walleij, Paul Boddie, zhouyanjie,
	H. Nikolaus Schaller, Andreas Kemnade, linux-mips, linux-gpio,
	linux-kernel
  Cc: stable

ingenic_pinmux_set_mux() treats grp->data as a u8 array of per-pin mux
modes (u8 *pin_modes = grp->data), and every other *_funcs array in the
Ingenic pinctrl driver is declared as u8[].  Because x1600_sfc_funcs[]
was declared as int[], indexing pin_modes[0..6] reads the first seven
bytes of the int array (0, 0, 0, 0, 0, 0, 0) instead of reading mode 2
for the seventh pin.

Change the element type of x1600_sfc_funcs[] from int to u8.

Fixes: 4da56f9c6f14 ("pinctrl: ingenic: add x1600 support")
Closes: https://sashiko.dev/#/bug/linux-5dccd0ae-9450-440a-87d0-44cc86d1af45
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/pinctrl-ingenic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
index 1aa6a6dc1209..5c06208b8854 100644
--- a/drivers/pinctrl/pinctrl-ingenic.c
+++ b/drivers/pinctrl/pinctrl-ingenic.c
@@ -2456,7 +2456,7 @@ static int x1600_mac_pins[] = {
 	0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
 };
 
-static int x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
+static u8 x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
 
 static const struct group_desc x1600_groups[] = {
 	INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/10] pinctrl: mediatek: mt7981: Add missing entries to mt7981_ant_sel_funcs
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (2 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 05/10] pinctrl: realtek: Prevent out-of-bounds access in rtd_pinctrl_find_config() Lee Jones
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Sean Wang, Linus Walleij, Matthias Brugger,
	AngeloGioacchino Del Regno, Sam Shih, Rob Herring, Daniel Golle,
	linux-mediatek, linux-gpio, linux-kernel, linux-arm-kernel
  Cc: stable

mt7981_ant_sel_pins[] defines 14 pins (pins 14..25, 34, and 35), all of
which select ANT_SEL at function mux mode 6, but mt7981_ant_sel_funcs[]
only contains 12 entries.  When mtk_pinmux_set_mux() iterates over
grp->num_pins (14), it reads two int elements past the end of
mt7981_ant_sel_funcs[].

Add the two missing mode 6 entries to mt7981_ant_sel_funcs[] so its
length matches mt7981_ant_sel_pins[].

Fixes: 6c83b2d94fcc ("pinctrl: add mt7981 pinctrl driver")
Closes: https://sashiko.dev/#/bug/linux-6233f285-1487-4d2d-afe3-d4ce3c445054
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/mediatek/pinctrl-mt7981.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
index 2325cc8b9345..62fec909408b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c
@@ -800,7 +800,7 @@ static int mt7981_mt7531_int_funcs[] = { 1, };
 
 /* ANT_SEL */
 static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 };
-static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
+static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
 
 static const struct group_desc mt7981_groups[] = {
 	/* @GPIO(0,1): WA_AICE(2) */
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/10] pinctrl: realtek: Prevent out-of-bounds access in rtd_pinctrl_find_config()
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (3 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 04/10] pinctrl: mediatek: mt7981: Add missing entries to mt7981_ant_sel_funcs Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 06/10] pinctrl: realtek: Fix bit shift when configuring RTD_HIGH_VIL Lee Jones
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, James Tai, Yu-Chun Lin, Andreas Färber, Linus Walleij,
	Tzuyi Chang, linux-arm-kernel, linux-realtek-soc, linux-gpio,
	linux-kernel
  Cc: stable

Several Realtek SoC pin configuration tables (such as rtd1319d_iso_configs,
rtd1619b_iso_configs, and the rtd1625 config tables) omit trailing pins
that do not support pin configuration, making data->info->num_configs
smaller than data->info->num_pins.  Because rtd_pinctrl_find_config()
indexes data->info->configs[pin] without checking data->info->num_configs,
requesting pin configuration on a trailing pin reads out-of-bounds memory.

Check that pin is less than data->info->num_configs before indexing
data->info->configs[].

Fixes: e99ce78030db ("pinctrl: realtek: Add common pinctrl driver for Realtek DHC RTD SoCs")
Closes: https://sashiko.dev/#/bug/linux-60e13761-fd9e-4fd3-826a-47344f36d4fa
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/realtek/pinctrl-rtd.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/realtek/pinctrl-rtd.c b/drivers/pinctrl/realtek/pinctrl-rtd.c
index 60222339726b..2b877099ec85 100644
--- a/drivers/pinctrl/realtek/pinctrl-rtd.c
+++ b/drivers/pinctrl/realtek/pinctrl-rtd.c
@@ -252,6 +252,9 @@ static const struct pinctrl_pin_desc
 static const struct rtd_pin_config_desc
 	*rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin)
 {
+	if (pin >= data->info->num_configs)
+		return NULL;
+
 	if (data->info->configs[pin].name)
 		return &data->info->configs[pin];
 
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/10] pinctrl: realtek: Fix bit shift when configuring RTD_HIGH_VIL
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (4 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 05/10] pinctrl: realtek: Prevent out-of-bounds access in rtd_pinctrl_find_config() Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 07/10] pinctrl: realtek: Initialise omitted offset fields to NA in config macros Lee Jones
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, James Tai, Yu-Chun Lin, Andreas Färber, Linus Walleij,
	Tzuyi Chang, linux-arm-kernel, linux-realtek-soc, linux-gpio,
	linux-kernel
  Cc: stable

In rtd_pconf_parse_conf(), the RTD_HIGH_VIL case prepares mask as
BIT(hvil_off) for regmap_update_bits(), but sets val = 1 without
shifting it to hvil_off.  Whenever hvil_off is non-zero,
regmap_update_bits() masks val with BIT(hvil_off) and clears the high
VIL bit instead of setting it.

Set val to BIT(hvil_off) so that the target bit is set as intended.

Fixes: dcc9334435b0 ("pinctrl: realtek: add support for slew rate, input voltage and high VIL")
Closes: https://sashiko.dev/#/bug/linux-e7077311-3f30-4b77-844b-1447519d0c84
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/realtek/pinctrl-rtd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/realtek/pinctrl-rtd.c b/drivers/pinctrl/realtek/pinctrl-rtd.c
index 2b877099ec85..72773600303b 100644
--- a/drivers/pinctrl/realtek/pinctrl-rtd.c
+++ b/drivers/pinctrl/realtek/pinctrl-rtd.c
@@ -473,7 +473,7 @@ static int rtd_pconf_parse_conf(struct rtd_pinctrl *data,
 		hvil_off = config_desc->base_bit + config_desc->hvil_offset;
 		reg_off = config_desc->reg_offset;
 		mask = BIT(hvil_off);
-		val = 1;
+		val = BIT(hvil_off);
 		break;
 
 	case RTD_DRIVE_STRENGTH_P:
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/10] pinctrl: realtek: Initialise omitted offset fields to NA in config macros
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (5 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 06/10] pinctrl: realtek: Fix bit shift when configuring RTD_HIGH_VIL Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error Lee Jones
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, James Tai, Yu-Chun Lin, Andreas Färber, Linus Walleij,
	Tzuyi Chang, linux-arm-kernel, linux-realtek-soc, linux-gpio,
	linux-kernel
  Cc: stable

The Realtek pinctrl driver uses NA (0xffffffff) as the sentinel for
unsupported pin configuration features.  However, RTK_PIN_CONFIG omits
input_volt_offset, slew_rate_offset, and hvil_offset, and
RTK_PIN_CONFIG_V2 omits slew_rate_offset and hvil_offset.  Because C99
designated initialisers zero-initialise omitted members, those fields
default to 0 instead of NA, causing rtd_pconf_parse_conf() to treat
unsupported features as valid at bit offset base_bit + 0 and corrupt
adjacent register bits.

Explicitly initialise the omitted offset fields to NA in RTK_PIN_CONFIG
and RTK_PIN_CONFIG_V2.

Fixes: dcc9334435b0 ("pinctrl: realtek: add support for slew rate, input voltage and high VIL")
Fixes: e309dbd523b8 ("pinctrl: realtek: add rtd1625 pinctrl driver")
Closes: https://sashiko.dev/#/bug/linux-fbd0bf54-6dba-4652-9418-270b11fb6d8b
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/realtek/pinctrl-rtd.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/pinctrl/realtek/pinctrl-rtd.h b/drivers/pinctrl/realtek/pinctrl-rtd.h
index 77c30ea76443..86db54ea3ce8 100644
--- a/drivers/pinctrl/realtek/pinctrl-rtd.h
+++ b/drivers/pinctrl/realtek/pinctrl-rtd.h
@@ -96,6 +96,9 @@ struct rtd_pin_reg_list {
 		.smt_offset = _smt_off, \
 		.power_offset = _pow_off, \
 		.curr_type = _curr_type, \
+		.input_volt_offset = NA, \
+		.slew_rate_offset = NA, \
+		.hvil_offset = NA, \
 	}
 
 #define RTK_PIN_CONFIG_V2(_name, _reg_off, _base_bit, _pud_en_off, \
@@ -112,6 +115,8 @@ struct rtd_pin_reg_list {
 		.power_offset = _pow_off, \
 		.input_volt_offset = _input_volt_off, \
 		.curr_type = _curr_type, \
+		.slew_rate_offset = NA, \
+		.hvil_offset = NA, \
 	}
 
 #define RTK_PIN_CONFIG_I2C(_name, _reg_off, _base_bit, _pud_en_off, \
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (6 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 07/10] pinctrl: realtek: Initialise omitted offset fields to NA in config macros Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:40   ` sashiko-bot
  2026-11-03 21:29 ` [PATCH 09/10] pinctrl: mediatek: Prevent divide-by-zero for pins with fixed drive strength Lee Jones
  2026-11-03 21:29 ` [PATCH 10/10] pinctrl: qcom: Check qcom_scm_io_readl() return value in msm_gpio_irq_set_type() Lee Jones
  9 siblings, 1 reply; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Sean Wang, Linus Walleij, Matthias Brugger,
	AngeloGioacchino Del Regno, Hao Chang, Qingliang Li,
	linux-mediatek, linux-gpio, linux-kernel, linux-arm-kernel
  Cc: stable

In mtk_build_eint(), if of_property_count_strings() fails or
hw->eint->nbase is non-positive, the function returns -EINVAL directly
after allocating hw->eint without jumping to err_free_base.  Because
callers such as mtk_paris_pinctrl_probe() and mtk_moore_pinctrl_probe()
log a warning and continue probing when mtk_build_eint() fails, leaving
hw->eint non-NULL with hw->eint->hw unset causes subsequent GPIO or
suspend/resume callbacks to dereference a NULL pointer inside
mtk_eint_do_suspend() or mtk_gpio_to_irq().

Jump to err_free_base on both error paths so hw->eint is freed and
reset to NULL.

Fixes: 3ef9f710efcb ("pinctrl: mediatek: Add EINT support for multiple addresses")
Closes: https://sashiko.dev/#/bug/linux-0689c07e-ef74-4bc2-b5de-bd2f361124bd
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index faa6dbf0f635..aa15c9e047d8 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -382,12 +382,16 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
 		return -ENOMEM;
 
 	count_reg_names = of_property_count_strings(np, "reg-names");
-	if (count_reg_names < 0)
-		return -EINVAL;
+	if (count_reg_names < 0) {
+		ret = -EINVAL;
+		goto err_free_base;
+	}
 
 	hw->eint->nbase = count_reg_names - (int)hw->soc->nbase_names;
-	if (hw->eint->nbase <= 0)
-		return -EINVAL;
+	if (hw->eint->nbase <= 0) {
+		ret = -EINVAL;
+		goto err_free_base;
+	}
 
 	hw->eint->base = devm_kmalloc_array(&pdev->dev, hw->eint->nbase,
 					    sizeof(*hw->eint->base), GFP_KERNEL | __GFP_ZERO);
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/10] pinctrl: mediatek: Prevent divide-by-zero for pins with fixed drive strength
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (7 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  2026-11-03 21:29 ` [PATCH 10/10] pinctrl: qcom: Check qcom_scm_io_readl() return value in msm_gpio_irq_set_type() Lee Jones
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Sean Wang, Linus Walleij, Matthias Brugger,
	AngeloGioacchino Del Regno, Ryder.Lee, linux-mediatek, linux-gpio,
	linux-kernel, linux-arm-kernel
  Cc: stable

mtk_drive[] only defines entries for DRV_GRP0 (1) through DRV_GRP4 (5),
leaving mtk_drive[DRV_FIXED] (0) zero-initialised with min = 0, max = 0,
step = 0, and scal = 0.  If mtk_pinconf_drive_set() or
mtk_pinconf_drive_set_rev1() is called with arg = 0 on a pin with
drv_n == DRV_FIXED, the range check (0 >= 0 && 0 <= 0) succeeds and
!(arg % tb->step) divides by zero.  Similarly, mtk_pinconf_drive_get()
and mtk_pinconf_drive_get_rev1() divide by tb->scal (0) if the pin has
drive register fields defined.

Return -ENOTSUPP immediately when desc->drv_n == DRV_FIXED.

Fixes: c28321979ba8 ("pinctrl: mediatek: add driving strength related support to pinctrl-mtk-common-v2.c")
Closes: https://sashiko.dev/#/bug/linux-d3852d37-6806-4c41-a493-f249dd59d0c6
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
index aa15c9e047d8..1243862983b9 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
@@ -1040,6 +1040,9 @@ int mtk_pinconf_drive_set(struct mtk_pinctrl *hw,
 	const struct mtk_drive_desc *tb;
 	int err = -ENOTSUPP;
 
+	if (desc->drv_n == DRV_FIXED)
+		return -ENOTSUPP;
+
 	tb = &mtk_drive[desc->drv_n];
 	/* 4mA when (e8, e4) = (0, 0)
 	 * 8mA when (e8, e4) = (0, 1)
@@ -1069,6 +1072,9 @@ int mtk_pinconf_drive_get(struct mtk_pinctrl *hw,
 	const struct mtk_drive_desc *tb;
 	int err, val1, val2;
 
+	if (desc->drv_n == DRV_FIXED)
+		return -ENOTSUPP;
+
 	tb = &mtk_drive[desc->drv_n];
 
 	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_E4, &val1);
@@ -1095,6 +1101,9 @@ int mtk_pinconf_drive_set_rev1(struct mtk_pinctrl *hw,
 	const struct mtk_drive_desc *tb;
 	int err = -ENOTSUPP;
 
+	if (desc->drv_n == DRV_FIXED)
+		return -ENOTSUPP;
+
 	tb = &mtk_drive[desc->drv_n];
 
 	if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
@@ -1116,6 +1125,9 @@ int mtk_pinconf_drive_get_rev1(struct mtk_pinctrl *hw,
 	const struct mtk_drive_desc *tb;
 	int err, val1;
 
+	if (desc->drv_n == DRV_FIXED)
+		return -ENOTSUPP;
+
 	tb = &mtk_drive[desc->drv_n];
 
 	err = mtk_hw_get_value(hw, desc, PINCTRL_PIN_REG_DRV, &val1);
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/10] pinctrl: qcom: Check qcom_scm_io_readl() return value in msm_gpio_irq_set_type()
  2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
                   ` (8 preceding siblings ...)
  2026-11-03 21:29 ` [PATCH 09/10] pinctrl: mediatek: Prevent divide-by-zero for pins with fixed drive strength Lee Jones
@ 2026-11-03 21:29 ` Lee Jones
  9 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2026-11-03 21:29 UTC (permalink / raw)
  To: lee, Bartosz Golaszewski, Bjorn Andersson, Linus Walleij,
	Ajay Kishore, Christian Marangi, linux-arm-msm, linux-gpio,
	linux-kernel
  Cc: stable

In msm_gpio_irq_set_type(), when pctrl->intr_target_use_scm is set, the
return value of qcom_scm_io_readl(addr, &val) is ignored.  If the SCM read
fails, val remains uninitialised and its stack contents are modified and
written back to the hardware register via qcom_scm_io_writel().

Check the return value of qcom_scm_io_readl() before modifying and writing
back val.

Fixes: 13bec8d49bdf ("pinctrl: qcom: use scm_call to route GPIO irq to Apps")
Closes: https://sashiko.dev/#/bug/linux-a5545ffd-48cc-4856-94cc-4b2dd7968f50
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
---
 drivers/pinctrl/qcom/pinctrl-msm.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 27f06bbc113c..1b46735fc4bc 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1105,11 +1105,13 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 		u32 addr = pctrl->phys_base[0] + reg;
 		int ret;
 
-		qcom_scm_io_readl(addr, &val);
-		val &= ~(intr_target_mask << g->intr_target_bit);
-		val |= g->intr_target_kpss_val << g->intr_target_bit;
+		ret = qcom_scm_io_readl(addr, &val);
+		if (!ret) {
+			val &= ~(intr_target_mask << g->intr_target_bit);
+			val |= g->intr_target_kpss_val << g->intr_target_bit;
 
-		ret = qcom_scm_io_writel(addr, val);
+			ret = qcom_scm_io_writel(addr, val);
+		}
 		if (ret)
 			dev_err(pctrl->dev,
 				"Failed routing %lu interrupt to Apps proc",
-- 
2.56.0.385.gac671c819a-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error
  2026-11-03 21:29 ` [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error Lee Jones
@ 2026-11-03 21:40   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-11-03 21:40 UTC (permalink / raw)
  To: Lee Jones, linux-gpio

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] pinctrl: mediatek: NULL deref in mtk_eint_do_suspend() on EINT init error
--

commit 8d040caade190db874ef6d84f338e06e2679ef73
Author: Lee Jones <lee@kernel.org>

pinctrl: mediatek: Clean up partially initialised hw->eint on error

This commit updates mtk_build_eint() to jump to err_free_base when
of_property_count_strings() fails or hw->eint->nbase is non-positive,
freeing hw->eint and resetting it to NULL.

> diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> index faa6dbf0f6356..aa15c9e047d89 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c
> @@ -382,12 +382,16 @@ int mtk_build_eint(struct mtk_pinctrl *hw, struct platform_device *pdev)
>  		return -ENOMEM;
>  
>  	count_reg_names = of_property_count_strings(np, "reg-names");
> -	if (count_reg_names < 0)
> -		return -EINVAL;
> +	if (count_reg_names < 0) {
> +		ret = -EINVAL;
> +		goto err_free_base;
> +	}
>  
>  	hw->eint->nbase = count_reg_names - (int)hw->soc->nbase_names;
> -	if (hw->eint->nbase <= 0)
> -		return -EINVAL;
> +	if (hw->eint->nbase <= 0) {
> +		ret = -EINVAL;
> +		goto err_free_base;
> +	}

[Severity: High]
The commit message notes that leaving hw->eint non-NULL on these error
paths causes subsequent suspend/resume callbacks to dereference a NULL
pointer inside mtk_eint_do_suspend(), and that resetting hw->eint to NULL
avoids this.

However, when mtk_build_eint() fails during mtk_paris_pinctrl_probe(), the
driver logs a warning and finishes probing with pctl->eint set to NULL. On
system suspend or resume, mtk_paris_pinctrl_suspend() and
mtk_paris_pinctrl_resume() pass pctl->eint directly to
mtk_eint_do_suspend() and mtk_eint_do_resume():

drivers/pinctrl/mediatek/pinctrl-paris.c:
static int mtk_paris_pinctrl_suspend(struct device *device)
{
	struct mtk_pinctrl *pctl = dev_get_drvdata(device);

	return mtk_eint_do_suspend(pctl->eint);
}

Neither those callers nor mtk_eint_do_suspend() and mtk_eint_do_resume()
check whether eint is NULL before dereferencing it:

drivers/pinctrl/mediatek/mtk-eint.c:
int mtk_eint_do_suspend(struct mtk_eint *eint)
{
	mtk_eint_chip_write_mask(eint, eint->wake_mask);

	return 0;
}

Previously on these two error paths, hw->eint remained non-NULL with
hw->eint->nbase <= 0, so the loop in mtk_eint_chip_write_mask() over
inst < eint->nbase did zero iterations. With hw->eint reset to NULL here
(as well as on the existing error paths in mtk_build_eint()), won't
suspending or resuming trigger a NULL pointer dereference in
mtk_eint_do_suspend() and mtk_eint_do_resume() unless a NULL check is also
added?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103213002.1673560-1-lee@kernel.org?part=8

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs
  2026-11-03 21:29 ` [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs Lee Jones
@ 2026-11-03 21:42   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-11-03 21:42 UTC (permalink / raw)
  To: Lee Jones, linux-gpio, linux-sunxi

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] pinctrl: sunxi: off-by-one IRQ bank mapping in prepare_function_table()
--

commit c76ce1661381ff598e234c433e51d5307fae79a4
Author: Lee Jones <lee@kernel.org>

pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs

This commit initializes irq_bank and last_bank to -1 in
prepare_function_table() and only updates last_bank on IRQ-capable banks so
that irq_bank starts at 0 even when bank 0 (PA) has no pins or interrupts.

> diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
> index 8bcd566593ae8..79ca1a7c48374 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi-dt.c
> @@ -208,8 +208,8 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
>  	 * Assign the function's memory and fill in GPIOs, IRQ and a sentinel.
>  	 * The extra functions will be filled in later.
>  	 */
> -	irq_bank = 0;
> -	last_bank = 0;
> +	irq_bank = -1;
> +	last_bank = -1;
>  	for (i = 0; i < npins; i++) {
>  		struct sunxi_desc_pin *pin = &pins[i];
>  		int bank = (pin->pin.number - pin_base) / PINS_PER_BANK;
> @@ -222,17 +222,16 @@ static int prepare_function_table(struct device *dev, struct device_node *pnode,
>  		func[1].muxval = 1;
>  
>  		if (irq_mux) {
> -			if (bank > last_bank)
> +			if (bank > last_bank) {
>  				irq_bank++;
> +				last_bank = bank;
> +			}
>  			func[lastfunc].muxval = irq_mux;
>  			func[lastfunc].irqbank = irq_bank;
>  			func[lastfunc].irqnum = pin->pin.number % PINS_PER_BANK;
>  			func[lastfunc].name = "irq";
>  		}
>  
> -		if (bank > last_bank)
> -			last_bank = bank;

[Severity: High]
Won't assigning irqbank starting at 0 for Port B shift the hardware IRQ
register offsets and GIC interrupt mappings off by one bank on Allwinner A523
and A733?

On Allwinner A523 and A733, Port A (bank 0) has 0 pins, while Ports B through
K (banks 1 through 10) implement pins and interrupts. With this change,
sunxi_pinctrl_dt_table_init() -> prepare_function_table() assigns
func[lastfunc].irqbank = 0..9 to Ports B..K instead of 1..10.

However, as described in commits 11f25ac56372 ("dt-bindings: pinctrl:
sun55i-a523: increase IRQ banks number") and 6b81aa0c8a4f ("arm64: dts:
allwinner: a523: Add missing GPIO interrupt"), the hardware IRQ register
layout and Device Tree interrupt numbering on A523 and A733 start at index 0
for the unimplemented Port A (RAZ/WI), with Ports B..K occupying hardware and
DT indices 1..10.

On Allwinner A523, drivers/pinctrl/sunxi/pinctrl-sun55i-a523.c defines an
identity bank map starting at 0:

    static const unsigned int a523_irq_bank_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

When Ports B..K are given irqbank 0..9 without updating a523_pinctrl_data,
sunxi_irq_base_reg() maps Port B (irqbank 0) via a523_irq_bank_map[0] = 0 to
Port A's unimplemented IRQ registers at offset 0x200 instead of Port B's at
0x220, Port C (irqbank 1) to Port B's registers at 0x220, and so on through
Port K (irqbank 9) accessing Port J's registers at 0x320, leaving Port K's
registers at 0x340 unused.

Furthermore, arch/arm64/boot/dts/allwinner/sun55i-a523.dtsi and
Documentation/devicetree/bindings/pinctrl/allwinner,sun55i-a523-pinctrl.yaml
specify 11 GIC interrupts starting with Port A (GIC_SPI 67) at index 0, Port B
(GIC_SPI 69) at index 1, through Port K (GIC_SPI 140) at index 10:

    interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
                 ...
                 <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
                 <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;

Because sunxi_pinctrl_init_with_flags() populates
pctl->irq[i] = platform_get_irq(pdev, i) for i = 0 .. desc->irq_banks - 1,
assigning irqbank 0..9 to Ports B..K pairs Port B with Port A's GIC_SPI 67
(pctl->irq[0]), Port C with Port B's GIC_SPI 69 (pctl->irq[1]), through Port K
with Port J's GIC_SPI 85 (pctl->irq[9]), while index 10 (GIC_SPI 140 for
Port K) is never requested.

Similarly, on Allwinner A733, drivers/pinctrl/sunxi/pinctrl-sun60i-a733.c
uses SUNXI_PINCTRL_NCAT3_REG_LAYOUT with no irq_bank_map:

    static struct sunxi_pinctrl_desc a733_pinctrl_data = {
            .irq_banks = 10,
            .irq_read_needs_mux = true,
            .io_bias_cfg_variant = BIAS_VOLTAGE_PIO_POW_MODE_SEL,
    };

In drivers/pinctrl/sunxi/pinctrl-sunxi.h, sunxi_irq_base_reg() computes the
register offset directly from bank without calling sunxi_irq_hw_bank_num():

    static inline u32 sunxi_irq_base_reg(const struct sunxi_pinctrl *pctl, u16 bank)
    {
            if (pctl->flags & SUNXI_PINCTRL_NCAT3_REG_LAYOUT)
                    return pctl->bank_offset + bank * pctl->bank_mem_size +
                           A733_IRQ_REGS_OFFSET;

            return IRQ_REGS_OFFSET +
                   sunxi_irq_hw_bank_num(pctl->desc, bank) * IRQ_MEM_SIZE;
    }

Because pctl->bank_offset (0x80) is Port A's register base (IRQ-A at 0x0c0 for
bank 0) and Port B's IRQ registers are at bank 1 (0x140), assigning irqbank
0..9 to Ports B..K shifts all A733 IRQ register accesses down by one bank to
0x0c0..0x540 (Ports A..J) instead of 0x140..0x5c0 (Ports B..K).

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261103213002.1673560-1-lee@kernel.org?part=1

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array
  2026-11-03 21:29 ` [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array Lee Jones
@ 2026-11-03 22:00   ` H. Nikolaus Schaller
  0 siblings, 0 replies; 14+ messages in thread
From: H. Nikolaus Schaller @ 2026-11-03 22:00 UTC (permalink / raw)
  To: Lee Jones
  Cc: Paul Cercueil, Linus Walleij, Paul Boddie, zhouyanjie,
	Andreas Kemnade, linux-mips, linux-gpio, linux-kernel, stable

Hi,

> Am 03.11.2026 um 22:29 schrieb Lee Jones <lee@kernel.org>:
> 
> ingenic_pinmux_set_mux() treats grp->data as a u8 array of per-pin mux
> modes (u8 *pin_modes = grp->data), and every other *_funcs array in the
> Ingenic pinctrl driver is declared as u8[].  Because x1600_sfc_funcs[]
> was declared as int[], indexing pin_modes[0..6] reads the first seven
> bytes of the int array (0, 0, 0, 0, 0, 0, 0) instead of reading mode 2
> for the seventh pin.
> 
> Change the element type of x1600_sfc_funcs[] from int to u8.
> 
> Fixes: 4da56f9c6f14 ("pinctrl: ingenic: add x1600 support")
> Closes: https://sashiko.dev/#/bug/linux-5dccd0ae-9450-440a-87d0-44cc86d1af45
> Cc: stable@vger.kernel.org
> Signed-off-by: Lee Jones <lee@kernel.org>
> ---
> drivers/pinctrl/pinctrl-ingenic.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-ingenic.c b/drivers/pinctrl/pinctrl-ingenic.c
> index 1aa6a6dc1209..5c06208b8854 100644
> --- a/drivers/pinctrl/pinctrl-ingenic.c
> +++ b/drivers/pinctrl/pinctrl-ingenic.c
> @@ -2456,7 +2456,7 @@ static int x1600_mac_pins[] = {
> 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
> };
> 
> -static int x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };
> +static u8 x1600_sfc_funcs[] = { 0, 0, 0, 0, 0, 0, 2, };

Yes, that appears to be the correct fix. All other INGENIC_PIN_GROUP_FUNCS()
use u8 arrays.

I can not test as our x1600 board does not use the SFC interface.

> 
> static const struct group_desc x1600_groups[] = {
> INGENIC_PIN_GROUP("uart0-data", x1600_uart0_data, 0),
> -- 
> 2.56.0.385.gac671c819a-goog

Reviewed-by: H. Nikolaus Schaller <hns@goldelico.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-11-03 22:01 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 21:29 [PATCH 00/10] pinctrl: Fix out-of-bounds accesses, divide-by-zero, and error handling Lee Jones
2026-11-03 21:29 ` [PATCH 01/10] pinctrl: sunxi: Fix out-of-bounds irq_bank index when first bank has no IRQs Lee Jones
2026-11-03 21:42   ` sashiko-bot
2026-11-03 21:29 ` [PATCH 02/10] pinctrl: tegra186: Fix out-of-bounds register bank index for AON drive groups Lee Jones
2026-11-03 21:29 ` [PATCH 03/10] pinctrl: ingenic: Fix element type of x1600_sfc_funcs array Lee Jones
2026-11-03 22:00   ` H. Nikolaus Schaller
2026-11-03 21:29 ` [PATCH 04/10] pinctrl: mediatek: mt7981: Add missing entries to mt7981_ant_sel_funcs Lee Jones
2026-11-03 21:29 ` [PATCH 05/10] pinctrl: realtek: Prevent out-of-bounds access in rtd_pinctrl_find_config() Lee Jones
2026-11-03 21:29 ` [PATCH 06/10] pinctrl: realtek: Fix bit shift when configuring RTD_HIGH_VIL Lee Jones
2026-11-03 21:29 ` [PATCH 07/10] pinctrl: realtek: Initialise omitted offset fields to NA in config macros Lee Jones
2026-11-03 21:29 ` [PATCH 08/10] pinctrl: mediatek: Clean up partially initialised hw->eint on error Lee Jones
2026-11-03 21:40   ` sashiko-bot
2026-11-03 21:29 ` [PATCH 09/10] pinctrl: mediatek: Prevent divide-by-zero for pins with fixed drive strength Lee Jones
2026-11-03 21:29 ` [PATCH 10/10] pinctrl: qcom: Check qcom_scm_io_readl() return value in msm_gpio_irq_set_type() Lee Jones

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox