Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault in jsimd_huff_encode_one_block_sse2 when executing jpegtran #543

Closed
jwright-arm opened this issue Aug 3, 2021 · 10 comments
Closed
Assignees

Comments

@jwright-arm
Copy link
Contributor

Have you searched the existing issues (both open and closed) in the libjpeg-turbo issue tracker to ensure that this bug report is not a duplicate?

Yes.

Does this bug report describe one of the two known and unsolvable issues with the JPEG format?

No.

Clear and concise description of the bug:

Executing jpegtran - with what is presumably a maliciously crafted JPEG file - results in a segfault on x86_64 platforms.

Steps to reproduce the bug (using only libjpeg-turbo):

./jpegtran -outfile out.jpg 0005.jpg

Image(s) needed in order to reproduce the bug (if applicable):

0005

Expected behavior:

No crash.

Observed behavior:

On x86_64 Linux for release builds of libjpeg-turbo,

./jpegtran -outfile out.jpg 0005.jpg and
./jpegtran-static -outfile out.jpg 0005.jpg

results in the following crash:

Corrupt JPEG data: 1 extraneous bytes before marker 0xda
Segmentation fault (core dumped)

For debug builds of libjpeg-turbo on the same platform:

./jpegtran-static -outfile out.jpg 0005.jpg results in the same crash but normal execution is observed for
./jpegtran -outfile out.jpg 0005.jpg

Running under GDB, the only build/execution configuration that reproduces the crash is a release build execution of

./jpegtran -outfile out.jpg 0005.jpg

Consequently, the only debug information available is:

Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7f7b694 in jsimd_huff_encode_one_block_sse2 () from /x86-build/libjpeg.so.62 (gdb) bt #0 0x00007ffff7f7b694 in jsimd_huff_encode_one_block_sse2 () from /x86-build/libjpeg.so.62 #1 0x000055555557ba00 in ?? () #2 0x0000000000000000 in ?? ()

I could not reproduce the crash on AArch64 Linux or Apple Silicon MacOS for either Release or Debug builds of libjpeg-turbo.

Platform(s) (compiler version, operating system version, CPU) on which the bug was observed:

GCC 9.3.0, Ubuntu 20.04.2 LTS, Intel(R) Xeon(R) CPU E5-2660.

libjpeg-turbo release(s), commit(s), or branch(es) in which the bug was observed (always test the tip of the main branch or the latest stable pre-release to verify that the bug hasn't already been fixed):

Tip of main branch.

Additional information:

This bug was originally reported to the Chromium project.[1] The useful information on that ticket is reproduced in this GitHub issue (for those that don't have the required credentials to view the Chromium bug ticket.)

[1] https://bugs.chromium.org/p/chromium/issues/detail?id=1234259

@dcommander
Copy link
Member

dcommander commented Aug 6, 2021

I observe that the issue is reproducible with:

  • dynamic linking when using
    • GCC 4 on CentOS 7
    • GCC 8 on CentOS 7
    • GCC 9 on Ubuntu 20.04
    • GCC 10 on Ubuntu 20.04
  • static linking when using
    • GCC 4 on CentOS 7
    • GCC 8 on CentOS 7
    • GCC 9 on Ubuntu 20.04
    • GCC 10 on Ubuntu 20.04
    • Clang 10 on Ubuntu 20.04
    • Clang 11 on Ubuntu 20.04

Enabling or disabling PIC/PIE doesn't make a difference with static linking.

The issue is not reproducible on macOS/x86-64 using either Xcode 7.2 or 11.3.

The crash is endemic to the SIMD-accelerated Huffman encoder, so setting JSIMD_NOHUFFENC=1 makes it go away.

It seems to be occurring at https://github.com/libjpeg-turbo/libjpeg-turbo/blob/main/simd/x86_64/jchuff-sse2.asm#L382, but I have no idea why. Perhaps @mayeut has some insight, since he wrote that code.

@dcommander
Copy link
Member

Confirmed that this is a regression introduced by 087c29e in 2.1 beta1.

@dcommander
Copy link
Member

@1camper This involves your code. Any ideas?

@dcommander
Copy link
Member

Apparently the issue is that the C Huffman encoder has a 65536-deep nbits table but the SSE2 version has a 32768-deep nbits table, and the malformed image causes the index into that table to exceed 32768. The following patch seems to fix the issue, by making the SSE2 table the same as the C table. I am performing further testing right now. I'm not sure why the i386 code doesn't exhibit the same issue.

--- a/simd/x86_64/jchuff-sse2.asm
+++ b/simd/x86_64/jchuff-sse2.asm
@@ -83,6 +83,7 @@ times 1 << 11 db 12
 times 1 << 12 db 13
 times 1 << 13 db 14
 times 1 << 14 db 15
+times 1 << 15 db 16
 
     alignz      32
 

@dcommander
Copy link
Member

Should be fixed. Please test and confirm.

@jwright-arm
Copy link
Contributor Author

Yes, the fix is working for me - I'm no longer able to reproduce the crash. Thanks everyone.

@dcommander
Copy link
Member

Great. I'm going to let OSS-Fuzz run over the weekend, since I added the test image above to the seed corpora, but I anticipate making a 2.1.1 release early next week.

@thoger
Copy link

thoger commented Sep 24, 2021

Google assigned CVE-2021-37972 to this issue, the CVE is listed in the recent Chrome release announcement:

https://chromereleases.googleblog.com/2021/09/stable-channel-update-for-desktop_21.html

[$TBD][1234259] Low CVE-2021-37972 : Out of bounds read in libjpeg-turbo. Reported by Xu Hanyu and Lu Yutao from Panguite-Forensics-Lab of Qianxin on 2021-07-29

@dcommander
Copy link
Member

I've updated the change log to indicate which line item fixes that CVE ID.

@thoger
Copy link

thoger commented Oct 3, 2021

Changelog update mentioned in the previous comment is commit 739ecbc.

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

No branches or pull requests

3 participants