Skip to content

Commit 8766d60

Browse files
committed
[Video/KMSDRM] Fix potetial access to freed structure and complete errorchecks.
1 parent b06ef3a commit 8766d60

File tree

1 file changed

+53
-35
lines changed

1 file changed

+53
-35
lines changed

src/video/kmsdrm/SDL_kmsdrmvideo.c

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ setup_plane(_THIS, struct plane **plane, uint32_t plane_type)
605605

606606
cleanup:
607607

608-
if (ret != 0) {
608+
if (ret) {
609609
if (*plane) {
610610
SDL_free(*plane);
611611
*plane = NULL;
@@ -1221,17 +1221,24 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
12211221
viddata->drm_fd = -1;
12221222

12231223
cleanup:
1224-
// TODO Use it as a list to see if everything we use here is freed.
12251224
if (encoder)
12261225
KMSDRM_drmModeFreeEncoder(encoder);
12271226
if (resources)
12281227
KMSDRM_drmModeFreeResources(resources);
1229-
if (ret != 0) {
1228+
if (ret) {
12301229
/* Error (complete) cleanup */
12311230
if (dispdata->connector->connector) {
12321231
KMSDRM_drmModeFreeConnector(dispdata->connector->connector);
12331232
dispdata->connector->connector = NULL;
12341233
}
1234+
if (dispdata->crtc->props_info) {
1235+
SDL_free(dispdata->crtc->props_info);
1236+
dispdata->crtc->props_info = NULL;
1237+
}
1238+
if (dispdata->connector->props_info) {
1239+
SDL_free(dispdata->connector->props_info);
1240+
dispdata->connector->props_info = NULL;
1241+
}
12351242
if (dispdata->crtc->crtc) {
12361243
KMSDRM_drmModeFreeCrtc(dispdata->crtc->crtc);
12371244
dispdata->crtc->crtc = NULL;
@@ -1240,7 +1247,6 @@ int KMSDRM_DisplayDataInit (_THIS, SDL_DisplayData *dispdata) {
12401247
close(viddata->drm_fd);
12411248
viddata->drm_fd = -1;
12421249
}
1243-
SDL_free(dispdata);
12441250
}
12451251

12461252
return ret;
@@ -1403,10 +1409,7 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
14031409

14041410
EGLContext egl_context;
14051411

1406-
/* Destroy the surfaces and buffers before creating the new ones. */
1407-
// TODO REENABLE THIS IF CGENIUS FAILS BECAUSE IT CREATES A NEW WINDOW
1408-
// W/O DESTRYING THE PREVIOUS ONE.
1409-
//KMSDRM_DestroySurfaces(_this, window);
1412+
int ret = 0;
14101413

14111414
if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) ||
14121415
((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)) {
@@ -1428,26 +1431,36 @@ KMSDRM_CreateSurfaces(_THIS, SDL_Window * window)
14281431
return SDL_SetError("Could not create GBM surface");
14291432
}
14301433

1431-
#if SDL_VIDEO_OPENGL_EGL //TODO Restore this lo LibraryLoad and Unload calls.
1434+
#if SDL_VIDEO_OPENGL_EGL
14321435
/* We can't get the EGL context yet because SDL_CreateRenderer has not been called,
14331436
but we need an EGL surface NOW, or GL won't be able to render into any surface
14341437
and we won't see the first frame. */
14351438
SDL_EGL_SetRequiredVisualId(_this, surface_fmt);
14361439
windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs);
14371440

14381441
if (windata->egl_surface == EGL_NO_SURFACE) {
1439-
return SDL_SetError("Could not create EGL window surface");
1442+
ret = SDL_SetError("Could not create EGL window surface");
1443+
goto cleanup;
14401444
}
14411445

14421446
/* Current context passing to EGL is now done here. If something fails,
14431447
go back to delayed SDL_EGL_MakeCurrent() call in SwapWindow. */
1444-
/* TODO Errorcheck on this (may lead to delayed call again...) */
14451448
egl_context = (EGLContext)SDL_GL_GetCurrentContext();
1446-
SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
1449+
ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context);
14471450

14481451
#endif
14491452

1450-
return 0;
1453+
cleanup:
1454+
1455+
if (ret) {
1456+
/* Error (complete) cleanup. */
1457+
if (windata->gs) {
1458+
KMSDRM_gbm_surface_destroy(windata->gs);
1459+
windata->gs = NULL;
1460+
}
1461+
}
1462+
1463+
return ret;
14511464
}
14521465

14531466
void
@@ -1464,13 +1477,12 @@ KMSDRM_DestroyWindow(_THIS, SDL_Window *window)
14641477
}
14651478

