kernel: fix bugs added with mac-address-ascii support
authorRafał Miłecki <rafal@milecki.pl>
Thu, 5 Jan 2023 12:33:18 +0000 (13:33 +0100)
committerRafał Miłecki <rafal@milecki.pl>
Sat, 7 Jan 2023 11:02:30 +0000 (12:02 +0100)
1. Check for -EPROBE_DEFER
If it occurs we have to return immediately. Trying other properties
could result in another error and ignoring -EPROBE_DEFER which has a
special meaning.

2. Check for read result
Assuming property->read() success can result in NULL pointer
dereference. It happens e.g. for "mac-address" with NVMEM cell
containing invalid MAC.

3. Simplify code
Don't move cell reading & nvmem_cell_put() into a loop. Simplify loop
code.

Fixes: ecd81de7a5ab ("ath79: add nvmem cell mac-address-ascii support")
Cc: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
target/linux/generic/hack-5.10/601-of_net-add-mac-address-ascii-support.patch
target/linux/generic/hack-5.15/601-of_net-add-mac-address-ascii-support.patch

index 5dd70f5f718ce0a48f62ddcbf0b84f2d94d03fa0..cf2a26c9d6aaede43ef344aaba5b70422a0550e5 100644 (file)
@@ -75,36 +75,35 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
  /**
   * Obtain the MAC address from an nvmem cell named 'mac-address' associated
   * with given device.
-@@ -552,19 +609,23 @@ int nvmem_get_mac_address(struct device
+@@ -550,21 +607,28 @@ EXPORT_SYMBOL(eth_platform_get_mac_addre
+  */
+ int nvmem_get_mac_address(struct device *dev, void *addrbuf)
  {
++      struct nvmem_cell_mac_address_property *property;
        struct nvmem_cell *cell;
        const void *mac;
 -      size_t len;
-+      struct nvmem_cell_mac_address_property *property;
 +      int i;
--      cell = nvmem_cell_get(dev, "mac-address");
--      if (IS_ERR(cell))
--              return PTR_ERR(cell);
--
--      mac = nvmem_cell_read(cell, &len);
--      nvmem_cell_put(cell);
--
--      if (IS_ERR(mac))
--              return PTR_ERR(mac);
++
 +      for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
 +              property = &nvmem_cell_mac_address_properties[i];
 +              cell = nvmem_cell_get(dev, property->name);
-+              if (IS_ERR(cell)) {
-+                      if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
-+                              return PTR_ERR(cell);
-+                      continue;
-+              }
-+              mac = property->read(cell);
-+              nvmem_cell_put(cell);
-+              break;
++              /* For -EPROBE_DEFER don't try other properties. We'll get back to this one. */
++              if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
++                      break;
 +      }
  
+-      cell = nvmem_cell_get(dev, "mac-address");
+       if (IS_ERR(cell))
+               return PTR_ERR(cell);
+-      mac = nvmem_cell_read(cell, &len);
++      mac = property->read(cell);
+       nvmem_cell_put(cell);
+-
+       if (IS_ERR(mac))
+               return PTR_ERR(mac);
 -      if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
 +      if (!is_valid_ether_addr(mac)) {
                kfree(mac);
index 4ab05b4ea6f94920c7eaffe60158d91f667f12c6..eb390961d7827519d08fe12ba8cf738dc8c326e5 100644 (file)
@@ -75,36 +75,35 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
  /**
   * nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
   * 'mac-address' associated with given device.
-@@ -551,19 +608,23 @@ int nvmem_get_mac_address(struct device
+@@ -549,21 +606,28 @@ EXPORT_SYMBOL(eth_platform_get_mac_addre
+  */
+ int nvmem_get_mac_address(struct device *dev, void *addrbuf)
  {
++      struct nvmem_cell_mac_address_property *property;
        struct nvmem_cell *cell;
        const void *mac;
 -      size_t len;
-+      struct nvmem_cell_mac_address_property *property;
 +      int i;
--      cell = nvmem_cell_get(dev, "mac-address");
--      if (IS_ERR(cell))
--              return PTR_ERR(cell);
--
--      mac = nvmem_cell_read(cell, &len);
--      nvmem_cell_put(cell);
--
--      if (IS_ERR(mac))
--              return PTR_ERR(mac);
++
 +      for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
 +              property = &nvmem_cell_mac_address_properties[i];
 +              cell = nvmem_cell_get(dev, property->name);
-+              if (IS_ERR(cell)) {
-+                      if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
-+                              return PTR_ERR(cell);
-+                      continue;
-+              }
-+              mac = property->read(cell);
-+              nvmem_cell_put(cell);
-+              break;
++              /* For -EPROBE_DEFER don't try other properties. We'll get back to this one. */
++              if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
++                      break;
 +      }
  
+-      cell = nvmem_cell_get(dev, "mac-address");
+       if (IS_ERR(cell))
+               return PTR_ERR(cell);
+-      mac = nvmem_cell_read(cell, &len);
++      mac = property->read(cell);
+       nvmem_cell_put(cell);
+-
+       if (IS_ERR(mac))
+               return PTR_ERR(mac);
 -      if (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
 +      if (!is_valid_ether_addr(mac)) {
                kfree(mac);