kernel: fix bugs added with mac-address-ascii support
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: ecd81de7a5
("ath79: add nvmem cell mac-address-ascii support")
Cc: Yousong Zhou <yszhou4tech@gmail.com>
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
7c574525ee
commit
a1abf71827
2 changed files with 38 additions and 40 deletions
|
@ -75,36 +75,35 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||||
/**
|
/**
|
||||||
* Obtain the MAC address from an nvmem cell named 'mac-address' associated
|
* Obtain the MAC address from an nvmem cell named 'mac-address' associated
|
||||||
* with given device.
|
* 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;
|
struct nvmem_cell *cell;
|
||||||
const void *mac;
|
const void *mac;
|
||||||
- size_t len;
|
- size_t len;
|
||||||
+ struct nvmem_cell_mac_address_property *property;
|
|
||||||
+ int i;
|
+ 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++) {
|
+ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
|
||||||
+ property = &nvmem_cell_mac_address_properties[i];
|
+ property = &nvmem_cell_mac_address_properties[i];
|
||||||
+ cell = nvmem_cell_get(dev, property->name);
|
+ cell = nvmem_cell_get(dev, property->name);
|
||||||
+ if (IS_ERR(cell)) {
|
+ /* For -EPROBE_DEFER don't try other properties. We'll get back to this one. */
|
||||||
+ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
|
+ if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
|
||||||
+ return PTR_ERR(cell);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ mac = property->read(cell);
|
|
||||||
+ nvmem_cell_put(cell);
|
|
||||||
+ break;
|
+ 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 (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
|
||||||
+ if (!is_valid_ether_addr(mac)) {
|
+ if (!is_valid_ether_addr(mac)) {
|
||||||
kfree(mac);
|
kfree(mac);
|
||||||
|
|
|
@ -75,36 +75,35 @@ Submitted-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||||
/**
|
/**
|
||||||
* nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
|
* nvmem_get_mac_address - Obtain the MAC address from an nvmem cell named
|
||||||
* 'mac-address' associated with given device.
|
* '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;
|
struct nvmem_cell *cell;
|
||||||
const void *mac;
|
const void *mac;
|
||||||
- size_t len;
|
- size_t len;
|
||||||
+ struct nvmem_cell_mac_address_property *property;
|
|
||||||
+ int i;
|
+ 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++) {
|
+ for (i = 0; i < ARRAY_SIZE(nvmem_cell_mac_address_properties); i++) {
|
||||||
+ property = &nvmem_cell_mac_address_properties[i];
|
+ property = &nvmem_cell_mac_address_properties[i];
|
||||||
+ cell = nvmem_cell_get(dev, property->name);
|
+ cell = nvmem_cell_get(dev, property->name);
|
||||||
+ if (IS_ERR(cell)) {
|
+ /* For -EPROBE_DEFER don't try other properties. We'll get back to this one. */
|
||||||
+ if (i == ARRAY_SIZE(nvmem_cell_mac_address_properties) - 1)
|
+ if (!IS_ERR(cell) || PTR_ERR(cell) == -EPROBE_DEFER)
|
||||||
+ return PTR_ERR(cell);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ mac = property->read(cell);
|
|
||||||
+ nvmem_cell_put(cell);
|
|
||||||
+ break;
|
+ 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 (len != ETH_ALEN || !is_valid_ether_addr(mac)) {
|
||||||
+ if (!is_valid_ether_addr(mac)) {
|
+ if (!is_valid_ether_addr(mac)) {
|
||||||
kfree(mac);
|
kfree(mac);
|
||||||
|
|
Loading…
Reference in a new issue