14661479
if (!is_vulkan) {
1467-
14681480
KMSDRM_DestroySurfaces(_this, window);
1469-
1481+
#if SDL_VIDEO_OPENGL_EGL
14701482
if (_this->egl_data) {
14711483
SDL_EGL_UnloadLibrary(_this);
14721484
}
1473-
1485+
#endif
14741486
if (dispdata->gbm_init) {
14751487
KMSDRM_DeinitMouse(_this);
14761488
KMSDRM_GBMDeinit(_this, dispdata);
@@ -1604,6 +1616,7 @@ KMSDRM_VideoInit(_THIS)
16041616
cleanup:
16051617

16061618
if (ret) {
1619+
/* Error (complete) cleanup */
16071620
if (dispdata->display_plane) {
16081621
SDL_free(dispdata->display_plane);
16091622
}
@@ -1613,6 +1626,8 @@ KMSDRM_VideoInit(_THIS)
16131626
if (dispdata->connector) {
16141627
SDL_free(dispdata->connector);
16151628
}
1629+
1630+
SDL_free(dispdata);
16161631
}
16171632

16181633
return ret;
@@ -1728,27 +1743,32 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
17281743
SDL_DisplayData *dispdata = display->driverdata;
17291744
SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */
17301745
NativeDisplayType egl_display;
1731-
17321746
float ratio;
1747+
int ret = 0;
17331748

17341749
if ( !(dispdata->gbm_init) && (!is_vulkan)) {
17351750
/* Reopen FD, create gbm dev, setup display plane, etc,.
17361751
but only when we come here for the first time,
17371752
and only if it's not a VK window. */
1738-
KMSDRM_GBMInit(_this, dispdata);
1753+
if ((ret = KMSDRM_GBMInit(_this, dispdata))) {
1754+
goto cleanup;
1755+
}
17391756

1757+
#if SDL_VIDEO_OPENGL_EGL
17401758
/* Manually load the EGL library. KMSDRM_EGL_LoadLibrary() has already
17411759
been called by SDL_CreateWindow() but we don't do anything there,
17421760
precisely to be able to load it here.
17431761
If we let SDL_CreateWindow() load the lib, it will be loaded
17441762
before we call KMSDRM_GBMInit(), causing GLES programs to fail. */
1745-
// TODO errorcheck the return value of this.
17461763
if (!_this->egl_data) {
17471764
egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev;
1748-
SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA);
1765+
if ((ret = SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA))) {
1766+
goto cleanup;
1767+
}
17491768
}
1769+
#endif
17501770

1751-
/* Can't init mouse stuff sooner cursor plane is not ready. */
1771+
/* Can't init mouse stuff sooner because cursor plane is not ready. */
17521772
KMSDRM_InitMouse(_this);
17531773

17541774
/* Since we take cursor buffer way from the cursor plane and
@@ -1761,8 +1781,8 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
17611781
/* Allocate window internal data */
17621782
windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
17631783
if (!windata) {
1764-
SDL_OutOfMemory();
1765-
goto error;
1784+
ret = SDL_OutOfMemory();
1785+
goto cleanup;
17661786
}
17671787

17681788
if (((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) ||
@@ -1773,9 +1793,7 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
17731793
windata->output_w = dispdata->mode.hdisplay;
17741794
windata->output_h = dispdata->mode.vdisplay;
17751795
windata->output_x = 0;
1776-
17771796
} else {
1778-
17791797
/* Normal non-fullscreen windows are scaled using the CRTC,
17801798
so get output (CRTC) size and position, for AR correction. */
17811799
ratio = (float)window->w / (float)window->h;
@@ -1784,7 +1802,6 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
17841802
windata->output_w = dispdata->mode.vdisplay * ratio;
17851803
windata->output_h = dispdata->mode.vdisplay;
17861804
windata->output_x = (dispdata->mode.hdisplay - windata->output_w) / 2;
1787-
17881805
}
17891806

17901807
/* Don't force fullscreen on all windows: it confuses programs that try
@@ -1796,8 +1813,8 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
17961813
window->driverdata = windata;
17971814

17981815
if (!is_vulkan) {
1799-
if (KMSDRM_CreateSurfaces(_this, window)) {
1800-
goto error;
1816+
if ((ret = KMSDRM_CreateSurfaces(_this, window))) {
1817+
goto cleanup;
18011818
}
18021819
}
18031820

@@ -1811,8 +1828,8 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
18111828
viddata->max_windows = new_max_windows;
18121829

18131830
if (!viddata->windows) {
1814-
SDL_OutOfMemory();
1815-
goto error;
1831+
ret = SDL_OutOfMemory();
1832+
goto cleanup;
18161833
}
18171834
}
18181835

@@ -1831,12 +1848,13 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
18311848
/***********************************************************/
18321849
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ENTER, 0, 0);
18331850

1834-
return 0;
1835-
1836-
error:
1837-
KMSDRM_DestroyWindow(_this, window);
1851+
cleanup:
18381852

1839-
return -1;
1853+
if (ret) {
1854+
/* Allocated windata will be freed in KMSDRM_DestroyWindow */
1855+
KMSDRM_DestroyWindow(_this, window);
1856+
}
1857+
return ret;
18401858
}
18411859

18421860
int

0 commit comments

Comments
 (0)