All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i2c: smbus: fix NULL function pointer dereference
@ 2024-04-10 15:12 Baruch Siach
  2024-04-26  6:43 ` Wolfram Sang
  0 siblings, 1 reply; 12+ messages in thread
From: Baruch Siach @ 2024-04-10 15:12 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linux-i2c, Baruch Siach

Running i2cdetect on i2c slave device (i2c-designware) gives this splat:

[   53.306730] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[   53.318340] Mem abort info:
[   53.323864]   ESR = 0x0000000086000004
[   53.330374]   EC = 0x21: IABT (current EL), IL = 32 bits
[   53.338446]   SET = 0, FnV = 0
[   53.344263]   EA = 0, S1PTW = 0
[   53.350166]   FSC = 0x04: level 0 translation fault
[   53.357806] user pgtable: 4k pages, 48-bit VAs, pgdp=00000008c7d8e000
[   53.367008] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
[   53.376559] Internal error: Oops: 0000000086000004 [#1] PREEMPT SMP
[   53.382892] Modules linked in:
[   53.385936] CPU: 6 PID: 420 Comm: i2cdetect Not tainted 6.9.0-rc3-yocto-standard+ #1295
[   53.393926] Hardware name: xxx (DT)
[   53.398531] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   53.405480] pc : 0x0
[   53.407656] lr : __i2c_transfer+0x1f4/0x830
[   53.411834] sp : ffff800082c13b00
[   53.415136] x29: ffff800082c13b00 x28: 0000000000000001 x27: 0000000000000001
[   53.422259] x26: ffff8000813aa340 x25: ffff0000c69553c0 x24: 00000000ffff0eeb
[   53.429383] x23: ffff8000813a6000 x22: ffff800082c13bc0 x21: 0000000000000000
[   53.436506] x20: 0000000000000001 x19: ffff000040b82140 x18: 0000000000000000
[   53.443630] x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffffff59bd58
[   53.450753] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[   53.457876] x11: 0000000000000000 x10: 0000000000000000 x9 : ffff8000807e4470
[   53.464999] x8 : ffff800082c13c05 x7 : 0000000000000001 x6 : ffff800082c13d56
[   53.472122] x5 : 0000000000000001 x4 : 0000000000000000 x3 : 0000000000000000
[   53.479245] x2 : 0000000000000001 x1 : ffff800082c13bc0 x0 : ffff000040b82140
[   53.486368] Call trace:
[   53.488803]  0x0
[   53.490629]  i2c_smbus_xfer_emulated+0x148/0x6d0
[   53.495236]  __i2c_smbus_xfer+0x130/0x4d0
[   53.499235]  i2c_smbus_xfer+0xc0/0x128
[   53.502973]  i2cdev_ioctl_smbus+0x110/0x2b0
[   53.507145]  i2cdev_ioctl+0x9c/0x348
[   53.510710]  __arm64_sys_ioctl+0xb4/0xe0
[   53.514624]  invoke_syscall+0x4c/0x118
[   53.518365]  el0_svc_common.constprop.0+0xc4/0xf0
[   53.523058]  do_el0_svc+0x24/0x38
[   53.526362]  el0_svc+0x28/0xb8
[   53.529407]  el0t_64_sync_handler+0x134/0x150
[   53.533751]  el0t_64_sync+0x14c/0x150
[   53.537405] Code: ???????? ???????? ???????? ???????? (????????)
[   53.543485] ---[ end trace 0000000000000000 ]---

Callers of __i2c_transfer() must verify that master_xfer is not NULL.
Check that before i2c_smbus_xfer_emulated() call.

Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
 drivers/i2c/i2c-core-smbus.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index e3b96fc53b5c..d252716c9f74 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -604,8 +604,11 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 		 */
 	}
 
-	res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
-				      command, protocol, data);
+	if (adapter->algo->master_xfer)
+		res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
+				command, protocol, data);
+	else
+		res = -EOPNOTSUPP;
 
 trace:
 	/* If enabled, the reply tracepoint is conditional on read_write. */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread
* [PATCH] i2c: smbus: fix NULL function pointer dereference
@ 2024-04-26  6:44 Wolfram Sang
  2024-04-26  7:28 ` Sergei Shtylyov
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Wolfram Sang @ 2024-04-26  6:44 UTC (permalink / raw)
  To: linux-renesas-soc; +Cc: Wolfram Sang, Baruch Siach, linux-i2c, linux-kernel

Brauch reported an OOPS when using the designware controller as target
only. Target-only modes break the assumption of one transfer function
always being available. Fix this by always checking the pointer in
__i2c_transfer.

Reported-by: Baruch Siach <baruch@tkos.co.il>
Closes: https://lore.kernel.org/r/4269631780e5ba789cf1ae391eec1b959def7d99.1712761976.git.baruch@tkos.co.il
Fixes: 4b1acc43331d ("i2c: core changes for slave support")
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
 drivers/i2c/i2c-core-base.c  | 12 ++++++------
 drivers/i2c/i2c-core-smbus.c |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index ff5c486a1dbb..db0d1ac82910 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -2200,13 +2200,18 @@ static int i2c_check_for_quirks(struct i2c_adapter *adap, struct i2c_msg *msgs,
  * Returns negative errno, else the number of messages executed.
  *
  * Adapter lock must be held when calling this function. No debug logging
- * takes place. adap->algo->master_xfer existence isn't checked.
+ * takes place.
  */
 int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
 	unsigned long orig_jiffies;
 	int ret, try;
 
+	if (!adap->algo->master_xfer) {
+		dev_dbg(&adap->dev, "I2C level transfers not supported\n");
+		return -EOPNOTSUPP;
+	}
+
 	if (WARN_ON(!msgs || num < 1))
 		return -EINVAL;
 
@@ -2273,11 +2278,6 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
 	int ret;
 
-	if (!adap->algo->master_xfer) {
-		dev_dbg(&adap->dev, "I2C level transfers not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	/* REVISIT the fault reporting model here is weak:
 	 *
 	 *  - When we get an error after receiving N bytes from a slave,
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c
index e3b96fc53b5c..a942c5306a4e 100644
--- a/drivers/i2c/i2c-core-smbus.c
+++ b/drivers/i2c/i2c-core-smbus.c
@@ -596,7 +596,7 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 				break;
 		}
 
-		if (res != -EOPNOTSUPP || !adapter->algo->master_xfer)
+		if (res != -EOPNOTSUPP)
 			goto trace;
 		/*
 		 * Fall back to i2c_smbus_xfer_emulated if the adapter doesn't
-- 
2.39.2


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

end of thread, other threads:[~2024-06-05  9:21 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-10 15:12 [PATCH] i2c: smbus: fix NULL function pointer dereference Baruch Siach
2024-04-26  6:43 ` Wolfram Sang
2024-04-26  6:44 Wolfram Sang
2024-04-26  7:28 ` Sergei Shtylyov
2024-04-26  8:39   ` Wolfram Sang
2024-04-26  8:32 ` Baruch Siach
2024-04-26  9:52 ` Wolfram Sang
2024-05-30 13:24 ` Jean Delvare
2024-06-04  8:50   ` Wolfram Sang
2024-06-04 15:11     ` Jean Delvare
2024-06-04 20:08       ` Wolfram Sang
2024-06-05  9:20         ` Jean Delvare

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.