[HarfBuzz] GCC 12 warning of use after free in hbfont.cc
Philip Race
philip.race at oracle.com
Thu May 12 02:32:43 UTC 2022
Someone tried building OpenJDK (which includes harfbuzz) using gcc 12
and got this warning
In function 'void trampoline_reference(hb_trampoline_closure_t*)',
inlined from 'void hb_font_funcs_set_glyph_func(hb_font_funcs_t*,
hb_font_get_glyph_func_t, void*, hb_destroy_func_t)' at
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:2368:24:
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:2286:12:
error: pointer 'trampoline' used after 'void free(void*)'
[-Werror=use-after-free]
2286 | closure->ref_count++;
| ~~~~~~~~~^~~~~~~~~
inlined from 'void trampoline_destroy(void*)' at
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:2290:1,
inlined from 'void
hb_font_funcs_set_nominal_glyph_func(hb_font_funcs_t*,
hb_font_get_nominal_glyph_func_t, void*, hb_destroy_func_t)' at
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:733:1,
inlined from 'void hb_font_funcs_set_glyph_func(hb_font_funcs_t*,
hb_font_get_glyph_func_t, void*, hb_destroy_func_t)' at
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:2363:40:
/home/ysuenaga/github-forked/jdk/src/java.desktop/share/native/libharfbuzz/hb-font.cc:2299:8:
note: call to 'void free(void*)' here
2299 | free (closure);
The line numbers don't match current git sources since OpenJDK has an
older version but I think upstream is the same in this regard.
It is referring to this code
----------
hb_font_funcs_set_nominal_glyph_func (ffuncs,
hb_font_get_nominal_glyph_trampoline,
trampoline,
trampoline_destroy);
trampoline_reference (&trampoline->closure);
--------
I *think* the potential problem is this
void \
hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
hb_font_get_##name##_func_t func, \
void *user_data, \
hb_destroy_func_t destroy) \
{ \
if (hb_object_is_immutable (ffuncs)) \
{ \
if (destroy) \
destroy (user_data); \
return; \
}
The macro expansion of that is hb_font_funcs_set_nominal_glyph_func
which is called from
hb_font_funcs_set_glyph_func and on return if that
hb_object_is_immutable code path was taken
then the trampoline reference will have been freed already since we have
static void
trampoline_destroy (void *user_data)
{
hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data;
if (--closure->ref_count)
return;
if (closure->destroy)
closure->destroy (closure->user_data);
free (closure);
}
I suppose if it is never immutable no problem, but I don't know how you
prove that.
And it isn't clear what fix would be wanted.
-phil
More information about the HarfBuzz
mailing list