All of lore.kernel.org
 help / color / mirror / Atom feed
* [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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-26  6:44 [PATCH] i2c: smbus: fix NULL function pointer dereference Wolfram Sang
@ 2024-04-26  7:28 ` Sergei Shtylyov
  2024-04-26  8:39   ` Wolfram Sang
  2024-04-26  8:32 ` Baruch Siach
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Sergei Shtylyov @ 2024-04-26  7:28 UTC (permalink / raw)
  To: Wolfram Sang, linux-renesas-soc; +Cc: Baruch Siach, linux-i2c, linux-kernel

On 4/26/24 9:44 AM, Wolfram Sang wrote:

> Brauch reported an OOPS when using the designware controller as target

   He's Baruch... :-)

> 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>

[...]

MBR, Sergey

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-26  6:44 [PATCH] i2c: smbus: fix NULL function pointer dereference Wolfram Sang
  2024-04-26  7:28 ` Sergei Shtylyov
@ 2024-04-26  8:32 ` Baruch Siach
  2024-04-26  9:52 ` Wolfram Sang
  2024-05-30 13:24 ` Jean Delvare
  3 siblings, 0 replies; 12+ messages in thread
From: Baruch Siach @ 2024-04-26  8:32 UTC (permalink / raw)
  To: Wolfram Sang; +Cc: linux-renesas-soc, linux-i2c, linux-kernel

Hi Wolfram,

On Fri, Apr 26 2024, Wolfram Sang wrote:
> 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>

Tested-by: Baruch Siach <baruch@tkos.co.il>

Thanks,
baruch

> ---
>  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


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch@tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-26  7:28 ` Sergei Shtylyov
@ 2024-04-26  8:39   ` Wolfram Sang
  0 siblings, 0 replies; 12+ messages in thread
From: Wolfram Sang @ 2024-04-26  8:39 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: linux-renesas-soc, Baruch Siach, linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 251 bytes --]

On Fri, Apr 26, 2024 at 10:28:40AM +0300, Sergei Shtylyov wrote:
> On 4/26/24 9:44 AM, Wolfram Sang wrote:
> 
> > Brauch reported an OOPS when using the designware controller as target
> 
>    He's Baruch... :-)

Oh, I am very sorry Baruch!


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-26  6:44 [PATCH] i2c: smbus: fix NULL function pointer dereference Wolfram Sang
  2024-04-26  7:28 ` Sergei Shtylyov
  2024-04-26  8:32 ` Baruch Siach
@ 2024-04-26  9:52 ` Wolfram Sang
  2024-05-30 13:24 ` Jean Delvare
  3 siblings, 0 replies; 12+ messages in thread
From: Wolfram Sang @ 2024-04-26  9:52 UTC (permalink / raw)
  To: linux-renesas-soc; +Cc: Baruch Siach, linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 653 bytes --]

On Fri, Apr 26, 2024 at 08:44:08AM +0200, Wolfram Sang wrote:
> 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>

Fixed the name typo and applied to for-current, thanks!


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-26  6:44 [PATCH] i2c: smbus: fix NULL function pointer dereference Wolfram Sang
                   ` (2 preceding siblings ...)
  2024-04-26  9:52 ` Wolfram Sang
@ 2024-05-30 13:24 ` Jean Delvare
  2024-06-04  8:50   ` Wolfram Sang
  3 siblings, 1 reply; 12+ messages in thread
From: Jean Delvare @ 2024-05-30 13:24 UTC (permalink / raw)
  To: Wolfram Sang, linux-renesas-soc
  Cc: Baruch Siach, linux-i2c, linux-kernel, Peter Rosin

Hi Wolfram, Baruch, Peter,

On Fri, 2024-04-26 at 08:44 +0200, Wolfram Sang wrote:
> 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.

I was asked to backport this fix to our oldest kernel branches, so I
looked into it and I have comments and a question.

> 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")

I have a hard time establishing a formal link between the reported bug
and the commit listed above. I do understand that it wouldn't make
sense to register an i2c_adapter with neither .master_xfer nor
.smbus_xfer set before .reg_slave was added to struct i2c_algorithm,
but there were no checks in i2c-core preventing it from happening.

It was also possible for any (broken) device driver to call
__i2c_transfer() without first checking if plain I2C transfers were
actually supported by the i2c_adapter. I would argue that such an issue
should have been fixed at the device driver level by checking for the
I2C_FUNC_I2C functionality flag before calling __i2c_transfer(). That's
a theoretical issue though as I'm not aware of any device driver having
this issue.

The call stack in Baruch's report shows that the real issue is with
i2c_smbus_xfer_emulated() being called with the i2c bus lock already
held, and thus having to call __i2c_transfer() instead of
i2c_transfer(). This code path did not exist before commit 63453b59e411
("i2c: smbus: add unlocked __i2c_smbus_xfer variant"), which was added
in kernel v4.19. Therefore I claim that CVE-2024-35984 only affects
kernel v4.19 and newer. Do we agree on that?

> 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;
> +       }
> +

Not related specifically to this commit, as it is only moving a check
which already existed before, but this looks inefficient to me.

We end up performing the check with every I2C-level transfer, while the
availability of such support can almost always be checked once and for
all in the I2C device driver (i2c-dev and i2c_smbus_xfer_emulated being
the exceptions).

I see two ways for us to reach this check:
* __i2c_transfer() or i2c_transfer() gets called directly by a device
driver. This driver should have checked for the I2C_FUNC_I2C
functionality flag before calling either function. If they did not,
it's a driver bug, which should be fixed in the driver in question.
Note that i2c-dev currently lacks this check, I think it should be
added.
* __i2c_transfer() gets called by i2c_smbus_xfer_emulated(). We should
add a check for I2C_FUNC_I2C in __i2c_smbus_xfer() before calling this
function. This is more or less what Baruch proposed initially, and I
think it would have been a more efficient fix.

And if you are concerned about functionality flags not being set
properly (specifically I2C_FUNC_I2C being set while .master_xfer isn't
set [1]) then we should add a consistency check at i2c_adapter
registration time, so again it's done once and for all and we don't
have to check again and again at transfer time.

Or is this optimization not worth it?

[1] BTW, looking at the only two in-tree slave-only I2C adapter
drivers, i2c-at91-slave and i2c-designware-slave, both are setting
functionality flags other than I2C_FUNC_SLAVE. Unless I don't
understand how the slave functionality works, this is a bug. I'll
prepare and post patches later today.


-- 
Jean Delvare
SUSE L3 Support

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-05-30 13:24 ` Jean Delvare
@ 2024-06-04  8:50   ` Wolfram Sang
  2024-06-04 15:11     ` Jean Delvare
  0 siblings, 1 reply; 12+ messages in thread
From: Wolfram Sang @ 2024-06-04  8:50 UTC (permalink / raw)
  To: Jean Delvare
  Cc: linux-renesas-soc, Baruch Siach, linux-i2c, linux-kernel, Peter Rosin

[-- Attachment #1: Type: text/plain, Size: 4510 bytes --]

Hi Jean,

> I have a hard time establishing a formal link between the reported bug
> and the commit listed above. I do understand that it wouldn't make
> sense to register an i2c_adapter with neither .master_xfer nor
> .smbus_xfer set before .reg_slave was added to struct i2c_algorithm,
> but there were no checks in i2c-core preventing it from happening.

Well, yes, correct.

> It was also possible for any (broken) device driver to call
> __i2c_transfer() without first checking if plain I2C transfers were
> actually supported by the i2c_adapter. I would argue that such an issue
> should have been fixed at the device driver level by checking for the
> I2C_FUNC_I2C functionality flag before calling __i2c_transfer(). That's
> a theoretical issue though as I'm not aware of any device driver having
> this issue.

In theory, checking against I2C_FUNC_I2C should happen. In practice,
most I2C drivers do not do this. Being picky here could results in bad
user experience because of OOPS. If we really want to enforce checking
I2C_FUNC_I2C, then we should have this safety net while we convert all
users. No, actually, I think we always should have some safety nets.

> The call stack in Baruch's report shows that the real issue is with
> i2c_smbus_xfer_emulated() being called with the i2c bus lock already
> held, and thus having to call __i2c_transfer() instead of
> i2c_transfer(). This code path did not exist before commit 63453b59e411
> ("i2c: smbus: add unlocked __i2c_smbus_xfer variant"), which was added
> in kernel v4.19. Therefore I claim that CVE-2024-35984 only affects
> kernel v4.19 and newer. Do we agree on that?

(There is a CVE for it??) For Baruch's case, this is true. But there are
__i2c_transfer users all over the tree, they are all potentially
vulnerable, or?

> > +       if (!adap->algo->master_xfer) {
> > +               dev_dbg(&adap->dev, "I2C level transfers not supported\n");
> > +               return -EOPNOTSUPP;
> > +       }
> > +
> 
> Not related specifically to this commit, as it is only moving a check
> which already existed before, but this looks inefficient to me.
> 
> We end up performing the check with every I2C-level transfer, while the
> availability of such support can almost always be checked once and for
> all in the I2C device driver (i2c-dev and i2c_smbus_xfer_emulated being
> the exceptions).
> 
> I see two ways for us to reach this check:
> * __i2c_transfer() or i2c_transfer() gets called directly by a device
> driver. This driver should have checked for the I2C_FUNC_I2C
> functionality flag before calling either function. If they did not,
> it's a driver bug, which should be fixed in the driver in question.

I see the performance penalty, yet I prefer handling the buggy driver
gracefully because kicking off I2C transfers is not a hot path. Maybe we
could turn the dev_dbg into something louder to make people aware that
there is a bug?

> Note that i2c-dev currently lacks this check, I think it should be
> added.

True, it should be a role-model of a good citizen :)

> * __i2c_transfer() gets called by i2c_smbus_xfer_emulated(). We should
> add a check for I2C_FUNC_I2C in __i2c_smbus_xfer() before calling this
> function. This is more or less what Baruch proposed initially, and I
> think it would have been a more efficient fix.

As I said above, more efficient but not thorough. One driver not
checking I2C_FUNC_I2C and boom...

> And if you are concerned about functionality flags not being set
> properly (specifically I2C_FUNC_I2C being set while .master_xfer isn't
> set [1]) then we should add a consistency check at i2c_adapter
> registration time, so again it's done once and for all and we don't
> have to check again and again at transfer time.

I think this check is worth to have. It is not complete because drivers
may still not check the flag, but it is one step to be more robust.

> Or is this optimization not worth it?

I think so. It is one pointer check against a kernel oopsing somewhere
somewhen.

> [1] BTW, looking at the only two in-tree slave-only I2C adapter
> drivers, i2c-at91-slave and i2c-designware-slave, both are setting
> functionality flags other than I2C_FUNC_SLAVE. Unless I don't
> understand how the slave functionality works, this is a bug. I'll
> prepare and post patches later today.

Thanks for doing that!

Happy hacking,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-06-04  8:50   ` Wolfram Sang
@ 2024-06-04 15:11     ` Jean Delvare
  2024-06-04 20:08       ` Wolfram Sang
  0 siblings, 1 reply; 12+ messages in thread
From: Jean Delvare @ 2024-06-04 15:11 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-renesas-soc, Baruch Siach, linux-i2c, linux-kernel, Peter Rosin

Hi Wolfram,

Thanks for your answer.

On Tue, 4 Jun 2024 10:50:30 +0200, Wolfram Sang wrote:
> Hi Jean,
> 
> > I have a hard time establishing a formal link between the reported bug
> > and the commit listed above. I do understand that it wouldn't make
> > sense to register an i2c_adapter with neither .master_xfer nor
> > .smbus_xfer set before .reg_slave was added to struct i2c_algorithm,
> > but there were no checks in i2c-core preventing it from happening.  
> 
> Well, yes, correct.
> 
> > It was also possible for any (broken) device driver to call
> > __i2c_transfer() without first checking if plain I2C transfers were
> > actually supported by the i2c_adapter. I would argue that such an issue
> > should have been fixed at the device driver level by checking for the
> > I2C_FUNC_I2C functionality flag before calling __i2c_transfer(). That's
> > a theoretical issue though as I'm not aware of any device driver having
> > this issue.  
> 
> In theory, checking against I2C_FUNC_I2C should happen. In practice,
> most I2C drivers do not do this. Being picky here could results in bad
> user experience because of OOPS. If we really want to enforce checking
> I2C_FUNC_I2C, then we should have this safety net while we convert all
> users. No, actually, I think we always should have some safety nets.

Point taken, makes sense.

Note that we still want I2C_FUNC_I2C to be set properly, because it
allows device drivers to optimize transfers (the at24 driver is a prime
example of that) or even just to bind to the I2C bus (for device
drivers which properly check for it).

> > The call stack in Baruch's report shows that the real issue is with
> > i2c_smbus_xfer_emulated() being called with the i2c bus lock already
> > held, and thus having to call __i2c_transfer() instead of
> > i2c_transfer(). This code path did not exist before commit 63453b59e411
> > ("i2c: smbus: add unlocked __i2c_smbus_xfer variant"), which was added
> > in kernel v4.19. Therefore I claim that CVE-2024-35984 only affects
> > kernel v4.19 and newer. Do we agree on that?  
> 
> (There is a CVE for it??) For Baruch's case, this is true. But there are
> __i2c_transfer users all over the tree, they are all potentially
> vulnerable, or?

Yes there are many, but I think we shall differentiate between 2 cases:
* Missing check in a specific kernel device driver. These are unlikely
  to be a problem in practice because (1) these devices are typically
  instantiated explicitly, and such explicit code or device tree
  description would not exist in the first place if said device was not
  compatible with said I2C bus, and (2) if such an incompatibility was
  really present then it would have been spotted and fixed very
  quickly. Arbitrary binding through sysfs attributes is still possible
  but would definitely require root access and evil intentions (at
  which point we are screwed no matter what). I'm honestly not worried
  about this scenario.
* The issue being triggered from user-space through i2c-dev, which is
  what Baruch reported. The user doing that can target any arbitrary
  I2C bus and thus cause the oops by accident or even on purpose. For
  me this is what CVE-2024-35984 is about. What limits the attack
  surface here is that slave-only I2C buses are rare and you typically
  need to be root to use i2c-dev. But this is still a serious issue.

Also note that the first case could happen ever since __i2c_transfer()
was introduced (kernel v3.6, commit b37d2a3a75cb) and is not limited to
slave-only adapters, as any SMBus-only i2c_adapter would also be
vulnerable.

So the "Fixes:" tag in commit 91811a31b68d is incorrect for both
scenarios.

> (...)
> I see the performance penalty, yet I prefer handling the buggy driver
> gracefully because kicking off I2C transfers is not a hot path. Maybe we
> could turn the dev_dbg into something louder to make people aware that
> there is a bug?

My previous message initially had a suggestion in that direction ;-)
but I first wanted your opinion on the check itself. dev_dbg() is
definitely not appropriate for a condition which should never happen
and implies there's a bug somewhere else. A WARN_ON_ONCE would probably
be better, so that the bug gets spotted and fixed quickly.

-- 
Jean Delvare
SUSE L3 Support

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-06-04 15:11     ` Jean Delvare
@ 2024-06-04 20:08       ` Wolfram Sang
  2024-06-05  9:20         ` Jean Delvare
  0 siblings, 1 reply; 12+ messages in thread
From: Wolfram Sang @ 2024-06-04 20:08 UTC (permalink / raw)
  To: Jean Delvare
  Cc: linux-renesas-soc, Baruch Siach, linux-i2c, linux-kernel, Peter Rosin

[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]

Hi Jean,

> Note that we still want I2C_FUNC_I2C to be set properly, because it
> allows device drivers to optimize transfers (the at24 driver is a prime
> example of that) or even just to bind to the I2C bus (for device
> drivers which properly check for it).

I agree. We definitely want I2C_FUNC_I2C to be set and make use of it as
much as possible. We should just not completely rely on it.

> > (There is a CVE for it??) For Baruch's case, this is true. But there are
> > __i2c_transfer users all over the tree, they are all potentially
> > vulnerable, or?
> 
> Yes there are many, but I think we shall differentiate between 2 cases:
> * Missing check in a specific kernel device driver. These are unlikely
>   to be a problem in practice because (1) these devices are typically
>   instantiated explicitly, and such explicit code or device tree
>   description would not exist in the first place if said device was not
>   compatible with said I2C bus, and (2) if such an incompatibility was
>   really present then it would have been spotted and fixed very
>   quickly. Arbitrary binding through sysfs attributes is still possible
>   but would definitely require root access and evil intentions (at
>   which point we are screwed no matter what). I'm honestly not worried
>   about this scenario.

OK, can be argued.

> * The issue being triggered from user-space through i2c-dev, which is
>   what Baruch reported. The user doing that can target any arbitrary
>   I2C bus and thus cause the oops by accident or even on purpose. For
>   me this is what CVE-2024-35984 is about. What limits the attack
>   surface here is that slave-only I2C buses are rare and you typically
>   need to be root to use i2c-dev. But this is still a serious issue.

Agreed.

> Also note that the first case could happen ever since __i2c_transfer()
> was introduced (kernel v3.6, commit b37d2a3a75cb) and is not limited to
> slave-only adapters, as any SMBus-only i2c_adapter would also be
> vulnerable.

Which makes handling this gracefully even more important.

> So the "Fixes:" tag in commit 91811a31b68d is incorrect for both
> scenarios.

Ack. Sorry! :)

