win32u: Guard font unused_entry against race condition.
There is a race condition otherwise between release_gdi_font and find_cached_gdi_font, leading to invalid memory access: One thread calling release_gdi_font may decrement refcount to 0, then try to enter font_lock. At the same time, another thread may be calling find_cached_gdi_font through select_font, holding the font_lock. This second thread would find refcount set to 0, and then try to remove unused_entry from its list, although it hasn't been added yet to the unused list. Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
162991a03c
commit
39fea6cd1e
|
@ -2576,12 +2576,13 @@ static struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *m
|
||||||
static void release_gdi_font( struct gdi_font *font )
|
static void release_gdi_font( struct gdi_font *font )
|
||||||
{
|
{
|
||||||
if (!font) return;
|
if (!font) return;
|
||||||
if (--font->refcount) return;
|
|
||||||
|
|
||||||
TRACE( "font %p\n", font );
|
TRACE( "font %p\n", font );
|
||||||
|
|
||||||
/* add it to the unused list */
|
/* add it to the unused list */
|
||||||
pthread_mutex_lock( &font_lock );
|
pthread_mutex_lock( &font_lock );
|
||||||
|
if (!--font->refcount)
|
||||||
|
{
|
||||||
list_add_head( &unused_gdi_font_list, &font->unused_entry );
|
list_add_head( &unused_gdi_font_list, &font->unused_entry );
|
||||||
if (unused_font_count > UNUSED_CACHE_SIZE)
|
if (unused_font_count > UNUSED_CACHE_SIZE)
|
||||||
{
|
{
|
||||||
|
@ -2592,6 +2593,7 @@ static void release_gdi_font( struct gdi_font *font )
|
||||||
free_gdi_font( font );
|
free_gdi_font( font );
|
||||||
}
|
}
|
||||||
else unused_font_count++;
|
else unused_font_count++;
|
||||||
|
}
|
||||||
pthread_mutex_unlock( &font_lock );
|
pthread_mutex_unlock( &font_lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue