From cbc6b666ae40b1f6a1634612f8bd5bc599eec42b Mon Sep 17 00:00:00 2001 From: dance Date: Wed, 26 Jan 2022 19:52:35 +0300 Subject: [PATCH] wayland: fixed memory corruption issue (write to free'd memory) pass window and buffer index to buffer_release listener, so that it fetches actual pointer to released buffer by wayland, instead of directly passing a pointer to the UwacBuffer, which could result in heap-use-after-free --- uwac/libuwac/uwac-priv.h | 8 ++++++++ uwac/libuwac/uwac-window.c | 14 +++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/uwac/libuwac/uwac-priv.h b/uwac/libuwac/uwac-priv.h index 9a2efe53e..1bda15ff0 100644 --- a/uwac/libuwac/uwac-priv.h +++ b/uwac/libuwac/uwac-priv.h @@ -255,6 +255,14 @@ struct uwac_window int pointer_current_cursor; }; +/**@brief data to pass to wl_buffer release listener */ +struct uwac_buffer_release_data +{ + UwacWindow* window; + int bufferIdx; +}; +typedef struct uwac_buffer_release_data UwacBufferReleaseData; + /* in uwa-display.c */ UwacEvent* UwacDisplayNewEvent(UwacDisplay* d, int type); int UwacDisplayWatchFd(UwacDisplay* display, int fd, uint32_t events, UwacTask* task); diff --git a/uwac/libuwac/uwac-window.c b/uwac/libuwac/uwac-window.c index 7de1d35f9..f02b7ec55 100644 --- a/uwac/libuwac/uwac-window.c +++ b/uwac/libuwac/uwac-window.c @@ -48,7 +48,8 @@ static int bppFromShmFormat(enum wl_shm_format format) static void buffer_release(void* data, struct wl_buffer* buffer) { - UwacBuffer* uwacBuffer = (UwacBuffer*)data; + UwacBufferReleaseData* releaseData = data; + UwacBuffer* uwacBuffer = &releaseData->window->buffers[releaseData->bufferIdx]; uwacBuffer->used = false; } @@ -66,7 +67,10 @@ static void UwacWindowDestroyBuffers(UwacWindow* w) #else region16_uninit(&buffer->damage); #endif + UwacBufferReleaseData* releaseData = + (UwacBufferReleaseData*)wl_buffer_get_user_data(buffer->wayland_buffer); wl_buffer_destroy(buffer->wayland_buffer); + free(releaseData); munmap(buffer->data, buffer->size); } @@ -344,7 +348,8 @@ int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32 for (i = 0; i < nbuffers; i++) { - UwacBuffer* buffer = &w->buffers[w->nbuffers + i]; + int bufferIdx = w->nbuffers + i; + UwacBuffer* buffer = &w->buffers[bufferIdx]; #ifdef HAVE_PIXMAN_REGION pixman_region32_init(&buffer->damage); #else @@ -354,7 +359,10 @@ int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32 buffer->size = allocSize; buffer->wayland_buffer = wl_shm_pool_create_buffer(pool, allocSize * i, width, height, w->stride, format); - wl_buffer_add_listener(buffer->wayland_buffer, &buffer_listener, buffer); + UwacBufferReleaseData* listener_data = xmalloc(sizeof(UwacBufferReleaseData)); + listener_data->window = w; + listener_data->bufferIdx = bufferIdx; + wl_buffer_add_listener(buffer->wayland_buffer, &buffer_listener, listener_data); } wl_shm_pool_destroy(pool);