mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	render/gles2: check buffer stride when uploading texture
If the stride is too small, the driver could end up segfaulting (e.g. radeonsi segfaults in __memmove_sse2_unaligned_erms).
This commit is contained in:
		
							parent
							
								
									f3758d1d0a
								
							
						
					
					
						commit
						6ca59519c9
					
				
					 1 changed files with 23 additions and 0 deletions
				
			
		| 
						 | 
					@ -30,6 +30,21 @@ static bool gles2_texture_is_opaque(struct wlr_texture *wlr_texture) {
 | 
				
			||||||
	return !texture->has_alpha;
 | 
						return !texture->has_alpha;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool check_stride(const struct wlr_gles2_pixel_format *fmt,
 | 
				
			||||||
 | 
							uint32_t stride, uint32_t width) {
 | 
				
			||||||
 | 
						if (stride % (fmt->bpp / 8) != 0) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "Invalid stride %d (incompatible with %d "
 | 
				
			||||||
 | 
								"bytes-per-pixel)", stride, fmt->bpp / 8);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (stride < width * (fmt->bpp / 8)) {
 | 
				
			||||||
 | 
							wlr_log(WLR_ERROR, "Invalid stride %d (too small for %d "
 | 
				
			||||||
 | 
								"bytes-per-pixel and width %d)", stride, fmt->bpp / 8, width);
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
 | 
					static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
 | 
				
			||||||
		uint32_t stride, uint32_t width, uint32_t height,
 | 
							uint32_t stride, uint32_t width, uint32_t height,
 | 
				
			||||||
		uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
 | 
							uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
 | 
				
			||||||
| 
						 | 
					@ -45,6 +60,10 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
 | 
				
			||||||
		get_gles2_format_from_wl(texture->wl_format);
 | 
							get_gles2_format_from_wl(texture->wl_format);
 | 
				
			||||||
	assert(fmt);
 | 
						assert(fmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!check_stride(fmt, stride, width)) {
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_egl_context prev_ctx;
 | 
						struct wlr_egl_context prev_ctx;
 | 
				
			||||||
	wlr_egl_save_context(&prev_ctx);
 | 
						wlr_egl_save_context(&prev_ctx);
 | 
				
			||||||
	wlr_egl_make_current(texture->renderer->egl);
 | 
						wlr_egl_make_current(texture->renderer->egl);
 | 
				
			||||||
| 
						 | 
					@ -142,6 +161,10 @@ struct wlr_texture *gles2_texture_from_pixels(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!check_stride(fmt, stride, width)) {
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_gles2_texture *texture =
 | 
						struct wlr_gles2_texture *texture =
 | 
				
			||||||
		calloc(1, sizeof(struct wlr_gles2_texture));
 | 
							calloc(1, sizeof(struct wlr_gles2_texture));
 | 
				
			||||||
	if (texture == NULL) {
 | 
						if (texture == NULL) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue