BUG Report
Hi, developers of jhead: When I tested jhead, I found multiple bugs. jhead complied with ASAN(export ELECTRIC_FENCE=1)
Version
$ ./jhead -V
Jhead version: 3.08
Platform
$ uname -a
Linux freec-virtual-machine 5.11.0-49-generic #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
BUG1
$ ./jhead -norot poc1
=================================================================
==2806716==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b0000001ba at pc 0x7f9d709ddc33 bp 0x7ffd444ae2b0 sp 0x7ffd444ada58
WRITE of size 4 at 0x60b0000001ba thread T0
#0 0x7f9d709ddc32 in __interceptor_memset ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:799
#1 0x55e6a7fc9978 in memset /usr/include/x86_64-linux-gnu/bits/string_fortified.h:59
#2 0x55e6a7fc9978 in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1259
#3 0x55e6a7fc9978 in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1240
#4 0x55e6a7fc9978 in DoAutoRotate /home/freec/fuzz_normal/jhead/jhead.c:750
#5 0x55e6a7fc9978 in ProcessFile /home/freec/fuzz_normal/jhead/jhead.c:916
#6 0x55e6a7fbef30 in main /home/freec/fuzz_normal/jhead/jhead.c:1805
#7 0x7f9d70692564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#8 0x55e6a7fbfe9d in _start (/home/freec/fuzz_normal/jhead/jhead+0x10e9d)
0x60b0000001ba is located 26 bytes inside of 108-byte region [0x60b0000001a0,0x60b00000020c)
freed by thread T0 here:
#0 0x7f9d70a588f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x55e6a7fc253b in DiscardAllButExif /home/freec/fuzz_normal/jhead/jpgfile.c:544
previously allocated by thread T0 here:
#0 0x7f9d70a58c47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x55e6a7fc65fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:175
#2 0x55e6a7fc65fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:118
#3 0x55e6a7fc65fc in ReadJpegFile /home/freec/fuzz_normal/jhead/jpgfile.c:385
SUMMARY: AddressSanitizer: heap-use-after-free ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:799 in __interceptor_memset
Shadow bytes around the buggy address:
0x0c167fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff8000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa 00 00
0x0c167fff8020: 00 00 00 00 00 00 00 00 00 00 00 04 fa fa fa fa
=>0x0c167fff8030: fa fa fa fa fd fd fd[fd]fd fd fd fd fd fd fd fd
0x0c167fff8040: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd
0x0c167fff8050: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c167fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8080: 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
==2806716==ABORTING
BUG2
$ ./jhead -norot poc2
=================================================================
==3087901==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b0000001ba at pc 0x559111191e3f bp 0x7ffd2d9c6ae0 sp 0x7ffd2d9c6ad0
WRITE of size 1 at 0x60b0000001ba thread T0
#0 0x559111191e3e in Put16u /home/freec/fuzz_normal/jhead/exif.c:307
#1 0x559111191e3e in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1254
#2 0x559111191e3e in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1240
#3 0x559111191e3e in DoAutoRotate /home/freec/fuzz_normal/jhead/jhead.c:750
#4 0x559111191e3e in ProcessFile /home/freec/fuzz_normal/jhead/jhead.c:916
#5 0x559111180f30 in main /home/freec/fuzz_normal/jhead/jhead.c:1805
#6 0x7fa4ad288564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#7 0x559111181e9d in _start (/home/freec/fuzz_normal/jhead/jhead+0x10e9d)
0x60b0000001ba is located 26 bytes inside of 108-byte region [0x60b0000001a0,0x60b00000020c)
freed by thread T0 here:
#0 0x7fa4ad64e8f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x55911118453b in DiscardAllButExif /home/freec/fuzz_normal/jhead/jpgfile.c:544
previously allocated by thread T0 here:
#0 0x7fa4ad64ec47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5591111885fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:175
#2 0x5591111885fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:118
#3 0x5591111885fc in ReadJpegFile /home/freec/fuzz_normal/jhead/jpgfile.c:385
SUMMARY: AddressSanitizer: heap-use-after-free /home/freec/fuzz_normal/jhead/exif.c:307 in Put16u
Shadow bytes around the buggy address:
0x0c167fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff8000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa 00 00
0x0c167fff8020: 00 00 00 00 00 00 00 00 00 00 00 04 fa fa fa fa
=>0x0c167fff8030: fa fa fa fa fd fd fd[fd]fd fd fd fd fd fd fd fd
0x0c167fff8040: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd
0x0c167fff8050: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c167fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8080: 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
==3087901==ABORTING
BUG3
$ ./jhead -norot poc3
=================================================================
==3136555==ERROR: AddressSanitizer: heap-use-after-free on address 0x60b00000031a at pc 0x558da061fe59 bp 0x7fff48d041a0 sp 0x7fff48d04190
WRITE of size 1 at 0x60b00000031a thread T0
#0 0x558da061fe58 in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1250
#1 0x558da061fe58 in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1240
#2 0x558da061fe58 in DoAutoRotate /home/freec/fuzz_normal/jhead/jhead.c:750
#3 0x558da061fe58 in ProcessFile /home/freec/fuzz_normal/jhead/jhead.c:916
#4 0x558da060ef30 in main /home/freec/fuzz_normal/jhead/jhead.c:1805
#5 0x7f95e492c564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#6 0x558da060fe9d in _start (/home/freec/fuzz_normal/jhead/jhead+0x10e9d)
0x60b00000031a is located 26 bytes inside of 108-byte region [0x60b000000300,0x60b00000036c)
freed by thread T0 here:
#0 0x7f95e4cf28f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x558da061253b in DiscardAllButExif /home/freec/fuzz_normal/jhead/jpgfile.c:544
previously allocated by thread T0 here:
#0 0x7f95e4cf2c47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x558da06165fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:175
#2 0x558da06165fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:118
#3 0x558da06165fc in ReadJpegFile /home/freec/fuzz_normal/jhead/jpgfile.c:385
SUMMARY: AddressSanitizer: heap-use-after-free /home/freec/fuzz_normal/jhead/exif.c:1250 in ClearOrientation
Shadow bytes around the buggy address:
0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa 00 00
0x0c167fff8020: 00 00 00 00 00 00 00 00 00 00 00 04 fa fa fa fa
0x0c167fff8030: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
0x0c167fff8040: fd fd fa fa fa fa fa fa fa fa fd fd fd fd fd fd
0x0c167fff8050: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
=>0x0c167fff8060: fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fa fa
0x0c167fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff80b0: 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
==3136555==ABORTING
BUG4
$ ./jhead -norot poc4
=================================================================
==3167529==ERROR: AddressSanitizer: heap-use-after-free on address 0x621000001532 at pc 0x5587d6665a8e bp 0x7fff70ffed50 sp 0x7fff70ffed40
WRITE of size 1 at 0x621000001532 thread T0
#0 0x5587d6665a8d in Put16u /home/freec/fuzz_normal/jhead/exif.c:310
#1 0x5587d6665a8d in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1254
#2 0x5587d6665a8d in ClearOrientation /home/freec/fuzz_normal/jhead/exif.c:1240
#3 0x5587d6665a8d in DoAutoRotate /home/freec/fuzz_normal/jhead/jhead.c:750
#4 0x5587d6665a8d in ProcessFile /home/freec/fuzz_normal/jhead/jhead.c:916
#5 0x5587d6654f30 in main /home/freec/fuzz_normal/jhead/jhead.c:1805
#6 0x7ff91c1bf564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#7 0x5587d6655e9d in _start (/home/freec/fuzz_normal/jhead/jhead+0x10e9d)
0x621000001532 is located 50 bytes inside of 4593-byte region [0x621000001500,0x6210000026f1)
freed by thread T0 here:
#0 0x7ff91c5858f7 in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:127
#1 0x5587d665853b in DiscardAllButExif /home/freec/fuzz_normal/jhead/jpgfile.c:544
previously allocated by thread T0 here:
#0 0x7ff91c585c47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x5587d665c5fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:175
#2 0x5587d665c5fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:118
#3 0x5587d665c5fc in ReadJpegFile /home/freec/fuzz_normal/jhead/jpgfile.c:385
SUMMARY: AddressSanitizer: heap-use-after-free /home/freec/fuzz_normal/jhead/exif.c:310 in Put16u
Shadow bytes around the buggy address:
0x0c427fff8250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c427fff8260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c427fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c427fff8280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c427fff8290: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c427fff82a0: fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd
0x0c427fff82b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c427fff82c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c427fff82d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c427fff82e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c427fff82f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==3167529==ABORTING
BUG5
$ ./jhead -da2022:06:20-2021:06:20 poc5
=================================================================
==3216230==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b0000002bc at pc 0x7f75c23802d3 bp 0x7fff51dd5950 sp 0x7fff51dd50f8
WRITE of size 19 at 0x60b0000002bc thread T0
#0 0x7f75c23802d2 in __interceptor_memcpy ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x564ea7b25c25 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#2 0x564ea7b25c25 in ProcessFile /home/freec/fuzz_normal/jhead/jhead.c:1200
#3 0x564ea7b19f30 in main /home/freec/fuzz_normal/jhead/jhead.c:1805
#4 0x7f75c2034564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#5 0x564ea7b1ae9d in _start (/home/freec/fuzz_normal/jhead/jhead+0x10e9d)
0x60b0000002bc is located 0 bytes to the right of 108-byte region [0x60b000000250,0x60b0000002bc)
allocated by thread T0 here:
#0 0x7f75c23fac47 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x564ea7b215fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:175
#2 0x564ea7b215fc in ReadJpegSections /home/freec/fuzz_normal/jhead/jpgfile.c:118
#3 0x564ea7b215fc in ReadJpegFile /home/freec/fuzz_normal/jhead/jpgfile.c:385
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c167fff8000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c167fff8010: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fd fd
0x0c167fff8020: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa
0x0c167fff8030: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
0x0c167fff8040: 00 04 fa fa fa fa fa fa fa fa 00 00 00 00 00 00
=>0x0c167fff8050: 00 00 00 00 00 00 00[04]fa fa fa fa fa fa fa fa
0x0c167fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c167fff80a0: 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
==3216230==ABORTING
POC
I have just compiled jhead 3.08 on my MacM2 - Ventura. Everything ran cleanly but with a warnining, and based on my simple tests, successfully. The warning information may be helpful to the developer. See my results:
jhead compile on Mac M2 - Ventura.pdf
I then saw this issue so downloaded poc.zip and ran your tests. Results in the following attached file: jHead 3.08 poc test.pdf
I have no idea what the results mean but they are different from yours so I hope they are helpful to you in resolving this issue.
It is recommended to add asan when compiling to catch memory errors. I get a report similar to yours under normal compiling.
Thank you for that. I'm naive about modern compilers and had never heard of address sanitisation or asan. My C days are over 40 years behind me! Very useful to know about on the rare occasions that I compile a CLI program.
Just to let you know, these are very low priority for me. if you can demonstrate jhead failing on a file that actually came from a camera, and without special instrumentation, that would be a priority.
But if you have to contrive a special file and run it in a special test harness to even catch any misbehaviour, it's something that I will look at eventually when I have spare time, but its not urgent.