[RFC] ethdev: add buffer size parameter to rte_eth_dev_get_name_by_port()
Andrew Rybchenko
andrew.rybchenko at oktetlabs.ru
Thu Apr 9 11:05:35 CEST 2026
On 4/9/26 10:58 AM, Bruce Richardson wrote:
> On Thu, Apr 09, 2026 at 09:59:04AM +0300, Andrew Rybchenko wrote:
>> 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.
>>
>
> AFAIK That used to be the case because early versions of DPDK targetting a
> very early C standard. More recently, we've started allowing this sort of
> use, which makes the code more readable IMHO and easier to work with too as
> commenting out blocks when debugging leads to fewer unused variable warnings.
>
> /Bruce
Bruce, thanks for the clarification.
More information about the dev
mailing list