[PATCH v6 04/15] net: qrtr: use only low 16 bits of node/port in 32-bit systems
From: Juha-Matti Tilli <hidden>
Date: 2026-09-01 13:21:03
Also in:
linux-arm-msm, lkml
Subsystem:
networking [general], qualcomm ipc router (qrtr) driver, the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Manivannan Sadhasivam, Linus Torvalds
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 <redacted> --- 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