mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	linux_drm_syncobj_v1: fix use-after-free in surface_commit_destroy()
surface_commit_destroy() accesses a field from
struct wlr_linux_drm_syncobj_surface_v1, however that struct may have
been free'd earlier:
    ==1103==ERROR: AddressSanitizer: heap-use-after-free on address 0x7cdef7a6e288 at pc 0x7feefaac335a bp 0x7ffc4de8f570 sp 0x7ffc4de8f560
    READ of size 8 at 0x7cdef7a6e288 thread T0
        #0 0x7feefaac3359 in surface_commit_destroy ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:195
        #1 0x7feefaac34cd in surface_commit_handle_surface_destroy ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:211
        #2 0x7feefbd194cf in wl_signal_emit_mutable (/usr/lib/libwayland-server.so.0+0x84cf) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #3 0x7feefaa52b22 in surface_handle_resource_destroy ../subprojects/wlroots/types/wlr_compositor.c:730
        #4 0x7feefbd1bb9f  (/usr/lib/libwayland-server.so.0+0xab9f) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #5 0x7feefaa46a18 in surface_handle_destroy ../subprojects/wlroots/types/wlr_compositor.c:65
        #6 0x7feef89afac5  (/usr/lib/libffi.so.8+0x7ac5) (BuildId: d5e3b0d8921923f35438adefa9f864745abc5e90)
        #7 0x7feef89ac76a  (/usr/lib/libffi.so.8+0x476a) (BuildId: d5e3b0d8921923f35438adefa9f864745abc5e90)
        #8 0x7feef89af06d in ffi_call (/usr/lib/libffi.so.8+0x706d) (BuildId: d5e3b0d8921923f35438adefa9f864745abc5e90)
        #9 0x7feefbd17531  (/usr/lib/libwayland-server.so.0+0x6531) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #10 0x7feefbd1cd2f  (/usr/lib/libwayland-server.so.0+0xbd2f) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #11 0x7feefbd1b181 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa181) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #12 0x7feefbd1d296 in wl_display_run (/usr/lib/libwayland-server.so.0+0xc296) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #13 0x555bf0a55a40 in server_run ../sway/server.c:615
        #14 0x555bf0a4a654 in main ../sway/main.c:376
        #15 0x7feef9227674  (/usr/lib/libc.so.6+0x27674) (BuildId: 4fe011c94a88e8aeb6f2201b9eb369f42b4a1e9e)
        #16 0x7feef9227728 in __libc_start_main (/usr/lib/libc.so.6+0x27728) (BuildId: 4fe011c94a88e8aeb6f2201b9eb369f42b4a1e9e)
        #17 0x555bf0a03f54 in _start (/home/leo/code/stuff/sway/build/sway/sway+0x390f54) (BuildId: e3d4e653af1aa0885f0426c403e16fc87c086d33)
    0x7cdef7a6e288 is located 8 bytes inside of 176-byte region [0x7cdef7a6e280,0x7cdef7a6e330)
    freed by thread T0 here:
        #0 0x7feefb71f79d in free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:51
        #1 0x7feefaac29f1 in surface_destroy ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:84
        #2 0x7feefaac2e47 in surface_handle_resource_destroy ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:143
        #3 0x7feefbd1bb9f  (/usr/lib/libwayland-server.so.0+0xab9f) (BuildId: b9664217748f523995e3f855fa197cf8e59942d1)
        #4 0x7feefaac2a12 in surface_handle_destroy ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:89
        #5 0x7feef89afac5  (/usr/lib/libffi.so.8+0x7ac5) (BuildId: d5e3b0d8921923f35438adefa9f864745abc5e90)
    previously allocated by thread T0 here:
        #0 0x7feefb7205dd in calloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:74
        #1 0x7feefaac4abd in manager_handle_get_surface ../subprojects/wlroots/types/wlr_linux_drm_syncobj_v1.c:313
        #2 0x7feef89afac5  (/usr/lib/libffi.so.8+0x7ac5) (BuildId: d5e3b0d8921923f35438adefa9f864745abc5e90)
Fix this by storing the struct wlr_surface in the field.
Closes: https://github.com/swaywm/sway/issues/8917
			
			
This commit is contained in:
		
							parent
							
								
									19c5d22beb
								
							
						
					
					
						commit
						6d63871f05
					
				
					 1 changed files with 3 additions and 3 deletions
				
			
		| 
						 | 
					@ -26,7 +26,7 @@ struct wlr_linux_drm_syncobj_surface_v1 {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_linux_drm_syncobj_surface_v1_commit {
 | 
					struct wlr_linux_drm_syncobj_surface_v1_commit {
 | 
				
			||||||
	struct wlr_linux_drm_syncobj_surface_v1 *surface;
 | 
						struct wlr_surface *surface;
 | 
				
			||||||
	struct wlr_drm_syncobj_timeline_waiter waiter;
 | 
						struct wlr_drm_syncobj_timeline_waiter waiter;
 | 
				
			||||||
	uint32_t cached_seq;
 | 
						uint32_t cached_seq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,7 +192,7 @@ static struct wlr_linux_drm_syncobj_surface_v1 *surface_from_wlr_surface(
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void surface_commit_destroy(struct wlr_linux_drm_syncobj_surface_v1_commit *commit) {
 | 
					static void surface_commit_destroy(struct wlr_linux_drm_syncobj_surface_v1_commit *commit) {
 | 
				
			||||||
	wlr_surface_unlock_cached(commit->surface->surface, commit->cached_seq);
 | 
						wlr_surface_unlock_cached(commit->surface, commit->cached_seq);
 | 
				
			||||||
	wl_list_remove(&commit->surface_destroy.link);
 | 
						wl_list_remove(&commit->surface_destroy.link);
 | 
				
			||||||
	wlr_drm_syncobj_timeline_waiter_finish(&commit->waiter);
 | 
						wlr_drm_syncobj_timeline_waiter_finish(&commit->waiter);
 | 
				
			||||||
	free(commit);
 | 
						free(commit);
 | 
				
			||||||
| 
						 | 
					@ -237,7 +237,7 @@ static bool lock_surface_commit(struct wlr_linux_drm_syncobj_surface_v1 *surface
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	commit->surface = surface;
 | 
						commit->surface = surface->surface;
 | 
				
			||||||
	commit->cached_seq = wlr_surface_lock_pending(surface->surface);
 | 
						commit->cached_seq = wlr_surface_lock_pending(surface->surface);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	commit->surface_destroy.notify = surface_commit_handle_surface_destroy;
 | 
						commit->surface_destroy.notify = surface_commit_handle_surface_destroy;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue