| From 8ff2d368ca40055a8b1ac89b1c8c4dfba74bc4c2 Mon Sep 17 00:00:00 2001 |
| From: Florian Fainelli <f.fainelli@gmail.com> |
| Date: Mon, 30 Mar 2020 14:38:46 -0700 |
| Subject: [PATCH] net: dsa: bcm_sf2: Fix overflow checks |
| |
| commit d0802dc411f469569a537283b6f3833af47aece9 upstream. |
| |
| Commit f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing |
| set_rxnfc") tried to fix the some user controlled buffer overflows in |
| bcm_sf2_cfp_rule_set() and bcm_sf2_cfp_rule_del() but the fix was using |
| CFP_NUM_RULES, which while it is correct not to overflow the bitmaps, is |
| not representative of what the device actually supports. Correct that by |
| using bcm_sf2_cfp_rule_size() instead. |
| |
| The latter subtracts the number of rules by 1, so change the checks from |
| greater than or equal to greater than accordingly. |
| |
| Fixes: f949a12fd697 ("net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc") |
| Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c |
| index 471837cf0b21..e15d18bb981e 100644 |
| --- a/drivers/net/dsa/bcm_sf2_cfp.c |
| +++ b/drivers/net/dsa/bcm_sf2_cfp.c |
| @@ -882,17 +882,14 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, |
| fs->m_ext.data[1])) |
| return -EINVAL; |
| |
| - if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) |
| + if (fs->location != RX_CLS_LOC_ANY && |
| + fs->location > bcm_sf2_cfp_rule_size(priv)) |
| return -EINVAL; |
| |
| if (fs->location != RX_CLS_LOC_ANY && |
| test_bit(fs->location, priv->cfp.used)) |
| return -EBUSY; |
| |
| - if (fs->location != RX_CLS_LOC_ANY && |
| - fs->location > bcm_sf2_cfp_rule_size(priv)) |
| - return -EINVAL; |
| - |
| ret = bcm_sf2_cfp_rule_cmp(priv, port, fs); |
| if (ret == 0) |
| return -EEXIST; |
| @@ -973,7 +970,7 @@ static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 loc) |
| struct cfp_rule *rule; |
| int ret; |
| |
| - if (loc >= CFP_NUM_RULES) |
| + if (loc > bcm_sf2_cfp_rule_size(priv)) |
| return -EINVAL; |
| |
| /* Refuse deleting unused rules, and those that are not unique since |
| -- |
| 2.7.4 |
| |