Stack Buffer Overflow in cURL mprintf.c Formatting Function (Fallback Path) - Report #3493602
Summary
A stack-based buffer overflow exists in mprintf.c within the out_double() function. This vulnerability affects builds where HAVE_SNPRINTF is undefined, forcing the use of the legacy sprintf function. The logic responsible for calculating the maximum safe precision (maxprec) for floating-point formatting fails to correctly handle negative numbers. Specifically, it does not properly account for the number of digits required by the integer portion of negative values. As a result, the buffer size calculation is incorrect, allowing a subsequent sprintf call to write more data than the fixed-size stack buffer can hold.
Affected Component
File: lib/mprintf.c Function: out_double() Vulnerable Condition: HAVE_SNPRINTF is not defined at compile time
Technical Details
The function uses a local stack buffer (work) of size BUFFSIZE (326 bytes). To prevent overflow, the code attempts to estimate the number of digits required for the integer part of the floating-point value and reduce the allowable precision accordingly.
The relevant code is shown below (approx. line 675 in master):
|
|
For negative values (e.g., -1.0e100), the condition val >= 10.0 is false on entry, so the loop is skipped entirely. As a result, maxprec is not reduced, even though the integer portion of the formatted value will consume significant buffer space. The subsequent sprintf call writes the minus sign, the full integer portion, and the requested fractional precision, exceeding the 326-byte stack buffer.
Steps To Reproduce
1. Configure the Build
Compile libcurl with HAVE_SNPRINTF undefined to force the fallback sprintf path. One way to simulate this is by modifying lib/mprintf.c:
|
|
2. Compile Reproduction Program
Compile the following C program against the modified libcurl build:
|
|
3. Run the Program
4. Observe
The output length exceeds the 326-byte buffer size. Depending on stack protections (stack canaries, ASLR), this results in a segmentation fault or stack smashing detection.
Suggested Fix
Correct the integer digit calculation to account for negative values by operating on the absolute value (or equivalent logic):
|
|
Optionally, clamp maxprec to prevent underflow:
|
|
Impact
This vulnerability results in a classic stack-based buffer overflow.
-
Availability: Denial of Service (application crash)
-
Scope: The vulnerable code path is part of the legacy fallback implementation and is not used in default modern curl builds. It primarily affects legacy Unix systems, embedded platforms, or custom builds where snprintf is unavailable or explicitly disabled.
Discussion Timeline
bagder (curl staff) posted a comment. Updated 4 days ago @han_ank please mention a platform where this happens with unaltered source code
jimfuller2024 (curl staff) posted a comment. 3 days ago which platforms … maybe really old linuxes (I remember some older bsd variants, of course System V!) … maybe some embedded systems (TinyOS or FreeRTOS) … there is virtually no ‘surface area’ here which might indicate we can deprecate this all together.
jimfuller2024 (curl staff) posted a comment. 3 days ago forgot to mention - but I am not even certain TinyOS can build curl … maybe someone has done it with FreeRTOS
bagder (curl staff) posted a comment. 3 days ago There were some systems in the 90s that lacked snprintf. Even really old Windows back in those days I believe might had lacked it. In the last twenty or so years even embedded systems have been made with proper libc implementations that offer snprintf. I have not been able to find anything done in the last decades that do not offer snprintf. snprintf() is mandated by the C99 standard, which as the name suggests, came around 1999. libc implementations intended to work with C99 then need to offer the function. As we cannot find any system that is not a legacy end of life one, we cannot consider this a valid vulnerability - but a bug. To completely avoid this discussion from happening again, we remove the sprintf() fallback from the code: https://github.com/curl/curl/pull/20218
ankitsingh015 posted a comment. 3 days ago
bagder (curl staff) closed the report and changed the status to Informative. 3 days ago Thanks for your report. Closed as informative as it identifies a problem (now fixed).
bagder (curl staff) requested to disclose this report. 3 days ago Per project policy for transparency, we want all reports disclosed and made public.
ankitsingh015 agreed to disclose this report. 3 days ago This report has been disclosed. 3 days ago
Report Details
- Reported on: January 7, 2026, 10:12pm UTC
- Reported by: ankitsingh015
- Reported to: curl
- Report Id: #3493602
- Status: Informative
- Severity: High (7 ~ 8.9)
- Disclosed: January 8, 2026, 9:36am UTC
- Weakness: Classic Buffer Overflow
- CVE ID: None
- Bounty: None
- Account details: None