AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 51 Cryptographic libraries

epee, common: pass unsigned char to <cctype> functions

Public commit record

What the developer wrote

Authored by pucedoteth

95/100 · Strong
epee, common: pass unsigned char to <cctype> functions

The <cctype> functions require their argument to be representable as
unsigned char or to equal EOF. char is signed on the platforms Monero
targets, so every byte >= 0x80 reaches them negative, which is undefined
behaviour.

All six call sites take bytes that come from outside the process:

hex_to_dec_2bytes() percent-escapes in a payment URI
http_client.h the status line of an HTTP response
updates.cpp the hash field of a DNS update record

glibc and the macOS libc happen to tolerate -128..-1 because their tables
carry padding below zero, so this is quiet in practice on those, but it is
still out of contract and other libcs index without that cushion.

Cast to unsigned char at each call. The conversion is behaviour-preserving
for the ASCII these actually test: for a byte such as 0xC3, toupper()
returns it unchanged in the C locale, it narrows back to char, memchr()
misses it in the hex table, and hex_to_dec_2bytes() falls through to the
existing literal "%XY" output exactly as before.

epee::misc_utils::parse::isdigit/isalpha/isspace are separate char-taking
helpers and are already well defined, so they are untouched, as is
is_base64(), which already takes unsigned char.
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode✓ Mentions testing or verification
The short version

What changed, and why it matters

This commit fixes a low-level programming mistake in how Monero handles bytes received from outside the program. Functions that classify characters (like checking if a byte is a space, blank, letter, or digit) were being given bytes that could be interpreted as negative numbers on the systems Monero runs on. That is officially undefined behavior, meaning the program could in theory read out of bounds, crash, or misbeave on some C library implementations. The fix casts those bytes to unsigned char before passing them to the classification functions. The commit message says the bug is quiet in practice on glibc and macOS, but could be a real problem on other C libraries.

Recommended action

Apply the patch. It is a small, safe correctness fix that removes undefined behavior on untrusted input bytes. No immediate incident response is indicated because the commit message states the issue is quiet on the commonly used glibc and macOS libcs, but leaving the UB in place creates latent risk on other platforms or future libc changes.

Security signals we found

01

Undefined behavior in <cctype> functions triggered by attacker-controlled bytes

02

Potential out-of-bounds table read in libc character-classification tables on non-glibc/macOS libcs

03

Network/input-derived bytes passed directly to isblank, isspace, isalnum, toupper

04

Fix is defensive/correctness rather than a confirmed exploitable vulnerability

Risk score

Why this scored 51/100

Our methodology →
Potential impact 12/30
Exploitability 10/25
Stealth signal 8/15
Affected reach 10/15
Confidence 7/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.