rte_eth_random_addr() returned 48 bits of raw rte_rand() output on every call. That both makes the generated address predictable and leaks enough generator output to help recover the internal state.
Use rte_random_bytes() instead. The function cannot report an error to its callers, so fall back to rte_rand() if the system random generator is unavailable, which is no worse than the previous behaviour. Signed-off-by: Stephen Hemminger <[email protected]> --- lib/net/rte_ether.c | 13 ++++++++++--- lib/net/rte_ether.h | 5 +++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/net/rte_ether.c b/lib/net/rte_ether.c index 6703145fc5..4b2932c00b 100644 --- a/lib/net/rte_ether.c +++ b/lib/net/rte_ether.c @@ -3,6 +3,7 @@ */ #include <stdbool.h> +#include <string.h> #include <eal_export.h> #include <rte_ether.h> @@ -12,10 +13,16 @@ RTE_EXPORT_SYMBOL(rte_eth_random_addr) void rte_eth_random_addr(uint8_t *addr) { - uint64_t rand = rte_rand(); - uint8_t *p = (uint8_t *)&rand; + /* Prefer the system random generator so that the address can not + * be predicted from other random values. Fall back to rte_rand() + * if it is unavailable, which is what was always used before. + */ + if (rte_random_bytes(addr, RTE_ETHER_ADDR_LEN) != 0) { + uint64_t rand = rte_rand(); + + memcpy(addr, &rand, RTE_ETHER_ADDR_LEN); + } - rte_memcpy(addr, p, RTE_ETHER_ADDR_LEN); addr[0] &= (uint8_t)~RTE_ETHER_GROUP_ADDR; /* clear multicast bit */ addr[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR; /* set local assignment bit */ } diff --git a/lib/net/rte_ether.h b/lib/net/rte_ether.h index c9a0b536c3..b0dc227362 100644 --- a/lib/net/rte_ether.h +++ b/lib/net/rte_ether.h @@ -221,6 +221,11 @@ static inline int rte_is_valid_assigned_ether_addr(const struct rte_ether_addr * /** * Generate a random Ethernet address that is locally administered * and not multicast. + * + * The address is taken from the random source of the operating system + * so that it cannot be predicted from other random values. If that + * source is unavailable it falls back to the pseudo-random rte_rand(). + * * @param addr * A pointer to Ethernet address. */ -- 2.53.0

