Skip to content

Segmentation fault when calling FT_Open_Face with custom FT_StreamRec #31

Description

@mcendu

The following excerpt causes a segmentation fault inside FT_Open_Face:

    /* ... */
    Stream? s = /* ... */;
    var handle = GCHandle.Alloc(s);
    FT_FaceRec_* face = null;
    var ftStream = (FT_StreamRec_*)NativeMemory.AllocZeroed((nuint)sizeof(FT_StreamRec_));
  
    ftStream->size = 0x7FFFFFFF;
    ftStream->descriptor.pointer = (void*)(nint)handle;
    ftStream->read = (delegate* unmanaged<FT_StreamRec_*, nuint, byte*, nuint, nuint>)&ReadFromFreeType;
    ftStream->close = (delegate* unmanaged<FT_StreamRec_*, void>)&CloseFromFreeType;
  
    var openArgs = new FT_Open_Args_
    {
        flags = 0x2, // FT_OPEN_STREAM
        stream = ftStream,
        num_params = 0,
    };
  
    nint compoundFaceIndex = (ushort)FaceIndex | (NamedInstance << 16);
  
    FT_Error error = FT_Open_Face(freeType, &openArgs, compoundFaceIndex, &face);
    /* program crashes here */

GDB shows that FreeType does not see ftStream in the intended way:

Thread 43 ".NET TP Worker" hit Breakpoint 1, FT_Open_Face
(library=0x7fbe28005190, args=0x7fbe327fb810, face_index=0,
aface=0x7fbe327fb860) at /usr/src/debug/freetype-2.13.3-2.fc42.x86_64/src/base/ftobjs.c:2520
2520      {
(gdb) p *args->stream
$12 = {base = 0x0, size = 2147483647, pos = 0, descriptor = {value = 0,
  pointer = 0x0}, pathname = {value = 140737345688256,
  pointer = 0x7ffff77f12c0}, read = 0x0, close = 0x0,
  memory = 0x7fff7bb7a100,  cursor = 0x7fff7bb7a118 "\377%\372?",
  limit = 0x0}

On further inspection, the definition of FT_StreamDesc_ does not seem to be correct at the C# end (sizes and offsets assumes x86-64 Linux ABI):

    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct FT_StreamDesc_ /* size = 16! */
    {
        public IntPtr value; /* offset = 0 */
        public void* pointer; /* offset = 8! */
    }

FreeType expects FT_StreamDesc_ to be a union instead:

typedef union  FT_StreamDesc_ /* size = 8 */
  {
    long   value; /* offset = 0 */
    void*  pointer; /* offset = 0 */

  } FT_StreamDesc;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions