CVE-2026-46026
Description
In the Linux kernel, the following vulnerability has been resolved:
net: qrtr: ns: Limit the maximum number of lookups
Current code does no bound checking on the number of lookups a client can perform. Though the code restricts the lookups to local clients, there is still a possibility of a malicious local client sending a flood of NEW_LOOKUP messages over the same socket.
Fix this issue by limiting the maximum number of lookups to 64 globally. Since the nameserver allows only atmost one local observer, this global lookup count will ensure that the lookups stay within the limit.
Note that, limit of 64 is chosen based on the current platform requirements. If requirement changes in the future, this limit can be increased.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A local attacker can flood the QRTR nameserver with lookup requests, exhausting resources; fixed by limiting lookups to 64 globally.
Vulnerability
In the Linux kernel's net/qrtr/ns.c, the QRTR nameserver (ns) does not bound the number of lookups a client can perform via NEW_LOOKUP messages. While lookups are restricted to local clients, a malicious local client can send a flood of such messages over the same socket, potentially exhausting kernel resources. This issue affects all kernel versions prior to the commit that introduces a global limit of 64 lookups [1].
Exploitation
An attacker with local access to the system can open a QRTR socket and repeatedly send NEW_LOOKUP messages to the nameserver. No special privileges beyond local user access are required, as the QRTR protocol is accessible to unprivileged local processes. The attacker can continue sending lookups until the nameserver's resources are exhausted, causing a denial-of-service condition for other legitimate local clients [1].
Impact
Successful exploitation leads to resource exhaustion on the QRTR nameserver, preventing it from processing legitimate lookup requests from other local clients. This results in a denial of service (DoS) for QRTR-based communication on the affected system. The impact is limited to local availability; no data confidentiality or integrity is compromised [1].
Mitigation
The fix is implemented in Linux kernel commit 0dbec101a7076e9b1e4bd1876f7cf07c56ff4ce3, which limits the maximum number of lookups to 64 globally. This commit is included in stable kernel updates released after 2026-05-27. Users should update to a kernel version containing this commit. No workaround is available for unpatched systems. The vulnerability is not listed on CISA's Known Exploited Vulnerabilities (KEV) catalog [1].
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
100dbec101a707net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index eeac701831827b..b83f1aa2a0c8a3 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -441,6 +447,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -558,6 +565,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -566,6 +578,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -606,6 +619,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
2b930bc77e00net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +12 −3
net/qrtr/ns.c+12 −3 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index e93a2e0f233e0a..3d1172c1b9c5ff 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -71,10 +72,11 @@ struct qrtr_node { u32 server_count; }; -/* Max server limit is chosen based on the current platform requirements. If the - * requirement changes in the future, this value can be increased. +/* Max server, lookup limits are chosen based on the current platform requirements. + * If the requirement changes in the future, these values can be increased. */ #define QRTR_NS_MAX_SERVERS 256 +#define QRTR_NS_MAX_LOOKUPS 64 static struct qrtr_node *node_get(unsigned int node_id) { @@ -434,6 +436,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -551,6 +554,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc_obj(*lookup); if (!lookup) return -ENOMEM; @@ -559,6 +567,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -599,6 +608,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
20855cef7e65net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 8a5352f6cf8b68..b6da0e7d72a5db 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -444,6 +450,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -561,6 +568,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -569,6 +581,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -609,6 +622,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
5640227d9a21net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +12 −3
net/qrtr/ns.c+12 −3 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 63cb5861d87a13..5b08d4d4840a3c 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; int local_node; @@ -70,10 +71,11 @@ struct qrtr_node { u32 server_count; }; -/* Max server limit is chosen based on the current platform requirements. If the - * requirement changes in the future, this value can be increased. +/* Max server, lookup limits are chosen based on the current platform requirements. + * If the requirement changes in the future, these values can be increased. */ #define QRTR_NS_MAX_SERVERS 256 +#define QRTR_NS_MAX_LOOKUPS 64 static struct qrtr_node *node_get(unsigned int node_id) { @@ -433,6 +435,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -550,6 +553,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc_obj(*lookup); if (!lookup) return -ENOMEM; @@ -558,6 +566,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -598,6 +607,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
76adf8f69b0bnet: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 8a5352f6cf8b68..b6da0e7d72a5db 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -444,6 +450,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -561,6 +568,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -569,6 +581,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -609,6 +622,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
76adf8f69b0bnet: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 8a5352f6cf8b68..b6da0e7d72a5db 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -444,6 +450,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -561,6 +568,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -569,6 +581,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -609,6 +622,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
2b930bc77e00net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +12 −3
net/qrtr/ns.c+12 −3 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index e93a2e0f233e0a..3d1172c1b9c5ff 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -71,10 +72,11 @@ struct qrtr_node { u32 server_count; }; -/* Max server limit is chosen based on the current platform requirements. If the - * requirement changes in the future, this value can be increased. +/* Max server, lookup limits are chosen based on the current platform requirements. + * If the requirement changes in the future, these values can be increased. */ #define QRTR_NS_MAX_SERVERS 256 +#define QRTR_NS_MAX_LOOKUPS 64 static struct qrtr_node *node_get(unsigned int node_id) { @@ -434,6 +436,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -551,6 +554,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc_obj(*lookup); if (!lookup) return -ENOMEM; @@ -559,6 +567,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -599,6 +608,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
0dbec101a707net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index eeac701831827b..b83f1aa2a0c8a3 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -441,6 +447,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -558,6 +565,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -566,6 +578,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -606,6 +619,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
20855cef7e65net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +14 −1
net/qrtr/ns.c+14 −1 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 8a5352f6cf8b68..b6da0e7d72a5db 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; void (*saved_data_ready)(struct sock *sk); @@ -76,6 +77,11 @@ struct qrtr_node { */ #define QRTR_NS_MAX_SERVERS 256 +/* Max lookup limit is chosen based on the current platform requirements. If the + * requirement changes in the future, this value can be increased. + */ +#define QRTR_NS_MAX_LOOKUPS 64 + static struct qrtr_node *node_get(unsigned int node_id) { struct qrtr_node *node; @@ -444,6 +450,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -561,6 +568,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); if (!lookup) return -ENOMEM; @@ -569,6 +581,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -609,6 +622,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
5640227d9a21net: qrtr: ns: Limit the maximum number of lookups
1 file changed · +12 −3
net/qrtr/ns.c+12 −3 modifieddiff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index 63cb5861d87a13..5b08d4d4840a3c 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -22,6 +22,7 @@ static struct { struct socket *sock; struct sockaddr_qrtr bcast_sq; struct list_head lookups; + u32 lookup_count; struct workqueue_struct *workqueue; struct work_struct work; int local_node; @@ -70,10 +71,11 @@ struct qrtr_node { u32 server_count; }; -/* Max server limit is chosen based on the current platform requirements. If the - * requirement changes in the future, this value can be increased. +/* Max server, lookup limits are chosen based on the current platform requirements. + * If the requirement changes in the future, these values can be increased. */ #define QRTR_NS_MAX_SERVERS 256 +#define QRTR_NS_MAX_LOOKUPS 64 static struct qrtr_node *node_get(unsigned int node_id) { @@ -433,6 +435,7 @@ static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } /* Remove the server belonging to this port but don't broadcast @@ -550,6 +553,11 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; + if (qrtr_ns.lookup_count >= QRTR_NS_MAX_LOOKUPS) { + pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n"); + return -ENOSPC; + } + lookup = kzalloc_obj(*lookup); if (!lookup) return -ENOMEM; @@ -558,6 +566,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, lookup->service = service; lookup->instance = instance; list_add_tail(&lookup->li, &qrtr_ns.lookups); + qrtr_ns.lookup_count++; memset(&filter, 0, sizeof(filter)); filter.service = service; @@ -598,6 +607,7 @@ static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, list_del(&lookup->li); kfree(lookup); + qrtr_ns.lookup_count--; } } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing bound check on the number of lookups a client can register allows unlimited memory allocation via NEW_LOOKUP message flood."
Attack vector
A malicious local client can send a flood of `NEW_LOOKUP` messages over the same QRTR socket. The nameserver restricts lookups to local clients (checking `from->sq_node != qrtr_ns.local_node`), but performs no bound checking on how many lookups a client can register [patch_id=2660329]. By repeatedly sending `NEW_LOOKUP` messages, the attacker can exhaust kernel memory by causing unlimited allocations of `struct qrtr_lookup` entries, leading to a denial-of-service condition. The attack requires only local unprivileged access to a QRTR socket.
Affected code
The vulnerability resides in `net/qrtr/ns.c` in the QRTR nameserver implementation. The affected functions are `ctrl_cmd_new_lookup()` (which handles `NEW_LOOKUP` messages) and the cleanup paths in `ctrl_cmd_del_lookup()` and `ctrl_cmd_del_client()`. Prior to the patch, none of these functions tracked or bounded the number of outstanding lookup entries on the `qrtr_ns.lookups` list [patch_id=2660329].
What the fix does
The patch introduces a global `lookup_count` field in the `qrtr_ns` structure and a `QRTR_NS_MAX_LOOKUPS` constant set to 64 [patch_id=2660329]. In `ctrl_cmd_new_lookup()`, a new bounds check rejects `NEW_LOOKUP` messages when `lookup_count >= QRTR_NS_MAX_LOOKUPS`, returning `-ENOSPC`. The count is incremented after a successful lookup allocation and decremented in both `ctrl_cmd_del_lookup()` and `ctrl_cmd_del_client()` when lookups are freed. This ensures the total number of concurrent lookups cannot exceed 64, preventing memory exhaustion from a flood of lookup requests.
Preconditions
- authAttacker must have local access to the system and be able to open a QRTR socket
- configThe QRTR nameserver must be running (kernel-based nameservice)
- inputAttacker must send NEW_LOOKUP messages from a local node (from->sq_node == qrtr_ns.local_node)
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/0dbec101a7076e9b1e4bd1876f7cf07c56ff4ce3nvd
- git.kernel.org/stable/c/20855cef7e659ef84ac73251256fa530819b2346nvd
- git.kernel.org/stable/c/2b930bc77e00cb27e1d6e1d497b3b596283465efnvd
- git.kernel.org/stable/c/5640227d9a21c6a8be249a10677b832e7f40dc55nvd
- git.kernel.org/stable/c/76adf8f69b0bb3ab20be7c58f5d555027332d113nvd
News mentions
0No linked articles in our index yet.