Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dpll: fix device-id-get and pin-id-get to return errors properly

The device-id-get and pin-id-get handlers were ignoring errors from
the find functions and sending empty replies instead of returning
error codes to userspace.

When dpll_device_find_from_nlattr() or dpll_pin_find_from_nlattr()
returned an error (e.g., -EINVAL for "multiple matches" or -ENODEV
for "not found"), the handlers checked `if (!IS_ERR(ptr))` and
skipped adding the device/pin handle to the message, but then still
sent the empty message as a successful reply.

This caused userspace tools to receive empty responses with id=0
instead of proper netlink errors with extack messages like
"multiple matches".

The bug is visible via strace, which shows the kernel sending TWO
netlink messages in response to a single request:

1. Empty reply (20 bytes, just header, no attributes):
recvfrom(3, [{nlmsg_len=20, nlmsg_type=dpll, nlmsg_flags=0, ...},
{cmd=0x7, version=1}], ...)

2. NLMSG_ERROR ACK with extack (because of NLM_F_ACK flag):
recvfrom(3, [{nlmsg_len=60, nlmsg_type=NLMSG_ERROR,
nlmsg_flags=NLM_F_CAPPED|NLM_F_ACK_TLVS, ...},
[{error=0, msg={...}},
[{nla_type=NLMSGERR_ATTR_MSG}, "multiple matches"]]], ...)

The C YNL library parses the first message, sees an empty response,
and creates a result object with calloc() which zero-initializes all
fields, resulting in id=0.

The Python YNL library parses both messages and displays the extack
from the second NLMSG_ERROR message.

Fix by checking `if (IS_ERR(ptr))` first and returning the error
code immediately, so that netlink properly sends only NLMSG_ERROR with
the extack message to userspace. After this fix, both C and Python
YNL tools receive only the NLMSG_ERROR and behave consistently.

This affects:
- DPLL_CMD_DEVICE_ID_GET: now properly returns error when multiple
devices match the criteria (e.g., same module-name + clock-id)
- DPLL_CMD_PIN_ID_GET: now properly returns error when multiple pins
match the criteria (e.g., same module-name)

Before fix:
$ dpll pin id-get module-name ice
0 (wrong - should be error, there are 17 pins with module-name "ice")

After fix:
$ dpll pin id-get module-name ice
Error: multiple matches
(correct - kernel reports the ambiguity via extack)

Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
Signed-off-by: Petr Oros <poros@redhat.com>
Reviewed-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20251024190733.364101-1-poros@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Petr Oros and committed by
Jakub Kicinski
36fedc44 210b35d6

+20 -16
+20 -16
drivers/dpll/dpll_netlink.c
··· 1559 1559 return -EMSGSIZE; 1560 1560 } 1561 1561 pin = dpll_pin_find_from_nlattr(info); 1562 - if (!IS_ERR(pin)) { 1563 - if (!dpll_pin_available(pin)) { 1564 - nlmsg_free(msg); 1565 - return -ENODEV; 1566 - } 1567 - ret = dpll_msg_add_pin_handle(msg, pin); 1568 - if (ret) { 1569 - nlmsg_free(msg); 1570 - return ret; 1571 - } 1562 + if (IS_ERR(pin)) { 1563 + nlmsg_free(msg); 1564 + return PTR_ERR(pin); 1565 + } 1566 + if (!dpll_pin_available(pin)) { 1567 + nlmsg_free(msg); 1568 + return -ENODEV; 1569 + } 1570 + ret = dpll_msg_add_pin_handle(msg, pin); 1571 + if (ret) { 1572 + nlmsg_free(msg); 1573 + return ret; 1572 1574 } 1573 1575 genlmsg_end(msg, hdr); 1574 1576 ··· 1737 1735 } 1738 1736 1739 1737 dpll = dpll_device_find_from_nlattr(info); 1740 - if (!IS_ERR(dpll)) { 1741 - ret = dpll_msg_add_dev_handle(msg, dpll); 1742 - if (ret) { 1743 - nlmsg_free(msg); 1744 - return ret; 1745 - } 1738 + if (IS_ERR(dpll)) { 1739 + nlmsg_free(msg); 1740 + return PTR_ERR(dpll); 1741 + } 1742 + ret = dpll_msg_add_dev_handle(msg, dpll); 1743 + if (ret) { 1744 + nlmsg_free(msg); 1745 + return ret; 1746 1746 } 1747 1747 genlmsg_end(msg, hdr); 1748 1748