From: Kenneth Kabogo <kennethkabogo2@gmail.com>
To: Alex Elder <elder@kernel.org>
Cc: netdev@vger.kernel.org, Andrew Lunn <andrew+netdev@lunn.ch>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
linux-kernel@vger.kernel.org,
Kenneth Kabogo <kennethkabogo2@gmail.com>
Subject: [PATCH] net: ipa: validate QMI sender for modem-only server requests
Date: Thu, 10 Sep 2026 21:17:37 +0300 [thread overview]
Message-ID: <20260910181737.55570-1-kennethkabogo2@gmail.com> (raw)
The IPA driver's QMI server has two request handlers,
ipa_server_indication_register() and ipa_server_driver_init_complete(),
that are only ever legitimately sent by the paired modem. Neither checks
the sender address (struct sockaddr_qrtr *sq) against ipa_qmi->modem_sq,
which the driver already caches when the modem's QMI service appears in
ipa_client_new_server().
Both handlers set a readiness flag (indication_requested, uc_ready) and
call ipa_qmi_ready(), which starts the modem netdev via ipa_modem_start()
-> register_netdev() once both flags are set. A local process able to
send QMI messages on the qrtr socket, other than the modem, can spoof
both signals and drive ipa_qmi_ready() to completion before the modem
has confirmed its endpoint configuration, bringing up the modem network
interface out of sequence with real modem readiness. The realistic
outcome is a data-path stall requiring a subsystem restart to recover.
It is not a memory-safety issue.
On Android the qrtr socket is not reachable by untrusted apps (SELinux
neverallow on qipcrtr_socket), so this is gated to privileged system
components, hence the low severity. It is still a missing trust check on
a cross-processor control interface.
Reject server requests whose sender does not match the cached modem
address. modem_sq is populated before the modem sends these requests and
is zeroed in ipa_server_bye(); a zeroed modem_sq does not match any real
sender's address, so requests arriving during the teardown window are
rejected without a separate check.
Found by code inspection; no runtime proof-of-concept.
Signed-off-by: Kenneth Kabogo <kennethkabogo2@gmail.com>
---
Build-tested only (arm64 allmodconfig); I don't have IPA hardware to
test at runtime.
This assumes modem_sq is always populated (via ipa_client_new_server(),
the NEW_SERVER path) before the modem sends INDICATION_REGISTER /
DRIVER_INIT_COMPLETE. That ordering looks right from the code, but QMI
delivery is asynchronous - if the modem's request can legitimately
arrive before we've processed its NEW_SERVER event, this would wrongly
drop it, and the check should instead only be enforced when modem_sq is
non-zero. Happy to respin that way if you prefer.
drivers/net/ipa/ipa_qmi.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/net/ipa/ipa_qmi.c b/drivers/net/ipa/ipa_qmi.c
index d771f3a71..a7cc98b27 100644
--- a/drivers/net/ipa/ipa_qmi.c
+++ b/drivers/net/ipa/ipa_qmi.c
@@ -168,6 +168,14 @@ static const struct qmi_ops ipa_server_ops = {
.bye = ipa_server_bye,
};
+/* True if a QMI request arrived from the modem we are paired with */
+static bool ipa_server_from_modem(const struct ipa_qmi *ipa_qmi,
+ const struct sockaddr_qrtr *sq)
+{
+ return sq->sq_node == ipa_qmi->modem_sq.sq_node &&
+ sq->sq_port == ipa_qmi->modem_sq.sq_port;
+}
+
/* Callback function to handle an INDICATION_REGISTER request message from the
* modem. This informs the AP that the modem is now ready to receive the
* INIT_COMPLETE indication message.
@@ -185,6 +193,13 @@ static void ipa_server_indication_register(struct qmi_handle *qmi,
ipa_qmi = container_of(qmi, struct ipa_qmi, server_handle);
ipa = container_of(ipa_qmi, struct ipa, qmi);
+ if (!ipa_server_from_modem(ipa_qmi, sq)) {
+ dev_warn_ratelimited(ipa->dev,
+ "ignoring QMI request from non-modem sender %u:%u\n",
+ sq->sq_node, sq->sq_port);
+ return;
+ }
+
rsp.rsp.result = QMI_RESULT_SUCCESS_V01;
rsp.rsp.error = QMI_ERR_NONE_V01;
@@ -214,6 +229,13 @@ static void ipa_server_driver_init_complete(struct qmi_handle *qmi,
ipa_qmi = container_of(qmi, struct ipa_qmi, server_handle);
ipa = container_of(ipa_qmi, struct ipa, qmi);
+ if (!ipa_server_from_modem(ipa_qmi, sq)) {
+ dev_warn_ratelimited(ipa->dev,
+ "ignoring QMI request from non-modem sender %u:%u\n",
+ sq->sq_node, sq->sq_port);
+ return;
+ }
+
rsp.rsp.result = QMI_RESULT_SUCCESS_V01;
rsp.rsp.error = QMI_ERR_NONE_V01;
--
2.50.1 (Apple Git-155)
next reply other threads:[~2026-09-10 18:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-10 18:17 Kenneth Kabogo [this message]
2026-09-11 18:45 ` netdev-bot+sashiko
2026-09-11 19:17 ` Kenneth Kabogo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260910181737.55570-1-kennethkabogo2@gmail.com \
--to=kennethkabogo2@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=elder@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®