Heap Use After Free in the deletestringbox() function (READ of size 8 )

Hi,

While fuzzing dpic 68ab9432 with AFL++, I found a heap use-after-free in the deletestringbox() function, in dpic.y.

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"

Attaching a reproducer: test03

the issue can be reproduced by running:

dpic test03

With ASAN report

=================================================================
==18==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000000060 at pc 0x000000528bfe bp 0x7fffffffa5a0 sp 0x7fffffffa598
READ of size 8 at 0x60d000000060 thread T0
    #0 0x528bfd in deletestringbox /src/dpic/dpic.y:5716:19
    #1 0x4fba03 in yyparse /src/dpic/dpic.y
    #2 0x4e67b3 in main /src/dpic/main.c:1795:13
    #3 0x7ffff7c570b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #4 0x41c48d in _start (/src/dpic/dpic+0x41c48d)

0x60d000000060 is located 32 bytes inside of 136-byte region [0x60d000000040,0x60d0000000c8)
freed by thread T0 here:
    #0 0x497482 in free (/src/dpic/dpic+0x497482)
    #1 0x51b74d in deletetree /src/dpic/dpic.y

previously allocated by thread T0 here:
    #0 0x4976ed in malloc (/src/dpic/dpic+0x4976ed)
    #1 0x525e42 in newprim /src/dpic/dpic.y

SUMMARY: AddressSanitizer: heap-use-after-free /src/dpic/dpic.y:5716:19 in deletestringbox
Shadow bytes around the buggy address:
  0x0c1a7fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1a7fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1a7fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1a7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c1a7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c1a7fff8000: fa fa fa fa fa fa fa fa fd fd fd fd[fd]fd fd fd
  0x0c1a7fff8010: fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa
  0x0c1a7fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c1a7fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==18==ABORTING

GDB report:

$ gdb -q ./dpic core 
Reading symbols from ./dpic...
[New LWP 3062595]
Core was generated by `./dpic ./test03'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  bval (buf=0x1000000000000 <error: Cannot access memory at address 0x1000000000000>) at dpic.y:4919
4919		 if (bval(pn->segmnt) > 1) {
(gdb) bt
#0  bval (buf=0x1000000000000 <error: Cannot access memory at address 0x1000000000000>) at dpic.y:4919
#1  deletename (head=0x4394e8) at dpic.y:4919
#2  0x000000000040778d in deletetree (p=0x7fffffffa728) at dpic.y:3906
#3  0x0000000000409184 in deletestringbox (pr=pr@entry=0x7fffffffa728) at dpic.y:5724
#4  0x000000000041079d in yyparse () at dpic.y:2810
#5  0x0000000000404830 in main (argc=<optimized out>, argv=<optimized out>) at main.c:1795
(gdb) 

Valgrind report:

$ valgrind --track-origins=yes ./dpic ./test03 
==55== Memcheck, a memory error detector
==55== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==55== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==55== Command: ./dpic ./test03
==55== 
Char chr(127)"\177" unknown

*** dpic ERROR: file "./test03" line 1:
>
Character not recognized: ignored

*** dpic ERROR: file "./test03" line 1:
>0dbq
Improper use of logical operator

*** dpic ERROR: file "./test03" line 1:
>0dbq
Improper use of logical operator
==55== Invalid read of size 8
==55==    at 0x1139D5: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3e0 is 32 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid write of size 8
==55==    at 0x111F10: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3e0 is 32 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111F3E: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3f0 is 48 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111F20: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3e8 is 40 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111F54: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3e0 is 32 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111DA0: deletename (in /src/dpic/dpic)
==55==    by 0x111F60: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3d8 is 24 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111DA0: deletename (in /src/dpic/dpic)
==55==    by 0x111F6C: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3d0 is 16 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111DA0: deletename (in /src/dpic/dpic)
==55==    by 0x111F78: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3c8 is 8 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 8
==55==    at 0x111DA0: deletename (in /src/dpic/dpic)
==55==    by 0x111F80: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3c0 is 0 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid read of size 4
==55==    at 0x111F84: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a420 is 96 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 
==55== Invalid free() / delete / delete[] / realloc()
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B4A3: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Address 0x4b9a3c0 is 0 bytes inside a block of size 136 free'd
==55==    at 0x483CA3F: free (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x111F92: deletetree (in /src/dpic/dpic)
==55==    by 0x113A09: deletestringbox (in /src/dpic/dpic)
==55==    by 0x11B57F: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55==  Block was alloc'd at
==55==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55==    by 0x112078: newprim (in /src/dpic/dpic)
==55==    by 0x116888: yyparse (in /src/dpic/dpic)
==55==    by 0x10EDE7: main (in /src/dpic/dpic)
==55== 

*** dpic: maximum error count exceeded
==55== 
==55== HEAP SUMMARY:
==55==     in use at exit: 4,592 bytes in 4 blocks
==55==   total heap usage: 9 allocs, 6 frees, 17,048 bytes allocated
==55== 
==55== LEAK SUMMARY:
==55==    definitely lost: 0 bytes in 0 blocks
==55==    indirectly lost: 0 bytes in 0 blocks
==55==      possibly lost: 0 bytes in 0 blocks
==55==    still reachable: 4,592 bytes in 4 blocks
==55==         suppressed: 0 bytes in 0 blocks
==55== Rerun with --leak-check=full to see details of leaked memory
==55== 
==55== For lists of detected and suppressed errors, rerun with: -s
==55== ERROR SUMMARY: 11 errors from 11 contexts (suppressed: 0 from 0)