Message ID | 20240702095034.12371-1-amishin@t-argos.ru (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | fsl/fman: Validate cell-index value obtained from Device Tree | expand |
On Tue, Jul 02, 2024 at 12:50:34PM +0300, Aleksandr Mishin wrote: > Cell-index value is obtained from Device Tree and then used to calculate > the index for accessing arrays port_mfl[], mac_mfl[] and intr_mng[]. > In case of broken DT due to any error cell-index can contain any value > and it is possible to go beyond the array boundaries which can lead > at least to memory corruption. > Validate cell-index value obtained from Device Tree. > > Found by Linux Verification Center (linuxtesting.org) with SVACE. > > Fixes: 414fd46e7762 ("fsl/fman: Add FMan support") > Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru> > --- > drivers/net/ethernet/freescale/fman/fman.c | 7 +++++++ > drivers/net/ethernet/freescale/fman/fman.h | 2 ++ > drivers/net/ethernet/freescale/fman/mac.c | 5 +++++ > 3 files changed, 14 insertions(+) > > diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c > index d96028f01770..6929bca3f768 100644 > --- a/drivers/net/ethernet/freescale/fman/fman.c > +++ b/drivers/net/ethernet/freescale/fman/fman.c > @@ -2933,3 +2933,10 @@ module_exit(fman_unload); > > MODULE_LICENSE("Dual BSD/GPL"); > MODULE_DESCRIPTION("Freescale DPAA Frame Manager driver"); > + > +int check_mac_id(u32 mac_id) > +{ > + if (mac_id >= MAX_NUM_OF_MACS) > + return -EINVAL; > + return 0; > +} > diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h > index 2ea575a46675..3cedde4851e1 100644 > --- a/drivers/net/ethernet/freescale/fman/fman.h > +++ b/drivers/net/ethernet/freescale/fman/fman.h > @@ -372,6 +372,8 @@ u16 fman_get_max_frm(void); > > int fman_get_rx_extra_headroom(void); > > +int check_mac_id(u32 mac_id); > + > #ifdef CONFIG_DPAA_ERRATUM_A050385 > bool fman_has_errata_a050385(void); > #endif > diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c > index 9767586b4eb3..7a67b4c887e2 100644 > --- a/drivers/net/ethernet/freescale/fman/mac.c > +++ b/drivers/net/ethernet/freescale/fman/mac.c > @@ -247,6 +247,11 @@ static int mac_probe(struct platform_device *_of_dev) > dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); > return -EINVAL; > } > + err = check_mac_id(val); Hi Aleksandr, all, It seems that this breaks linking with allmodconfig builds on x86_64, perhaps it is better to simply make check_mac_id a static function in mac.c ? > + if (err) { > + dev_err(dev, "cell-index value is out of range for %pOF\n", mac_node); Although other instances exist in this function before this patch, it does look like this leaks a reference to of_dev taken by the call to of_find_device_by_node() on line 194. Maybe it is intentional, I'm unsure. Perhaps this can be investigated separately to the fix proposed by this patch? Flagged by Coccinelle (this one is on line 253): .../mac.c:238:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:242:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:248:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:253:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:267:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:273:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:282:3-9: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:320:2-8: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:333:1-7: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:337:1-7: ERROR: missing put_device; call of_find_device_by_node on line 194, but without a corresponding object release within this function. .../mac.c:282:3-9: ERROR: missing put_device; call of_find_device_by_node on line 285, but without a corresponding object release within this function. .../mac.c:320:2-8: ERROR: missing put_device; call of_find_device_by_node on line 285, but without a corresponding object release within this function. .../mac.c:333:1-7: ERROR: missing put_device; call of_find_device_by_node on line 285, but without a corresponding object release within this function. .../mac.c:337:1-7: ERROR: missing put_device; call of_find_device_by_node on line 285, but without a corresponding object release within this function. > + return err; > + } > priv->cell_index = (u8)val; > > /* Get the MAC address */
On Tue, 2 Jul 2024 14:36:51 +0100 Simon Horman wrote: > Maybe it is intentional, I'm unsure. > Perhaps this can be investigated separately to the fix proposed by this > patch? +1, please fix this first
diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c index d96028f01770..6929bca3f768 100644 --- a/drivers/net/ethernet/freescale/fman/fman.c +++ b/drivers/net/ethernet/freescale/fman/fman.c @@ -2933,3 +2933,10 @@ module_exit(fman_unload); MODULE_LICENSE("Dual BSD/GPL"); MODULE_DESCRIPTION("Freescale DPAA Frame Manager driver"); + +int check_mac_id(u32 mac_id) +{ + if (mac_id >= MAX_NUM_OF_MACS) + return -EINVAL; + return 0; +} diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h index 2ea575a46675..3cedde4851e1 100644 --- a/drivers/net/ethernet/freescale/fman/fman.h +++ b/drivers/net/ethernet/freescale/fman/fman.h @@ -372,6 +372,8 @@ u16 fman_get_max_frm(void); int fman_get_rx_extra_headroom(void); +int check_mac_id(u32 mac_id); + #ifdef CONFIG_DPAA_ERRATUM_A050385 bool fman_has_errata_a050385(void); #endif diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c index 9767586b4eb3..7a67b4c887e2 100644 --- a/drivers/net/ethernet/freescale/fman/mac.c +++ b/drivers/net/ethernet/freescale/fman/mac.c @@ -247,6 +247,11 @@ static int mac_probe(struct platform_device *_of_dev) dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); return -EINVAL; } + err = check_mac_id(val); + if (err) { + dev_err(dev, "cell-index value is out of range for %pOF\n", mac_node); + return err; + } priv->cell_index = (u8)val; /* Get the MAC address */
Cell-index value is obtained from Device Tree and then used to calculate the index for accessing arrays port_mfl[], mac_mfl[] and intr_mng[]. In case of broken DT due to any error cell-index can contain any value and it is possible to go beyond the array boundaries which can lead at least to memory corruption. Validate cell-index value obtained from Device Tree. Found by Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 414fd46e7762 ("fsl/fman: Add FMan support") Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru> --- drivers/net/ethernet/freescale/fman/fman.c | 7 +++++++ drivers/net/ethernet/freescale/fman/fman.h | 2 ++ drivers/net/ethernet/freescale/fman/mac.c | 5 +++++ 3 files changed, 14 insertions(+)