diff mbox series

net: dsa: microchip: fix NULL pointer dereference in ksz_connect_tag_protocol()

Message ID 20231205124636.1345761-1-sean@geanix.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net: dsa: microchip: fix NULL pointer dereference in ksz_connect_tag_protocol() | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl fail Tree is dirty after regen; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1115 this patch: 1115
netdev/cc_maintainers fail 2 blamed authors not CCed: arun.ramadoss@microchip.com olteanv@gmail.com; 6 maintainers not CCed: kuba@kernel.org f.fainelli@gmail.com olteanv@gmail.com pabeni@redhat.com arun.ramadoss@microchip.com edumazet@google.com
netdev/build_clang success Errors and warnings before: 1142 this patch: 1142
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1142 this patch: 1142
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 13 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Sean Nyekjaer Dec. 5, 2023, 12:46 p.m. UTC
We should check whether the ksz_tagger_data is allocated.
For example when using DSA_TAG_PROTO_KSZ8795 protocol, ksz_connect() is not
allocating ksz_tagger_data.

This avoids the following null pointer dereference:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 when write
[00000000] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT SMP ARM
Modules linked in:
CPU: 1 PID: 26 Comm: kworker/u5:1 Not tainted 6.6.0
Hardware name: STM32 (Device Tree Support)
Workqueue: events_unbound deferred_probe_work_func
PC is at ksz_connect_tag_protocol+0x40/0x48
LR is at ksz_connect_tag_protocol+0x3c/0x48
[ ... ]
 ksz_connect_tag_protocol from dsa_register_switch+0x9ac/0xee0
 dsa_register_switch from ksz_switch_register+0x65c/0x828
 ksz_switch_register from ksz_spi_probe+0x11c/0x168
 ksz_spi_probe from spi_probe+0x84/0xa8
 spi_probe from really_probe+0xc8/0x2d8

Fixes: ab32f56a4100 ("net: dsa: microchip: ptp: add packet transmission timestamping")
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
---
 drivers/net/dsa/microchip/ksz_common.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Comments

Vladimir Oltean Dec. 5, 2023, 5:09 p.m. UTC | #1
On Tue, Dec 05, 2023 at 01:46:36PM +0100, Sean Nyekjaer wrote:
> We should check whether the ksz_tagger_data is allocated.
> For example when using DSA_TAG_PROTO_KSZ8795 protocol, ksz_connect() is not
> allocating ksz_tagger_data.
> 
> This avoids the following null pointer dereference:
> Unable to handle kernel NULL pointer dereference at virtual address 00000000 when write
> [00000000] *pgd=00000000
> Internal error: Oops: 817 [#1] PREEMPT SMP ARM
> Modules linked in:
> CPU: 1 PID: 26 Comm: kworker/u5:1 Not tainted 6.6.0
> Hardware name: STM32 (Device Tree Support)
> Workqueue: events_unbound deferred_probe_work_func
> PC is at ksz_connect_tag_protocol+0x40/0x48
> LR is at ksz_connect_tag_protocol+0x3c/0x48
> [ ... ]
>  ksz_connect_tag_protocol from dsa_register_switch+0x9ac/0xee0
>  dsa_register_switch from ksz_switch_register+0x65c/0x828
>  ksz_switch_register from ksz_spi_probe+0x11c/0x168
>  ksz_spi_probe from spi_probe+0x84/0xa8
>  spi_probe from really_probe+0xc8/0x2d8
> 
> Fixes: ab32f56a4100 ("net: dsa: microchip: ptp: add packet transmission timestamping")
> Signed-off-by: Sean Nyekjaer <sean@geanix.com>
> ---
>  drivers/net/dsa/microchip/ksz_common.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 42db7679c360..1b9815418294 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -2623,9 +2623,10 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds,
>  				    enum dsa_tag_protocol proto)
>  {
>  	struct ksz_tagger_data *tagger_data;
> -
> -	tagger_data = ksz_tagger_data(ds);
> -	tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +	if (ksz_tagger_data(ds)) {
> +		tagger_data = ksz_tagger_data(ds);
> +		tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +	}
>  
>  	return 0;
>  }
> -- 
> 2.42.0
> 
> 

