[RFC] ethdev: add buffer size parameter to rte_eth_dev_get_name_by_port()

Andrew Rybchenko andrew.rybchenko at oktetlabs.ru
Thu Apr 9 08:59:04 CEST 2026


On 4/9/26 4:36 AM, Stephen Hemminger wrote:
> rte_eth_dev_get_name_by_port() uses strcpy() into a caller-provided
> buffer with no bounds checking. A mistaken caller that supplies a
> buffer smaller than RTE_ETH_NAME_MAX_LEN can overflow the buffer.
> 
> Add a size parameter and replace strcpy() with strlcpy(), returning
> -ERANGE if the name is truncated. The copy is now performed under
> the ethdev shared data lock so that the name cannot be mutated by
> another process between reading and copying.
> 
> The previous ABI is preserved via symbol versioning (DPDK_26) with a
> thin wrapper that delegates to the new implementation with
> RTE_ETH_NAME_MAX_LEN. The versioned symbol will be removed in 26.11.
> 
> Update all in-tree callers to pass sizeof(name) as the new parameter.
> 
> Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>

with notes below fixed

Reviewed-by: Andrew Rybchenko <andrew.rybchenko at oktetlabs.ru>

> diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
> index 2edc7a362e..586a56bd46 100644
> --- a/lib/ethdev/rte_ethdev.c
> +++ b/lib/ethdev/rte_ethdev.c
> @@ -721,12 +721,9 @@ rte_eth_dev_count_total(void)
>   	return count;
>   }
>   
> -RTE_EXPORT_SYMBOL(rte_eth_dev_get_name_by_port)
> -int
> -rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
> +static int
> +eth_dev_get_name_by_port(uint16_t port_id, char *name, size_t size)
>   {
> -	char *tmp;
> -
>   	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>   
>   	if (name == NULL) {
> @@ -735,19 +732,46 @@ rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
>   		return -EINVAL;
>   	}
>   
> +	if (size == 0) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +			"Cannot get ethdev port %u name with zero-size buffer", port_id);
> +		return -EINVAL;
> +	}
> +
>   	rte_spinlock_lock(rte_mcfg_ethdev_get_lock());
> -	/* shouldn't check 'rte_eth_devices[i].data',
> -	 * because it might be overwritten by VDEV PMD */
> -	tmp = eth_dev_shared_data->data[port_id].name;
> +	/*
> +	 * Use the shared data name rather than rte_eth_devices[].data->name
> +	 * because VDEV PMDs may overwrite the per-process data pointer.
> +	 */
> +	size_t n = strlcpy(name, eth_dev_shared_data->data[port_id].name, size);

As far as I know typically variable declaration and code are not mixed
in DPDK.

>   	rte_spinlock_unlock(rte_mcfg_ethdev_get_lock());
>   
> -	strcpy(name, tmp);
> +	if (n >= size) {
> +		RTE_ETHDEV_LOG_LINE(ERR,
> +				    "ethdev port %u name exceeds buffer size %zu",
> +				    port_id, size);
> +		return -ERANGE;
> +	}
>   
>   	rte_ethdev_trace_get_name_by_port(port_id, name);
>   
>   	return 0;
>   }

[...]

> diff --git a/lib/pdump/rte_pdump.c b/lib/pdump/rte_pdump.c
> index ac94efe7ff..57c81d4322 100644
> --- a/lib/pdump/rte_pdump.c
> +++ b/lib/pdump/rte_pdump.c
> @@ -736,7 +736,7 @@ pdump_validate_port(uint16_t port, char *name)
>   		return -1;
>   	}
>   
> -	ret = rte_eth_dev_get_name_by_port(port, name);
> +	ret = rte_eth_dev_get_name_by_port(port, name, sizeof(name));

It is definitely a bug here since name is a pointer.

>   	if (ret < 0) {
>   		PDUMP_LOG_LINE(ERR, "port %u to name mapping failed",
>   			  port);



More information about the dev mailing list