[PATCH v6 04/15] net: qrtr: use only low 16 bits of node/port in 32-bit systems

From: Juha-Matti Tilli

Date: Tue Sep 01 2026 - 09:49:19 EST


The node id is generally a single fixed value hardcoded into device
firmware. If it happens to be larger than 16 bits on a 32-bit system,
using the value modulo 65536 is enough. It is not necessary to check it
for being in range. Evidence of this is a prior implementation that fit
node_id (u32) and port (u32) into unsigned long in 32-bit systems, in a
manner that completely discarded all bits of node_id. Do the same for
port: don't check for it being in range.

This arguably creates a bug where node_id could clash with a node_id
that has the same low-order 16 bits, or a port could clash with a port
that has the same low-order 16 bits. But it's probably better than
discarding all bits of node and using only bits from port. It's probably
also better than failing if either node or port is out-of-range.

Signed-off-by: Juha-Matti Tilli <juha-matti.tilli@xxxxxx>
---
net/qrtr/af_qrtr.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
index f2edbd2e9dea9..b2cb05f2480e0 100644
--- a/net/qrtr/af_qrtr.c
+++ b/net/qrtr/af_qrtr.c
@@ -252,9 +252,9 @@ static int qrtr_tx_resume(struct qrtr_node *node, struct sk_buff *skb)
struct qrtr_tx_flow *flow;
unsigned long key = 0;

- if (remote_node > QRTR_INDEX_HALF_UNSIGNED_MAX ||
- remote_port > QRTR_INDEX_HALF_UNSIGNED_MAX)
- return -EINVAL;
+ /* Don't check node/port for the valid range, use only low
+ * 16 bits on 32-bit architectures.
+ */

key = ((unsigned long)(remote_node) << QRTR_INDEX_HALF_BITS) |
((unsigned long)(remote_port) & QRTR_INDEX_HALF_UNSIGNED_MAX);
@@ -295,11 +295,9 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port,
int confirm_rx = 0;
int ret;

- if (dest_node < QRTR_INDEX_HALF_SIGNED_MIN ||
- dest_node > QRTR_INDEX_HALF_SIGNED_MAX ||
- dest_port < QRTR_INDEX_HALF_SIGNED_MIN ||
- dest_port > QRTR_INDEX_HALF_SIGNED_MAX)
- return -EINVAL;
+ /* Don't check node/port for the valid range, use only low
+ * 16 bits on 32-bit architectures.
+ */

key = ((unsigned long)(dest_node) << QRTR_INDEX_HALF_BITS) |
((unsigned long)(dest_port) & QRTR_INDEX_HALF_UNSIGNED_MAX);
@@ -369,11 +367,9 @@ static int qrtr_tx_flow_failed(struct qrtr_node *node, int dest_node,
unsigned long key = 0;
struct qrtr_tx_flow *flow;

- if (dest_node < QRTR_INDEX_HALF_SIGNED_MIN ||
- dest_node > QRTR_INDEX_HALF_SIGNED_MAX ||
- dest_port < QRTR_INDEX_HALF_SIGNED_MIN ||
- dest_port > QRTR_INDEX_HALF_SIGNED_MAX)
- return -EINVAL;
+ /* Don't check node/port for the valid range, use only low
+ * 16 bits on 32-bit architectures.
+ */

key = ((unsigned long)(dest_node) << QRTR_INDEX_HALF_BITS) |
((unsigned long)(dest_port) & QRTR_INDEX_HALF_UNSIGNED_MAX);
--
2.34.1