Please spell out the list of protocols for which the driver should
provide its deferred xmit handler. This is what the "enum dsa_tag_protocol
proto" argument is there for. AKA those struct dsa_device_ops that do
provide a "connect" method: DSA_TAG_PROTO_KSZ9477, DSA_TAG_PROTO_KSZ9893,
DSA_TAG_PROTO_LAN937X. Also look at how other drivers do it. My bad for
not spotting this during review of the blamed change.

Simply checking against NULL might be masking other problems and making
them harder to spot.

General process-related information:
- Please designate the next email submission as "PATCH v2 net" to clarify
  that you are targeting the net.git tree for stable fixes, and not the
  net-next.git tree for new features
- Please use ./scripts/get_maintainer.pl more diligently and copy all
  the listed maintainers to future submissions.

---
pw-bot: changes-requested
Arun Ramadoss Dec. 6, 2023, 3:59 a.m. UTC | #2
Hi Sean,

> diff --git a/drivers/net/dsa/microchip/ksz_common.c
> b/drivers/net/dsa/microchip/ksz_common.c
> index 42db7679c360..1b9815418294 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -2623,9 +2623,10 @@ static int ksz_connect_tag_protocol(struct
> dsa_switch *ds,
>                                     enum dsa_tag_protocol proto)  {
>         struct ksz_tagger_data *tagger_data;
> -
> -       tagger_data = ksz_tagger_data(ds);
> -       tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +       if (ksz_tagger_data(ds)) {
> +               tagger_data = ksz_tagger_data(ds);
> +               tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +       }

Do we need to return error in case of xmit_work_fn is not initialized.

> 
>         return 0;
>  }
> --
> 2.42.0
Madhuri.Sripada@microchip.com Dec. 6, 2023, 1:35 p.m. UTC | #3
Hi Sean

-----Original Message-----
From: Sean Nyekjaer <sean@geanix.com> 
Sent: Tuesday, December 5, 2023 6:17 PM
To: Woojung Huh - C21699 <Woojung.Huh@microchip.com>; UNGLinuxDriver <UNGLinuxDriver@microchip.com>; andrew@lunn.ch; ceggers@arri.de; netdev@vger.kernel.org
Cc: Sean Nyekjaer <sean@geanix.com>
Subject: [PATCH] net: dsa: microchip: fix NULL pointer dereference in ksz_connect_tag_protocol()

