Skip to content

Commit d53e4aa

Browse files
committed
dpll: fix device-id-get and pin-id-get to return errors properly
JIRA: https://issues.redhat.com/browse/RHEL-126529 Upstream commit(s): commit 36fedc4 Author: Petr Oros <poros@redhat.com> Date: Fri Oct 24 21:07:33 2025 +0200 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: 9d71b54 ("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> Signed-off-by: Petr Oros <poros@redhat.com>
1 parent eb88b37 commit d53e4aa

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

drivers/dpll/dpll_netlink.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,16 +1559,18 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
15591559
return -EMSGSIZE;
15601560
}
15611561
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;
15721574
}
15731575
genlmsg_end(msg, hdr);
15741576

@@ -1735,12 +1737,14 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
17351737
}
17361738

17371739
dpll = dpll_device_find_from_nlattr(info);
1738-
if (!IS_ERR(dpll)) {
1739-
ret = dpll_msg_add_dev_handle(msg, dpll);
1740-
if (ret) {
1741-
nlmsg_free(msg);
1742-
return ret;
1743-
}
1740+
if (IS_ERR(dpll)) {
1741+
nlmsg_free(msg);
1742+
return PTR_ERR(dpll);
1743+
}
1744+
ret = dpll_msg_add_dev_handle(msg, dpll);
1745+
if (ret) {
1746+
nlmsg_free(msg);
1747+
return ret;
17441748
}
17451749
genlmsg_end(msg, hdr);
17461750

0 commit comments

Comments
 (0)