> > gracefully because kicking off I2C transfers is not a hot path. Maybe we
> > could turn the dev_dbg into something louder to make people aware that
> > there is a bug?
> 
> My previous message initially had a suggestion in that direction ;-)
> but I first wanted your opinion on the check itself. dev_dbg() is
> definitely not appropriate for a condition which should never happen
> and implies there's a bug somewhere else. A WARN_ON_ONCE would probably
> be better, so that the bug gets spotted and fixed quickly.

So, are you okay with keeping the check where it is now and turning the
dev_dbg into WARN_ON_ONCE? I am.

All the best,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-06-04 20:08       ` Wolfram Sang
@ 2024-06-05  9:20         ` Jean Delvare
  0 siblings, 0 replies; 12+ messages in thread
From: Jean Delvare @ 2024-06-05  9:20 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-renesas-soc, Baruch Siach, linux-i2c, linux-kernel, Peter Rosin

Hi Wolfram,

On Tue, 4 Jun 2024 22:08:41 +0200, Wolfram Sang wrote:
> > > gracefully because kicking off I2C transfers is not a hot path. Maybe we
> > > could turn the dev_dbg into something louder to make people aware that
> > > there is a bug?  
> > 
> > My previous message initially had a suggestion in that direction ;-)
> > but I first wanted your opinion on the check itself. dev_dbg() is
> > definitely not appropriate for a condition which should never happen
> > and implies there's a bug somewhere else. A WARN_ON_ONCE would probably
> > be better, so that the bug gets spotted and fixed quickly.  
> 
> So, are you okay with keeping the check where it is now and turning the
> dev_dbg into WARN_ON_ONCE? I am.

Yes I am.

Thanks,
-- 
Jean Delvare
SUSE L3 Support

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

* Re: [PATCH] i2c: smbus: fix NULL function pointer dereference
  2024-04-10 15:12 Baruch Siach
@ 2024-04-26  6:43 ` Wolfram Sang
  0 siblings, 0 replies; 12+ messages in thread
From: Wolfram Sang @ 2024-04-26  6:43 UTC (permalink / raw)
  To: Baruch Siach; +Cc: linux-i2c

[-- Attachment #1: Type: text/plain, Size: 346 bytes --]

Hi Baruch,

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

Right, thank you very much for this report! I think we should have a
more defensive solution, though. I'll send my idea next. If you could
check it, that would be much appreciated.

All the best,

   Wolfram


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* [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

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-26  6:44 [PATCH] i2c: smbus: fix NULL function pointer dereference 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
  -- strict thread matches above, loose matches on Subject: below --
2024-04-10 15:12 Baruch Siach
2024-04-26  6:43 ` Wolfram Sang

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.