[U-Boot] Running out of memory after setting invalid ethaddr
Thomas Schaefer
Thomas.Schaefer at kontron.com
Thu Nov 9 11:02:39 UTC 2017
Hi Joe et. al.
After setting MAC address to invalid value 00:00:00:00:00:00 and resetting to a valid one, u-boot will run into a recursive endless loop until no memory is left to allocate a new MAC address:
=> print eth1addr
eth1addr=00:a0:a5:10:20:31
=> setenv eth1addr 00:00:00:00:00:00
=> setenv eth1addr 00:a0:a5:10:20:31
## Can't malloc 18 bytes
=>
I have tested this with current v2017.11-rc4 on a Freescale T1024RDB eval system, but also see this on our custom i.MX7 and T1042 boards which are based on v2017.03.
After some investigation, I found that the recursive loop is entered in eth_write_hwaddr in net/eth_legacy.c when 'eth_env_set_enetaddr_by_index' is called:
~snip
} else if (is_valid_ethaddr(dev->enetaddr)) {
eth_env_set_enetaddr_by_index(base_name, eth_number,
dev->enetaddr);
~snip
The patch shown below would prevent u-boot from setting ethaddr to an invalid value like 00:00:00:00:00:00 and avoids running into a situation as shown above:
diff --git a/net/eth_legacy.c b/net/eth_legacy.c
index be0cf64a3d..8d0a573551 100644
--- a/net/eth_legacy.c
+++ b/net/eth_legacy.c
@@ -104,9 +104,11 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
{
int index;
struct eth_device *dev;
+ int ret = 0;
+ unsigned char tmp_enetaddr[ARP_HLEN];
if (!eth_devices)
- return 0;
+ return ret;
/* look for an index after "eth" */
index = simple_strtoul(name + 3, NULL, 10);
@@ -117,8 +119,17 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
switch (op) {
case env_op_create:
case env_op_overwrite:
- eth_parse_enetaddr(value, dev->enetaddr);
- eth_write_hwaddr(dev, "eth", dev->index);
+ if (is_valid_ethaddr(tmp_enetaddr)) {
+ eth_parse_enetaddr(value,
+ dev->enetaddr);
+ eth_write_hwaddr(dev, "eth",
+ dev->index);
+ } else {
+ printf("\nMAC address %pM is not "
+ "valid\n",
+ tmp_enetaddr);
+ ret = 1;
+ }
break;
case env_op_delete:
memset(dev->enetaddr, 0, ARP_HLEN);
@@ -127,7 +138,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
dev = dev->next;
} while (dev != eth_devices);
- return 0;
+ return ret;
}
U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
What do you think?
Best regards,
Thomas
Thomas Schäfer
SW Design Engineer
Kontron - An S&T Company
Heinrich-Barth-Straße 1-1a | 66115 Saarbrücken | Germany
P: +49 681 95916 203
thomas.schaefer at kontron.com
More information about the U-Boot
mailing list