From d0d1414836e340361c50db1d9f8d9e0672b187e1 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 16 Dec 2024 18:02:37 -0500
Subject: [PATCH] messagebox: Copy title and message up front, to protect
SDL_GetError() strings.
It's possible (likely!) someone could just pass a pointer returned by
SDL_GetError for one of these strings, but the message box code has to do a
ton of complicated stuff that might _also_ call SDL_SetError, so you could
end up with the string having different contents by the time you display it.
Just make a copy of the strings unconditionally at the start, so they're safe
no matter where they came from.
Fixes #10932.
---
src/video/SDL_video.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index b62d5c53a091b..9760a4426a1e6 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -5455,6 +5455,30 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
return SDL_SetError("Invalid number of buttons");
}
+ // in case either the title or message was a pointer from SDL_GetError(), make a copy
+ // now, as we'll likely overwrite error state in here.
+ bool titleisstack = false, msgisstack = false;
+ char *titlecpy = NULL;
+ char *msgcpy = NULL;
+ if (messageboxdata->title) {
+ const size_t slen = SDL_strlen(messageboxdata->title) + 1;
+ titlecpy = SDL_small_alloc(char, slen, &titleisstack);
+ if (!titlecpy) {
+ return false;
+ }
+ SDL_strlcpy(titlecpy, messageboxdata->title, slen);
+ }
+
+ if (messageboxdata->message) {
+ const size_t slen = SDL_strlen(messageboxdata->message) + 1;
+ msgcpy = SDL_small_alloc(char, slen, &msgisstack);
+ if (!msgcpy) {
+ SDL_small_free(titlecpy, titleisstack);
+ return false;
+ }
+ SDL_strlcpy(msgcpy, messageboxdata->message, slen);
+ }
+
(void)SDL_AtomicIncRef(&SDL_messagebox_count);
current_window = SDL_GetKeyboardFocus();
@@ -5469,9 +5493,11 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
}
SDL_memcpy(&mbdata, messageboxdata, sizeof(*messageboxdata));
+ mbdata.title = titlecpy;
if (!mbdata.title) {
mbdata.title = "";
}
+ mbdata.message = msgcpy;
if (!mbdata.message) {
mbdata.message = "";
}
@@ -5534,6 +5560,9 @@ bool SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
SDL_UpdateRelativeMouseMode();
SDL_UpdateMouseCapture(false);
+ SDL_small_free(msgcpy, msgisstack);
+ SDL_small_free(titlecpy, titleisstack);
+
return result;
}