Prevent crashes if freed objects are passed to SDL API functions

Instead of using the magic tag in the object, we'll actually keep track of valid objects

Fixes https://github.com/libsdl-org/SDL/issues/9869
Fixes https://github.com/libsdl-org/SDL/issues/9235
This commit is contained in:
Sam Lantinga
2024-06-03 04:09:28 -07:00
parent 57a15933cd
commit b0e93e4e63
28 changed files with 191 additions and 126 deletions

View File

@@ -37,7 +37,6 @@ typedef struct SDL_WindowData SDL_WindowData;
/* Define the SDL window structure, corresponding to toplevel windows */
struct SDL_Window
{
const void *magic;
SDL_WindowID id;
char *title;
SDL_Surface *icon;
@@ -371,7 +370,6 @@ struct SDL_VideoDevice
SDL_Rect desktop_bounds;
SDL_Window *windows;
SDL_Window *grabbed_window;
Uint8 window_magic;
Uint32 clipboard_sequence;
SDL_ClipboardDataCallback clipboard_callback;
SDL_ClipboardCleanupCallback clipboard_cleanup;

View File

@@ -141,7 +141,7 @@ static VideoBootStrap *bootstrap[] = {
SDL_UninitializedVideo(); \
return retval; \
} \
if (!(window) || (window)->magic != &_this->window_magic) { \
if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW)) { \
SDL_SetError("Invalid window"); \
return retval; \
}
@@ -2118,7 +2118,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
}
}
if ((flags & SDL_WINDOW_MODAL) && (!parent || parent->magic != &_this->window_magic)) {
if ((flags & SDL_WINDOW_MODAL) && !SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
SDL_SetError("Modal windows must specify a parent window");
return NULL;
}
@@ -2130,7 +2130,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
}
/* Tooltip and popup menu window must specify a parent window */
if (!parent || parent->magic != &_this->window_magic) {
if (!SDL_ObjectValid(parent, SDL_OBJECT_TYPE_WINDOW)) {
SDL_SetError("Tooltip and popup menu windows must specify a parent window");
return NULL;
}
@@ -2236,7 +2236,7 @@ SDL_Window *SDL_CreateWindowWithProperties(SDL_PropertiesID props)
if (!window) {
return NULL;
}
window->magic = &_this->window_magic;
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_TRUE);
window->id = SDL_GetNextObjectID();
window->floating.x = window->windowed.x = window->x = x;
window->floating.y = window->windowed.y = window->y = y;
@@ -3920,7 +3920,7 @@ void SDL_DestroyWindow(SDL_Window *window)
}
/* Now invalidate magic */
window->magic = NULL;
SDL_SetObjectValid(window, SDL_OBJECT_TYPE_WINDOW, SDL_FALSE);
/* Free memory associated with the window */
SDL_free(window->title);

View File

@@ -1252,7 +1252,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
} else if (window->max_aspect && aspect > window->max_aspect) {
wind->requested.pixel_width = SDL_roundf((float)wind->requested.pixel_height * window->max_aspect);
}
wind->requested.logical_width = PixelToPoint(window, wind->requested.pixel_width);
wind->requested.logical_height = PixelToPoint(window, wind->requested.pixel_height);
}
@@ -1854,7 +1854,7 @@ static void Wayland_ReleasePopup(SDL_VideoDevice *_this, SDL_Window *popup)
SDL_WindowData *popupdata;
/* Basic sanity checks to weed out the weird popup closures */
if (!popup || popup->magic != &_this->window_magic) {
if (!SDL_ObjectValid(popup, SDL_OBJECT_TYPE_WINDOW)) {
return;
}
popupdata = popup->driverdata;

View File

@@ -39,7 +39,6 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../core/linux/SDL_system_theme.h"
#include "../../SDL_utils_c.h"
#include "../SDL_sysvideo.h"
#include <stdio.h>

View File

@@ -28,7 +28,6 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_events_c.h"
#include "../../core/unix/SDL_appid.h"
#include "../../SDL_utils_c.h"
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"