[fpc-devel] double free of internal temp string with fpc 3.2.0

Martin Frb lazarus at mfriebe.de
Fri Jan 8 17:11:19 CET 2021


I only tested with 3.2.0 so far. Maybe someone recalls if this is fixed 
or not.

Also because it seems to happen only in very rare conditions, it may be 
that trunk does not cause it in this place even if the bug is not yet 
fixed. (as other code changes could simply change the context enough to 
mitigate it)


Using fpc 3.2.0
compiling lazarus  SVN 64346 at trunk with -gw -gl -gt -Criot -Sa -O-1 -gh -gv
(this also happened at -O3 / but I could not trace it as valgrinds 
reported stack was unreadable  / The attached valgrind is with -O-1)

unit MaskEdit
procedure TCustomMaskEdit.SetMask(Value : String);

 From the generated ASM

# Temps allocated between rbp-696 and rbp-296

# [575] for I := 1 To Utf8Length(S) do
     leaq    -400(%rbp),%rdi
     call    fpc_ansistr_decr_ref at PLT
     leaq    -408(%rbp),%rdi
     call    fpc_ansistr_decr_ref at PLT
     leaq    -272(%rbp),%rsi
     xorl    %edx,%edx
     leaq    -408(%rbp),%rdi
     call    fpc_shortstr_to_ansistr at PLT
     movq    -408(%rbp),%rsi   ////// 
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     movq    %rsi,-400(%rbp)
     testq    %rsi,%rsi
     je    .Lj156
     movq    -8(%rsi),%rsi
.Lj156:
     movq    -400(%rbp),%rdi
     testq    %rdi,%rdi
     jne    .Lj157
     movq    FPC_EMPTYCHAR at GOTPCREL(%rip),%rdi
.Lj157:
     call    LAZUTF8_$$_UTF8LENGTH$PCHAR$INT64$$INT64 at PLT

On the marked line, the string (ref) in temp(-408) is copied to temp(-400).
But the refcount is NOT increased

*****
Temp(-408) is later passed as "var param Result" to

# [741] FTextOnEnter := inherited RealGetText;
     movq    -16(%rbp),%rdi
     leaq    -408(%rbp),%rsi
     call STDCTRLS$_$TCUSTOMEDIT_$__$$_REALGETTEXT$$TTRANSLATESTRING at PLT

This will assign an empty string (in this case), and free the memory 
(apparently the refcount happens to be 1 at that time)

*****
in the autogenerated code for the procedures "end" statement:

# [743] end;
     leaq    -408(%rbp),%rdi
     call    fpc_ansistr_decr_ref at PLT
     leaq    -400(%rbp),%rdi
     call    fpc_ansistr_decr_ref at PLT

Temp-408 is already free (or may have a new value that gets correctly freed)

Temp-400 still points to the already freed string => double free.






