Products > Programming

fontconfig-2.14.2 memory leak.

(1/1)

Ed.Kloonk:
Was poking around with some widgets and had a old version of fontconfig that compelled asan to spam the console.

Built the latest version 2.14.2 (with configure flags as mentioned in INSTALL) but still getting mem leaks reported (I believe* in a different function). *forgot to capture the output. Cannot seem to find any free() in the code to match the reported realloc call.

Hurriedly tried just shoving a free() here and there. All I did was manage to keep borking the server until I revert. Ew.

Thought I'd ask on here if anyone can help me spot the obvious. Haven't ruled out my own code yet but showing no symptoms other than this.


--- Quote ---Direct leak of 2560 byte(s) in 4 object(s) allocated from:
    #0 0x4a6508 in __interceptor_realloc ../../../../libsanitizer/asan/asan_malloc_linux.cpp:164
    #1 0x7f630896dfd8 in FcPatternObjectInsertElt /media/sf_VMShare/fontconfig-2.14.2/src/fcpat.c:516

Indirect....etc etc etc etc

--- End quote ---

fontconfig-2.14.2/src/fcpat.c ( Lines 498-552. Line 516 embolded)

--- Quote ---FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object)
{
    int          i;
    FcPatternElt   *e;

    i = FcPatternObjectPosition (p, object);
    if (i < 0)
    {
   i = -i - 1;

   /* reallocate array */
   if (FcPatternObjectCount (p) + 1 >= p->size)
   {
       int s = p->size + 16;
       if (p->size)
       {
      FcPatternElt *e0 = FcPatternElts(p);
      e = (FcPatternElt *) realloc (e0, s * sizeof (FcPatternElt));
      if (!e) /* maybe it was mmapped */
      {
          e = malloc(s * sizeof (FcPatternElt));
          if (e)
         memcpy(e, e0, FcPatternObjectCount (p) * sizeof (FcPatternElt));
      }
       }
       else
      e = (FcPatternElt *) malloc (s * sizeof (FcPatternElt));
       if (!e)
      return FcFalse;
       p->elts_offset = FcPtrToOffset (p, e);
       while (p->size < s)
       {
      e[p->size].object = 0;
      e[p->size].values = NULL;
      p->size++;
       }
   }

   e = FcPatternElts(p);
   /* move elts up */
   memmove (e + i + 1,
       e + i,
       sizeof (FcPatternElt) *
       (FcPatternObjectCount (p) - i));

   /* bump count */
   p->num++;

   e.object = object;
   e.values = NULL;
    }

    return FcPatternElts(p) + i;
}

--- End quote ---

Nominal Animal:
(The sources are at https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/2.14.2/src/fcpat.c, with src/fcpat.c:FcPatternObjectInsertElt() at https://gitlab.freedesktop.org/fontconfig/fontconfig/-/blob/2.14.2/src/fcpat.c#L498.)

Nominal Animal:
Let's see.

FcPattern is a structure with four members: integers num and size, elts_offset of type intptr_t, and ref of type FcRef AKA int.

FcPatternElt is a structure with two members: object (of type FcObject AKA int), and a pointer values (to type FcValueList) forming a linked list.

FcPatternElts(p) evaluates to ((FcPatternElt *)((intptr_t)p + (ptrdiff_t)(p->elts_offset))), i.e. elts = (FcPatternElt *)((char *)p + p->elts_offset).

Looking at other related stuff, that points to an array of objects at byte offset elts_offset relative to the original pointer, sorted in order of increasing object (number identifier).

In FcPatternObjectInsertElt(), FcPatternObjectPosition() does a binary search to find the specified object.  If the object is found, FcPatternObjectInsertElt() returns a pointer to it.  Otherwise, we get into the if body.

FcPatternObjectCount(p) returns just p->num, the number of FcPatternElt's in the array, and obviously p->size is the size of the array.

Now, how is that reallocation supposed to work?  Ah yes, that aforementioned FcPatternElts(), although relative to the original pointer, may actually be a completely separate pointer.  The line 528, p->elts_offset = FcPtrToOffset (p, e);, evaluates to p->elts_offset = (intptr_t)e - (intptr_t)p;, so that FcPatternElts() will yield the possibly realloc()'d pointer.

The FcPatternObjectInsertElt() is used in src/fcpat.c:FcPatternObjectListAdd(), src/fcpat.c:FcPatternObjectAddWithBinding(), and src/fccfg.c:FcConfigPatternAdd().

If we look through the entire src/fcpat.c file, wherever ->size is used (because that is the "allocated" size of the elts array, it is never reduced or zeroed out.  In other words, fontconfig-2.14.2 is not designed to actually release the memory allocated here back to the OS at all.

So, this is a bug, or rather design deficiency, in FontConfig that requires a refactoring, in my opinion.

Navigation

[0] Message Index

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod