| From ab81907d252633d08b2dbfe04780545adae348f7 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 24 Jun 2021 18:52:07 +0300 |
| Subject: net: dsa: sja1105: fix NULL pointer dereference in |
| sja1105_reload_cbs() |
| |
| From: Vladimir Oltean <vladimir.oltean@nxp.com> |
| |
| [ Upstream commit be7f62eebaff2f86c1467a2d33930a0a7a87675b ] |
| |
| priv->cbs is an array of priv->info->num_cbs_shapers elements of type |
| struct sja1105_cbs_entry which only get allocated if CONFIG_NET_SCH_CBS |
| is enabled. |
| |
| However, sja1105_reload_cbs() is called from sja1105_static_config_reload() |
| which in turn is called for any of the items in sja1105_reset_reasons, |
| therefore during the normal runtime of the driver and not just from a |
| code path which can be triggered by the tc-cbs offload. |
| |
| The sja1105_reload_cbs() function does not contain a check whether the |
| priv->cbs array is NULL or not, it just assumes it isn't and proceeds to |
| iterate through the credit-based shaper elements. This leads to a NULL |
| pointer dereference. |
| |
| The solution is to return success if the priv->cbs array has not been |
| allocated, since sja1105_reload_cbs() has nothing to do. |
| |
| Fixes: 4d7525085a9b ("net: dsa: sja1105: offload the Credit-Based Shaper qdisc") |
| Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/dsa/sja1105/sja1105_main.c | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c |
| index e273b2bd82ba..82852c57cc0e 100644 |
| --- a/drivers/net/dsa/sja1105/sja1105_main.c |
| +++ b/drivers/net/dsa/sja1105/sja1105_main.c |
| @@ -1711,6 +1711,12 @@ static int sja1105_reload_cbs(struct sja1105_private *priv) |
| { |
| int rc = 0, i; |
| |
| + /* The credit based shapers are only allocated if |
| + * CONFIG_NET_SCH_CBS is enabled. |
| + */ |
| + if (!priv->cbs) |
| + return 0; |
| + |
| for (i = 0; i < priv->info->num_cbs_shapers; i++) { |
| struct sja1105_cbs_entry *cbs = &priv->cbs[i]; |
| |
| -- |
| 2.30.2 |
| |