-------------- next part --------------
==57294== Memcheck, a memory error detector
==57294== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==57294== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==57294== Command: ./lazarus
==57294== Parent PID: 11182
==57294== 
==57294== Invalid read of size 8
==57294==    at 0x42DE84: fpc_ansistr_decr_ref (astrings.inc:146)
==57294==    by 0x8C56C6: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:743)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294==    by 0x49B467: FORMS$_$TCUSTOMFORM_$__$$_CREATE$TCOMPONENT$$TCUSTOMFORM (customform.inc:2068)
==57294==    by 0x49F5A8: FORMS$_$TFORM_$__$$_CREATE$TCOMPONENT$$TFORM (customform.inc:3197)
==57294==    by 0x144C445: PSEUDOTERMINALDLG$_$TPSEUDOCONSOLEDLG_$__$$_CREATE$TCOMPONENT$$TPSEUDOCONSOLEDLG (pseudoterminaldlg.pp:216)
==57294==    by 0xC40C60: DEBUGMANAGER$_$TDEBUGMANAGER_$__$$_VIEWDEBUGDIALOG$TDEBUGDIALOGTYPE$BOOLEAN$BOOLEAN$BOOLEAN (debugmanager.pas:1676)
==57294==    by 0xC448E7: DEBUGMANAGER$_$TDEBUGMANAGER_$__$$_CREATEDEBUGDIALOG$TOBJECT$ANSISTRING$TCUSTOMFORM$BOOLEAN (debugmanager.pas:2298)
==57294==  Address 0xdfdf160 is 16 bytes inside a block of size 40 free'd
==57294==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==57294==    by 0x4514DF: CMEM_$$_CFREEMEM$POINTER$$QWORD (cmem.pp:75)
==57294==    by 0x43DC52: SYSTEM_$$_FREEMEM$POINTER$$QWORD (heap.inc:324)
==57294==    by 0x42DEA4: fpc_ansistr_decr_ref (astrings.inc:149)
==57294==    by 0x42DF25: fpc_ansistr_assign (astrings.inc:186)
==57294==    by 0x66258A: STDCTRLS$_$TCUSTOMEDIT_$__$$_REALGETTEXT$$TTRANSLATESTRING (customedit.inc:535)
==57294==    by 0x8C5692: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:741)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294==  Block was alloc'd at
==57294==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==57294==    by 0x451498: CMEM_$$_CGETMEM$QWORD$$POINTER (cmem.pp:62)
==57294==    by 0x43DB39: SYSTEM_$$_GETMEM$POINTER$QWORD (heap.inc:284)
==57294==    by 0x42DDFC: SYSTEM_$$_NEWANSISTRING$INT64$$POINTER (astrings.inc:115)
==57294==    by 0x42F102: fpc_ansistr_setlength (astrings.inc:776)
==57294==    by 0x42E975: fpc_shortstr_to_ansistr (astrings.inc:510)
==57294==    by 0x8C4930: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:575)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294== 
==57294== Invalid read of size 8
==57294==    at 0x4221E5: SYSTEM_$$_DECLOCKED$INT64$$BOOLEAN (x86_64.inc:721)
==57294==    by 0x8C56C6: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:743)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294==    by 0x49B467: FORMS$_$TCUSTOMFORM_$__$$_CREATE$TCOMPONENT$$TCUSTOMFORM (customform.inc:2068)
==57294==    by 0x49F5A8: FORMS$_$TFORM_$__$$_CREATE$TCOMPONENT$$TFORM (customform.inc:3197)
==57294==    by 0x144C445: PSEUDOTERMINALDLG$_$TPSEUDOCONSOLEDLG_$__$$_CREATE$TCOMPONENT$$TPSEUDOCONSOLEDLG (pseudoterminaldlg.pp:216)
==57294==    by 0xC40C60: DEBUGMANAGER$_$TDEBUGMANAGER_$__$$_VIEWDEBUGDIALOG$TDEBUGDIALOGTYPE$BOOLEAN$BOOLEAN$BOOLEAN (debugmanager.pas:1676)
==57294==    by 0xC448E7: DEBUGMANAGER$_$TDEBUGMANAGER_$__$$_CREATEDEBUGDIALOG$TOBJECT$ANSISTRING$TCUSTOMFORM$BOOLEAN (debugmanager.pas:2298)
==57294==  Address 0xdfdf160 is 16 bytes inside a block of size 40 free'd
==57294==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==57294==    by 0x4514DF: CMEM_$$_CFREEMEM$POINTER$$QWORD (cmem.pp:75)
==57294==    by 0x43DC52: SYSTEM_$$_FREEMEM$POINTER$$QWORD (heap.inc:324)
==57294==    by 0x42DEA4: fpc_ansistr_decr_ref (astrings.inc:149)
==57294==    by 0x42DF25: fpc_ansistr_assign (astrings.inc:186)
==57294==    by 0x66258A: STDCTRLS$_$TCUSTOMEDIT_$__$$_REALGETTEXT$$TTRANSLATESTRING (customedit.inc:535)
==57294==    by 0x8C5692: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:741)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294==  Block was alloc'd at
==57294==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==57294==    by 0x451498: CMEM_$$_CGETMEM$QWORD$$POINTER (cmem.pp:62)
==57294==    by 0x43DB39: SYSTEM_$$_GETMEM$POINTER$QWORD (heap.inc:284)
==57294==    by 0x42DDFC: SYSTEM_$$_NEWANSISTRING$INT64$$POINTER (astrings.inc:115)
==57294==    by 0x42F102: fpc_ansistr_setlength (astrings.inc:776)
==57294==    by 0x42E975: fpc_shortstr_to_ansistr (astrings.inc:510)
==57294==    by 0x8C4930: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_SETMASK$ANSISTRING (maskedit.pp:575)
==57294==    by 0x8C963C: MASKEDIT$_$TCUSTOMMASKEDIT_$__$$_LOADED (maskedit.pp:1730)
==57294==    by 0x571C76: CLASSES_$$_NOTIFYGLOBALLOADING (classes.inc:1521)
==57294==    by 0x7C8E50: LRESOURCES_$$_INITLAZRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:3183)
==57294==    by 0x7BE2AE: LRESOURCES_$$_INITRESOURCECOMPONENT$TCOMPONENT$TCLASS$$BOOLEAN (lresources.pp:798)
==57294==    by 0x49B5F4: FORMS$_$TCUSTOMFORM_$__$$_PROCESSRESOURCE (customform.inc:2080)
==57294== 


More information about the fpc-devel mailing list