Denis Kirjanov 24bcdc
From fc532203ac4548cac5bc093d56e34fa8a7e28459 Mon Sep 17 00:00:00 2001
Denis Kirjanov 24bcdc
From: Du Cheng <ducheng2@gmail.com>
Denis Kirjanov 24bcdc
Date: Mon, 3 May 2021 13:56:50 +0200
Denis Kirjanov 24bcdc
Subject: [PATCH 15/19] ethernet: sun: niu: fix missing checks of
Denis Kirjanov 24bcdc
 niu_pci_eeprom_read()
Denis Kirjanov 24bcdc
Git-commit: e6e337708c22f80824b82d4af645f20715730ad0
Denis Kirjanov 24bcdc
Patch-mainline: v5.13-rc3
Denis Kirjanov 24bcdc
References: git-fixes
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
niu_pci_eeprom_read() may fail, so add checks to its return value and
Denis Kirjanov 24bcdc
propagate the error up the callstack.
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
An examination of the callstack up to niu_pci_eeprom_read shows that:
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
niu_pci_eeprom_read() // returns int
Denis Kirjanov 24bcdc
    niu_pci_vpd_scan_props() // returns int
Denis Kirjanov 24bcdc
        niu_pci_vpd_fetch() // returns *void*
Denis Kirjanov 24bcdc
            niu_get_invariants() // returns int
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
since niu_pci_vpd_fetch() returns void which breaks the bubbling up,
Denis Kirjanov 24bcdc
change its return type to int so that error is propagated upwards.
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
Signed-off-by: Du Cheng <ducheng2@gmail.com>
Denis Kirjanov 24bcdc
Cc: Shannon Nelson <shannon.lee.nelson@gmail.com>
Denis Kirjanov 24bcdc
Cc: David S. Miller <davem@davemloft.net>
Denis Kirjanov 24bcdc
Cc: stable <stable@vger.kernel.org>
Denis Kirjanov 24bcdc
Link: https://lore.kernel.org/r/20210503115736.2104747-24-gregkh@linuxfoundation.org
Denis Kirjanov 24bcdc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Denis Kirjanov 24bcdc
Signed-off-by: Denis Kirjanov <denis.kirjanov@suse.com>
Denis Kirjanov 24bcdc
---
Denis Kirjanov 24bcdc
 drivers/net/ethernet/sun/niu.c | 34 ++++++++++++++++++++++++----------
Denis Kirjanov 24bcdc
 1 file changed, 24 insertions(+), 10 deletions(-)
Denis Kirjanov 24bcdc
Denis Kirjanov 24bcdc
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
Denis Kirjanov 24bcdc
index 1c0aee4ada92..8a9a175e3c92 100644
Denis Kirjanov 24bcdc
--- a/drivers/net/ethernet/sun/niu.c
Denis Kirjanov 24bcdc
+++ b/drivers/net/ethernet/sun/niu.c
Denis Kirjanov 24bcdc
@@ -8119,6 +8119,8 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
Denis Kirjanov 24bcdc
 		start += 3;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		prop_len = niu_pci_eeprom_read(np, start + 4);
Denis Kirjanov 24bcdc
+		if (prop_len < 0)
Denis Kirjanov 24bcdc
+			return prop_len;
Denis Kirjanov 24bcdc
 		err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64);
Denis Kirjanov 24bcdc
 		if (err < 0)
Denis Kirjanov 24bcdc
 			return err;
Denis Kirjanov 24bcdc
@@ -8163,8 +8165,12 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
Denis Kirjanov 24bcdc
 			netif_printk(np, probe, KERN_DEBUG, np->dev,
Denis Kirjanov 24bcdc
 				     "VPD_SCAN: Reading in property [%s] len[%d]\n",
Denis Kirjanov 24bcdc
 				     namebuf, prop_len);
