Fix memory corruption!

In FcStrListCreate() we were increasing reference count of set,
however, if set had a const reference (which is the case for list
of languages), and with multiple threads, the const ref (-1) was
getting up to 1 and then a decrease was destroying the set.  Ouch.

Here's the valgrind error, which took me quite a few hours of
running to catch:

==4464== Invalid read of size 4
==4464==    at 0x4E58FF3: FcStrListNext (fcstr.c:1256)
==4464==    by 0x4E3F11D: FcConfigSubstituteWithPat (fccfg.c:1508)
==4464==    by 0x4E3F8F4: FcConfigSubstitute (fccfg.c:1729)
==4464==    by 0x4009FA: test_match (simple-pthread-test.c:53)
==4464==    by 0x400A6E: run_test_in_thread (simple-pthread-test.c:68)
==4464==    by 0x507EE99: start_thread (pthread_create.c:308)
==4464==  Address 0x6bc0b44 is 4 bytes inside a block of size 24 free'd
==4464==    at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4464==    by 0x4E58F84: FcStrSetDestroy (fcstr.c:1236)
==4464==    by 0x4E3F0C6: FcConfigSubstituteWithPat (fccfg.c:1507)
==4464==    by 0x4E3F8F4: FcConfigSubstitute (fccfg.c:1729)
==4464==    by 0x4009FA: test_match (simple-pthread-test.c:53)
==4464==    by 0x400A6E: run_test_in_thread (simple-pthread-test.c:68)
==4464==    by 0x507EE99: start_thread (pthread_create.c:308)

Thread test is running happily now.  Will add the test in a moment.
This commit is contained in:
Behdad Esfahbod 2013-01-08 13:01:48 -06:00
parent 4e6c7d0827
commit dc21ed28d6
1 changed files with 12 additions and 1 deletions

View File

@ -1217,6 +1217,17 @@ FcStrSetDel (FcStrSet *set, const FcChar8 *s)
return FcFalse;
}
/* TODO Make public */
static FcStrSet *
FcStrSetReference (FcStrSet *set)
{
if (FcRefIsConst (&set->ref))
return set;
FcRefInc (&set->ref);
return set;
}
void
FcStrSetDestroy (FcStrSet *set)
{
@ -1245,7 +1256,7 @@ FcStrListCreate (FcStrSet *set)
if (!list)
return 0;
list->set = set;
FcRefInc (&set->ref);
FcStrSetReference (set);
list->n = 0;
return list;
}