Segmentation fault detected in function Get32s of exif.c when running jhead 3.04

Bug #1857519 reported by WangXiaoxiong
256
This bug affects 1 person
Affects Status Importance Assigned to Milestone
jhead (Ubuntu)
New
Undecided
Unassigned

Bug Description

Tested in Ubuntu 16.04, 64bit. [Jhead](https://www.sentex.ca/~mwandel/jhead/) version is 3.04 and updated on Nov 22 2019.

The testcase cause segmentation error is put in the attachment.
I use the following command:

```shell
./jhead -mkexif jhead_segv.jpg
```

and get:

```
Nonfatal Error : 'jhead_segv.jpg' Too many components -16777196 for tag 0002 in Exif

Nonfatal Error : 'jhead_segv.jpg' Inappropriate format (2) for Exif GPS coordinates!
Segmentation fault
```

I use **AddressSanitizer** to build jhead 3.04 and running it with the following command:

```shell
./jhead jhead_segv.jpg
```

This is the ASAN information:

```
install/jhead -mkexif jhead_segv.jpg

Nonfatal Error : 'jhead_segv.jpg' Too many components -16777196 for tag 0002 in Exif

Nonfatal Error : 'jhead_segv.jpg' Inappropriate format (2) for Exif GPS coordinates!
ASAN:SIGSEGV
=================================================================
==28329==ERROR: AddressSanitizer: SEGV on unknown address 0x60d00100cf7b (pc 0x00000040ae0c bp 0x7fff3f4085f0 sp 0x7fff3f4085f0 T0)
    #0 0x40ae0b in Get32s jhead-3.04/exif.c:337
    #1 0x4115dc in ProcessGpsInfo jhead-3.04/gpsinfo.c:138
    #2 0x40d9a3 in ProcessExifDir jhead-3.04/exif.c:866
    #3 0x40d91c in ProcessExifDir jhead-3.04/exif.c:852
    #4 0x40e09a in process_EXIF jhead-3.04/exif.c:1041
    #5 0x408318 in ReadJpegSections jhead-3.04/jpgfile.c:287
    #6 0x408581 in ReadJpegFile jhead-3.04/jpgfile.c:379
    #7 0x405039 in ProcessFile jhead-3.04/jhead.c:905
    #8 0x40267d in main jhead-3.04/jhead.c:1756
    #9 0x7f95e5ea182f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x403c38 in _start (install/jhead+0x403c38)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV jhead-3.04/exif.c:337 Get32s
==28329==ABORTING
```

I use **valgrind** to analysis the bug and get the below information:

```
==872== Memcheck, a memory error detector
==872== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==872== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==872== Command: ./jhead -mkexif jhead_segv.jpg
==872==

Nonfatal Error : 'jhead_segv.jpg' Too many components -16777196 for tag 0002 in Exif

Nonfatal Error : 'jhead_segv.jpg' Inappropriate format (2) for Exif GPS coordinates!
==872== Invalid read of size 4
==872== at 0x41D27E: Get32s (exif.c:332)
==872== by 0x42CB9C: ProcessGpsInfo (gpsinfo.c:138)
==872== by 0x423C4B: ProcessExifDir (exif.c:866)
==872== by 0x423A3D: ProcessExifDir (exif.c:852)
==872== by 0x424324: process_EXIF (exif.c:1041)
==872== by 0x411471: ReadJpegSections.part.0 (jpgfile.c:287)
==872== by 0x41289E: ReadJpegSections (jpgfile.c:126)
==872== by 0x41289E: ReadJpegFile (jpgfile.c:379)
==872== by 0x408E8E: ProcessFile (jhead.c:905)
==872== by 0x4022C3: main (jhead.c:1756)
==872== Address 0x650e38b is not stack'd, malloc'd or (recently) free'd
==872==
==872==
==872== Process terminating with default action of signal 11 (SIGSEGV)
==872== Access not within mapped region at address 0x650E38B
==872== at 0x41D27E: Get32s (exif.c:332)
==872== by 0x42CB9C: ProcessGpsInfo (gpsinfo.c:138)
==872== by 0x423C4B: ProcessExifDir (exif.c:866)
==872== by 0x423A3D: ProcessExifDir (exif.c:852)
==872== by 0x424324: process_EXIF (exif.c:1041)
==872== by 0x411471: ReadJpegSections.part.0 (jpgfile.c:287)
==872== by 0x41289E: ReadJpegSections (jpgfile.c:126)
==872== by 0x41289E: ReadJpegFile (jpgfile.c:379)
==872== by 0x408E8E: ProcessFile (jhead.c:905)
==872== by 0x4022C3: main (jhead.c:1756)
==872== If you believe this happened as a result of a stack
==872== overflow in your program's main thread (unlikely but
==872== possible), you can try to increase the size of the
==872== main thread stack using the --main-stacksize= flag.
==872== The main thread stack size used in this run was 8388608.
==872==
==872== HEAP SUMMARY:
==872== in use at exit: 766 bytes in 3 blocks
==872== total heap usage: 4 allocs, 1 frees, 4,862 bytes allocated
==872==
==872== LEAK SUMMARY:
==872== definitely lost: 0 bytes in 0 blocks
==872== indirectly lost: 0 bytes in 0 blocks
==872== possibly lost: 0 bytes in 0 blocks
==872== still reachable: 766 bytes in 3 blocks
==872== suppressed: 0 bytes in 0 blocks
==872== Rerun with --leak-check=full to see details of leaked memory
==872==
==872== For counts of detected and suppressed errors, rerun with: -v
==872== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault
```

Revision history for this message
WangXiaoxiong (1217161407-3) wrote :
Revision history for this message
Paulo Flabiano Smorigo (pfsmorigo) wrote :

Thanks for taking the time to report this bug and helping to make Ubuntu better. Since the package referred to in this bug is in universe or multiverse, it is community maintained. If you are able, I suggest coordinating with upstream and posting a debdiff for this issue. When a debdiff is available, members of the security team will review it and publish the package. See the following link for more information: https://wiki.ubuntu.com/SecurityTeam/UpdateProcedures

tags: added: community-security
information type: Private Security → Public Security
Revision history for this message
WangXiaoxiong (1217161407-3) wrote :

I review the source code and try to find why this error occurs. I find line 138 of gpsinfo.c calls function Get32s and its parameter is ValuePtr+4+a*ComponentSize. However, the parameter which doesn't been verified may not be a valid pointer. So we will get a segmentation fault when the pointer be dereferenced with a malicious JPEG file. This may allow a remote attacker to cause a denial-of-service attack or unspecified other impact.

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.