Denis Kirjanov 24bcdc
-			for (i = 0; i < prop_len; i++)
Denis Kirjanov 24bcdc
-				*prop_buf++ = niu_pci_eeprom_read(np, off + i);
Denis Kirjanov 24bcdc
+			for (i = 0; i < prop_len; i++) {
Denis Kirjanov 24bcdc
+				err =  niu_pci_eeprom_read(np, off + i);
Denis Kirjanov 24bcdc
+				if (err < 0)
Denis Kirjanov 24bcdc
+					return err;
Denis Kirjanov 24bcdc
+				*prop_buf++ = err;
Denis Kirjanov 24bcdc
+			}
Denis Kirjanov 24bcdc
 		}
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		start += len;
Denis Kirjanov 24bcdc
@@ -8174,14 +8180,14 @@ static int niu_pci_vpd_scan_props(struct niu *np, u32 start, u32 end)
Denis Kirjanov 24bcdc
 }
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 /* ESPC_PIO_EN_ENABLE must be set */
Denis Kirjanov 24bcdc
-static void niu_pci_vpd_fetch(struct niu *np, u32 start)
Denis Kirjanov 24bcdc
+static int niu_pci_vpd_fetch(struct niu *np, u32 start)
Denis Kirjanov 24bcdc
 {
Denis Kirjanov 24bcdc
 	u32 offset;
Denis Kirjanov 24bcdc
 	int err;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 	err = niu_pci_eeprom_read16_swp(np, start + 1);
Denis Kirjanov 24bcdc
 	if (err < 0)
Denis Kirjanov 24bcdc
-		return;
Denis Kirjanov 24bcdc
+		return err;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 	offset = err + 3;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
@@ -8190,12 +8196,14 @@ static void niu_pci_vpd_fetch(struct niu *np, u32 start)
Denis Kirjanov 24bcdc
 		u32 end;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		err = niu_pci_eeprom_read(np, here);
Denis Kirjanov 24bcdc
+		if (err < 0)
Denis Kirjanov 24bcdc
+			return err;
Denis Kirjanov 24bcdc
 		if (err != 0x90)
Denis Kirjanov 24bcdc
-			return;
Denis Kirjanov 24bcdc
+			return -EINVAL;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		err = niu_pci_eeprom_read16_swp(np, here + 1);
Denis Kirjanov 24bcdc
 		if (err < 0)
Denis Kirjanov 24bcdc
-			return;
Denis Kirjanov 24bcdc
+			return err;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		here = start + offset + 3;
Denis Kirjanov 24bcdc
 		end = start + offset + err;
Denis Kirjanov 24bcdc
@@ -8203,9 +8211,12 @@ static void niu_pci_vpd_fetch(struct niu *np, u32 start)
Denis Kirjanov 24bcdc
 		offset += err;
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		err = niu_pci_vpd_scan_props(np, here, end);
Denis Kirjanov 24bcdc
-		if (err < 0 || err == 1)
Denis Kirjanov 24bcdc
-			return;
Denis Kirjanov 24bcdc
+		if (err < 0)
Denis Kirjanov 24bcdc
+			return err;
Denis Kirjanov 24bcdc
+		if (err == 1)
Denis Kirjanov 24bcdc
+			return -EINVAL;
Denis Kirjanov 24bcdc
 	}
Denis Kirjanov 24bcdc
+	return 0;
Denis Kirjanov 24bcdc
 }
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 /* ESPC_PIO_EN_ENABLE must be set */
Denis Kirjanov 24bcdc
@@ -9298,8 +9309,11 @@ static int niu_get_invariants(struct niu *np)
Denis Kirjanov 24bcdc
 		offset = niu_pci_vpd_offset(np);
Denis Kirjanov 24bcdc
 		netif_printk(np, probe, KERN_DEBUG, np->dev,
Denis Kirjanov 24bcdc
 			     "%s() VPD offset [%08x]\n", __func__, offset);
Denis Kirjanov 24bcdc
-		if (offset)
Denis Kirjanov 24bcdc
-			niu_pci_vpd_fetch(np, offset);
Denis Kirjanov 24bcdc
+		if (offset) {
Denis Kirjanov 24bcdc
+			err = niu_pci_vpd_fetch(np, offset);
Denis Kirjanov 24bcdc
+			if (err < 0)
Denis Kirjanov 24bcdc
+				return err;
Denis Kirjanov 24bcdc
+		}
Denis Kirjanov 24bcdc
 		nw64(ESPC_PIO_EN, 0);
Denis Kirjanov 24bcdc
 
Denis Kirjanov 24bcdc
 		if (np->flags & NIU_FLAGS_VPD_VALID) {
Denis Kirjanov 24bcdc
-- 
Denis Kirjanov 24bcdc
2.16.4
Denis Kirjanov 24bcdc