[Some people who received this message don't often get email from sean@geanix.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]

EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe

We should check whether the ksz_tagger_data is allocated.
For example when using DSA_TAG_PROTO_KSZ8795 protocol, ksz_connect() is not allocating ksz_tagger_data.

This avoids the following null pointer dereference:
Unable to handle kernel NULL pointer dereference at virtual address 00000000 when write [00000000] *pgd=00000000 Internal error: Oops: 817 [#1] PREEMPT SMP ARM Modules linked in:
CPU: 1 PID: 26 Comm: kworker/u5:1 Not tainted 6.6.0 Hardware name: STM32 (Device Tree Support)
Workqueue: events_unbound deferred_probe_work_func PC is at ksz_connect_tag_protocol+0x40/0x48
LR is at ksz_connect_tag_protocol+0x3c/0x48
[ ... ]
 ksz_connect_tag_protocol from dsa_register_switch+0x9ac/0xee0  dsa_register_switch from ksz_switch_register+0x65c/0x828  ksz_switch_register from ksz_spi_probe+0x11c/0x168  ksz_spi_probe from spi_probe+0x84/0xa8  spi_probe from really_probe+0xc8/0x2d8

Fixes: ab32f56a4100 ("net: dsa: microchip: ptp: add packet transmission timestamping")
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
---
 drivers/net/dsa/microchip/ksz_common.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 42db7679c360..1b9815418294 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2623,9 +2623,10 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds,
                                    enum dsa_tag_protocol proto)  {
        struct ksz_tagger_data *tagger_data;
-
-       tagger_data = ksz_tagger_data(ds);
-       tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+       if (ksz_tagger_data(ds)) {
+               tagger_data = ksz_tagger_data(ds);
+               tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+       }

        return 0;
 }
--
2.42.0


Instead of calling " ksz_tagger_data(ds)" twice, NULL check tagger_data before assigning " xmit_work_fn" would help right?
Is there any reason for doing this way?
Sean Nyekjaer Dec. 6, 2023, 2:46 p.m. UTC | #4
> On 6 Dec 2023, at 14.35, <Madhuri.Sripada@microchip.com> <Madhuri.Sripada@microchip.com> wrote:
> 
> Hi Sean
> 
> -----Original Message-----
> From: Sean Nyekjaer <sean@geanix.com> 
> Sent: Tuesday, December 5, 2023 6:17 PM
> To: Woojung Huh - C21699 <Woojung.Huh@microchip.com>; UNGLinuxDriver <UNGLinuxDriver@microchip.com>; andrew@lunn.ch; ceggers@arri.de; netdev@vger.kernel.org
> Cc: Sean Nyekjaer <sean@geanix.com>
> Subject: [PATCH] net: dsa: microchip: fix NULL pointer dereference in ksz_connect_tag_protocol()
> 
> [Some people who received this message don't often get email from sean@geanix.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> We should check whether the ksz_tagger_data is allocated.
> For example when using DSA_TAG_PROTO_KSZ8795 protocol, ksz_connect() is not allocating ksz_tagger_data.
> 
> This avoids the following null pointer dereference:
> Unable to handle kernel NULL pointer dereference at virtual address 00000000 when write [00000000] *pgd=00000000 Internal error: Oops: 817 [#1] PREEMPT SMP ARM Modules linked in:
> CPU: 1 PID: 26 Comm: kworker/u5:1 Not tainted 6.6.0 Hardware name: STM32 (Device Tree Support)
> Workqueue: events_unbound deferred_probe_work_func PC is at ksz_connect_tag_protocol+0x40/0x48
> LR is at ksz_connect_tag_protocol+0x3c/0x48
> [ ... ]
> ksz_connect_tag_protocol from dsa_register_switch+0x9ac/0xee0  dsa_register_switch from ksz_switch_register+0x65c/0x828  ksz_switch_register from ksz_spi_probe+0x11c/0x168  ksz_spi_probe from spi_probe+0x84/0xa8  spi_probe from really_probe+0xc8/0x2d8
> 
> Fixes: ab32f56a4100 ("net: dsa: microchip: ptp: add packet transmission timestamping")
> Signed-off-by: Sean Nyekjaer <sean@geanix.com>
> ---
> drivers/net/dsa/microchip/ksz_common.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 42db7679c360..1b9815418294 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -2623,9 +2623,10 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds,
>                                    enum dsa_tag_protocol proto)  {
>        struct ksz_tagger_data *tagger_data;
> -
> -       tagger_data = ksz_tagger_data(ds);
> -       tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +       if (ksz_tagger_data(ds)) {
> +               tagger_data = ksz_tagger_data(ds);
> +               tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
> +       }
> 
>        return 0;
> }
> --
> 2.42.0
> 
> 
> Instead of calling " ksz_tagger_data(ds)" twice, NULL check tagger_data before assigning " xmit_work_fn" would help right?
> Is there any reason for doing this way?

I have submitted a v2 of this patch:
https://lore.kernel.org/netdev/20231206071655.1626479-1-sean@geanix.com/T/#u

/Sean
diff mbox series

Patch

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 42db7679c360..1b9815418294 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -2623,9 +2623,10 @@  static int ksz_connect_tag_protocol(struct dsa_switch *ds,
 				    enum dsa_tag_protocol proto)
 {
 	struct ksz_tagger_data *tagger_data;
-
-	tagger_data = ksz_tagger_data(ds);
-	tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+	if (ksz_tagger_data(ds)) {
+		tagger_data = ksz_tagger_data(ds);
+		tagger_data->xmit_work_fn = ksz_port_deferred_xmit;
+	}
 
 	return 0;
 }