Skip to content

Conversation

@xcawolfe-amzn
Copy link

Attempts to resolve #1472

Prevents excessive looping when consuming packets when errors are hit.

Validated with the steps below

Testing

create bigloop file to validate the issue

ÿOÿQ�,�����d����������	��ü������������������B�ÿR����ÿ��������"ÿ\��@@HHPÿd�-��Creator: AV-J2K (���Vator: AV-J2K (c) iotÿ��
��������ÿ�ÿÿOÿQ

Baseline

This establishes that there is an issue and that it breaks when the loop is excessive

Create a docker container from amazon linux 2023

Test script - test_baseline.sh

#!/bin/bash
set -e

echo "=== CVE-2023-39327 Baseline Test ==="
echo "Testing AL2023 baseline openjpeg2 with malicious PoC file"
echo ""

echo "[1] Installed version:"
rpm -q openjpeg2 openjpeg2-tools

# Test with the PoC file
echo ""
echo "[2] Testing with CVE-2023-39327 PoC file..."
echo "Running: timeout 10 opj2_decompress -i /test/bigloop -o /tmp/output.raw 2>&1 | wc -l"
echo ""

# Count total lines of output in 10 seconds
LINES=$(timeout 10 opj2_decompress -i /test/bigloop -o /tmp/output.raw 2>&1 | wc -l || true)

echo "Total output lines in 10 seconds: $LINES"
echo ""

if [ "$LINES" -gt 10000 ]; then
    echo "VULNERABLE: Excessive output detected ($LINES lines in 10s)"
    echo "The baseline version exhibits CVE-2023-39327 - infinite loop printing warnings."
    echo "This can consume CPU and fill logs indefinitely."
else
    echo "Output: $LINES lines in 10 seconds"
fi

Dockerfile

FROM public.ecr.aws/amazonlinux/amazonlinux:2023

# Install baseline openjpeg2 from AL2023 repos (vulnerable version)
RUN dnf install -y openjpeg2 openjpeg2-tools

# Copy test files
COPY bigloop /test/bigloop
COPY test_baseline.sh /test/test_baseline.sh

# Make script executable
RUN chmod +x /test/test_baseline.sh

# Run the test
CMD ["/test/test_baseline.sh"]

Run the container

# Build baseline test container
docker build -f Dockerfile.baseline -t openjpeg2-baseline-test .
# Run baseline test (should timeout showing vulnerability)
docker run --rm openjpeg2-baseline-test

see that there are many loop iterations and time out is hit

Fixed

Test scipt to validate fix - test_cve_fix.sh

#!/bin/bash
set -e

echo "=== CVE-2023-39327 Test Script ==="
echo "Testing openjpeg2 with malicious PoC file"
echo ""

# Install the patched RPM
echo "[1] Installing patched openjpeg2 package..."
dnf install -y /rpms/openjpeg2-2.5.2-*.x86_64.rpm /rpms/openjpeg2-tools-2.5.2-*.x86_64.rpm 2>&1 | tail -5

# Check version
echo ""
echo "[2] Installed version:"
rpm -q openjpeg2 openjpeg2-tools

# Test with the PoC file
echo ""
echo "[3] Testing with CVE-2023-39327 PoC file (should fail fast, not loop)..."
echo "Running: timeout 10 opj2_decompress -i /test/bigloop -o /tmp/output.raw"
echo ""

# Run with timeout - should fail quickly with error, not timeout
if timeout 10 opj2_decompress -i /test/bigloop -o /tmp/output.raw 2>&1; then
    echo "ERROR: Command succeeded when it should have failed!"
    exit 1
else
    EXIT_CODE=$?
    if [ $EXIT_CODE -eq 124 ]; then
        echo "FAIL: Command timed out - infinite loop detected!"
        echo "The CVE fix is NOT working properly."
        exit 1
    else
        echo "SUCCESS: Command failed quickly (exit code: $EXIT_CODE)"
        echo "The CVE fix is working - no infinite loop detected."
        exit 0
    fi
fi

Docker file

FROM public.ecr.aws/amazonlinux/amazonlinux:2023

# Copy test files
COPY bigloop /test/bigloop
COPY test_cve_fix.sh /test/test_cve_fix.sh
COPY ../<path_to_rpms_with_fix>/ /rpms/

# Make script executable
RUN chmod +x /test/test_cve_fix.sh

# Run the test
CMD ["/test/test_cve_fix.sh"]

Run and build the tests

# Build test container with patched RPMs
docker build -f Dockerfile.test -t openjpeg2-cve-test .

# Run test (should fail fast with loop detection)
docker run --rm openjpeg2-cve-test

See that the timeout is not hit

@rouault
Copy link
Collaborator

rouault commented Dec 31, 2025

From where does the hardcoded 100000 packet limit comes from ? Couldn't it be reached for large valid images ?

@xcawolfe-amzn
Copy link
Author

From where does the hardcoded 100000 packet limit comes from ? Couldn't it be reached for large valid images ?

It was a "big" number that seemed reasonable, but yes in theory it could be reached for very large images....
hmm maybe make it bigger? or configurable?

@rouault
Copy link
Collaborator

rouault commented Jan 2, 2026

I doubt making this configurable would be meaningful to 95% + of users who have no idea of the internals of JPEG2000 and in particular what a packet is. As far as making it bigger, there is perhaps some correlation with other JPEG2000 parameters (image or probably tile size, number of resoutions, number of quality layers), but that should be carefully studied. More globally there are tons of ways where JPEG2000 parameters can be abused to create huge RAM or CPU consumption. Ideally we'd have some global strategy to deal with that, but I can't think of one

@xcawolfe-amzn
Copy link
Author

there is perhaps some correlation with other JPEG2000 parameters (image or probably tile size, number of resoutions, number of quality layers), but that should be carefully studied. More globally there are tons of ways where JPEG2000 parameters can be abused to create huge RAM or CPU consumption.

This makes sense to me, hmmm we'll have to take a looks and see what might work. Ill convert this PR back to draft and take a look at what parameters we could measure and how to intake that data in a secure and effective manner. Thanks for taking a look @rouault!

@xcawolfe-amzn xcawolfe-amzn marked this pull request as draft January 5, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Malicious files can cause the program to enter a large loop

2 participants