From d73922e4074982746e888e571f1a38660c927752 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 5 Nov 2025 17:34:22 -0800
Subject: [PATCH] Validate SPI read command in the Nintendo Switch HIDAPI
driver
(cherry picked from commit c94da8977d49c71c074037201e18edc97b1a8f7f)
---
src/joystick/hidapi/SDL_hidapi_switch.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c
index 0ad5de6da66c2..8585b2847a484 100644
--- a/src/joystick/hidapi/SDL_hidapi_switch.c
+++ b/src/joystick/hidapi/SDL_hidapi_switch.c
@@ -389,7 +389,7 @@ static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int siz
#endif // SWITCH_SYNCHRONOUS_WRITES
}
-static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID)
+static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID, const Uint8 *pBuf, Uint8 ucLen)
{
// Average response time for messages is ~30ms
Uint64 endTicks = SDL_GetTicks() + 100;
@@ -399,9 +399,17 @@ static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Conte
if (nRead > 0) {
if (ctx->m_rgucReadBuffer[0] == k_eSwitchInputReportIDs_SubcommandReply) {
SwitchSubcommandInputPacket_t *reply = (SwitchSubcommandInputPacket_t *)&ctx->m_rgucReadBuffer[1];
- if (reply->ucSubcommandID == expectedID && (reply->ucSubcommandAck & 0x80)) {
- return reply;
+ if (reply->ucSubcommandID != expectedID || !(reply->ucSubcommandAck & 0x80)) {
+ continue;
}
+ if (reply->ucSubcommandID == k_eSwitchSubcommandIDs_SPIFlashRead) {
+ SDL_assert(ucLen == sizeof(reply->spiReadData.opData));
+ if (SDL_memcmp(&reply->spiReadData.opData, pBuf, ucLen) != 0) {
+ // This was a reply for another SPI read command
+ continue;
+ }
+ }
+ return reply;
}
} else {
SDL_Delay(1);
@@ -488,7 +496,7 @@ static bool WriteSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs
continue;
}
- reply = ReadSubcommandReply(ctx, ucCommandID);
+ reply = ReadSubcommandReply(ctx, ucCommandID, pBuf, ucLen);
}
if (ppReply) {