Skip to content

Conversation

@OxBat
Copy link

@OxBat OxBat commented Jan 27, 2026

Summary

I identified a Remote Denial of Service vulnerability in CharsetDecoder (specifically APRCharsetDecoder).
When processing untrusted network input, malformed byte sequences trigger an infinite loop.

The Loop:
When apr_xlate_conv_buffer encounters an invalid byte (like 0xFF in UTF-8), it returns an error status (APR_BADCH) but consumes 0 bytes.
The previous loop logic exited on error, but without advancing the buffer pointer. If the caller (e.g., SocketNode) retries decoding the remaining buffer, it hits the same byte again indefinitely (100% CPU).

The Fix:
I updated the decode loop to detect when an error occurs without consuming input. In this case, it now:

  1. Checks if it's just APR_INCOMPLETE (valid partial packet).
  2. If not, manually advances the buffer position by 1 byte (skipping the bad byte).
  3. Appends a Replacement Character (?) to the output.
  4. Resets status to APR_SUCCESS to continue decoding the rest of the stream.

OxBat added 2 commits January 27, 2026 19:24
When decoding invalid byte sequences (e.g. 0xFF in UTF-8), apr_xlate returns
an error without consuming input. This caused an infinite loop where the
decoder retried the same byte forever.
This patch forces the decoder to skip the invalid byte and insert a
replacement character ('?') to ensure forward progress.
@rm5248
Copy link
Contributor

rm5248 commented Jan 29, 2026

this seems like a pretty easy thing to add a test for to prove that it is working correctly, could you add a test to the charsetdecodertestcase?

Add a test for handling malformed input in APRCharsetDecoder.
@OxBat
Copy link
Author

OxBat commented Jan 29, 2026

Done! I added testInfiniteLoop to reproduce the hang with a bad byte (0xFF).

I purposely requested ISO-8859-2 in the test. If I used standard UTF-8, log4cxx would use its internal optimized decoder (skipping APR) and wouldn't hit the bug I fixed.

@rm5248
Copy link
Contributor

rm5248 commented Jan 29, 2026

your test does not appear to work properly. If I revert the changes to charsetdecoder.cpp the test fails and does not enter an infinite loop. What platform are you testing on and what version of APR are you using?

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.

2 participants