Description
## Summary
A missing integer overflow check was identified in `lib/system_win32.c::curl_load_library()`
when calculating the buffer size for a DLL path. On 32-bit Windows builds, the unchecked
size calculation can wrap around, resulting in an undersized heap allocation followed by
unbounded string copies via `_tcscpy()`.
While the current call sites only pass fixed, trusted strings and no immediate attack
vector is identified, the presence of a latent heap corruption primitive places this issue
beyond pure informational hardening and justifies a **Low severity** classification.
---
## Affected Code
**File:** `lib/system_win32.c`
**Function:** `curl_load_library(LPCTSTR filename)`
``` c
UINT systemdirlen = GetSystemDirectory(NULL, 0);
if(systemdirlen) {
size_t filenamelen = _tcslen(filename);
TCHAR *path = curlx_malloc(sizeof(TCHAR) *
(systemdirlen + 1 + filenamelen));
if(path && GetSystemDirectory(path, systemdirlen)) {
_tcscpy(path + _tcslen(path), TEXT("\\"));
_tcscpy(path + _tcslen(path), filename);
}
curlx_free(path);
}
```
---
## Technical Details
### Integer Overflow Condition
- `systemdirlen` is of type `UINT` (32-bit)
- `filenamelen` is of type `size_t`
- The allocation size is computed as:
```
sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)
```
On 32-bit platforms, `size_t` arithmetic wraps on overflow. If `filenamelen` is large,
the multiplication can overflow, resulting in a much smaller allocation than intended.
### Memory Safety Impact
After allocation, `_tcscpy()` is used twice without any bounds checking. If the buffer
is undersized due to arithmetic wrap-around, this creates a **reliable heap corruption
condition at the code level**, independent of current reachability.
---
## Why This Is Low Severity (Not Informational)
### 1. Heap Corruption Primitive Exists
Even though the current code paths are not attacker-controlled, the function contains
a complete heap corruption pattern (overflowable size calculation + unbounded copy).
This exceeds a stylistic or theoretical issue.
### 2. Violation of libcurlβs Own Defensive Patterns
Other parts of the codebase explicitly guard against integer overflows in allocation
calculations (e.g. `vauth/ntlm.c` using `SIZE_MAX` checks). This inconsistency weakens
the overall security posture and makes future maintenance riskier.
### 3. Long-Term and Supply-Chain Risk
`curl_load_library()` is a general-purpose internal utility. As libcurl evolves or is
embedded by third-party software, future refactoring or reuse could unintentionally
pass unvalidated input to this function, immediately exposing a heap corruption flaw.
### 4. Low-Cost, High-Value Fix
The issue can be resolved with a simple bounds check and without changing runtime
behavior in valid cases. This makes it a practical security fix rather than a
purely informational observation.
---
## Recommended Fix
Add an explicit overflow check before allocation, consistent with existing libcurl
practices:
``` c
if(filenamelen > (SIZE_MAX / sizeof(TCHAR)) - systemdirlen - 1) {
return NULL;
}
TCHAR *path = curlx_malloc(sizeof(TCHAR) *
(systemdirlen + 1 + filenamelen));
```
---
## Severity Assessment
- **Severity:** Low
- **Type:** Integer overflow leading to potential heap-based buffer overflow
- **Current Exploitability:** None identified
- **Risk Category:** Latent memory corruption / future reachability risk
---
## References
- CWE-190: Integer Overflow or Wraparound
- CWE-122: Heap-based Buffer Overflow
- CERT C: INT30-C (Ensure that unsigned integer operations do not wrap)
- libcurl precedent: overflow checks in `vauth/ntlm.c`
## Impact
### Impact
At present, no direct attacker-controlled input reaches this code path, and no
immediate exploitation scenario is identified in the current libcurl codebase.
However, this implementation contains a complete heap corruption primitive
(integer overflow in allocation size calculation followed by unbounded string
copies). If this function were to become reachable through future refactoring,
new features, or third-party reuse, an attacker could potentially achieve:
- Heap memory corruption on 32-bit Windows builds
- Process crash (denial of service)
- Potential arbitrary code execution, depending on allocator behavior and
surrounding memory layout
Because libcurl is a widely embedded library, such latent issues increase
software supply-chain risk and maintenance fragility. Fixing this proactively
eliminates a memory corruption condition before it becomes externally reachable.
A missing integer overflow check was identified in `lib/system_win32.c::curl_load_library()`
when calculating the buffer size for a DLL path. On 32-bit Windows builds, the unchecked
size calculation can wrap around, resulting in an undersized heap allocation followed by
unbounded string copies via `_tcscpy()`.
While the current call sites only pass fixed, trusted strings and no immediate attack
vector is identified, the presence of a latent heap corruption primitive places this issue
beyond pure informational hardening and justifies a **Low severity** classification.
---
## Affected Code
**File:** `lib/system_win32.c`
**Function:** `curl_load_library(LPCTSTR filename)`
``` c
UINT systemdirlen = GetSystemDirectory(NULL, 0);
if(systemdirlen) {
size_t filenamelen = _tcslen(filename);
TCHAR *path = curlx_malloc(sizeof(TCHAR) *
(systemdirlen + 1 + filenamelen));
if(path && GetSystemDirectory(path, systemdirlen)) {
_tcscpy(path + _tcslen(path), TEXT("\\"));
_tcscpy(path + _tcslen(path), filename);
}
curlx_free(path);
}
```
---
## Technical Details
### Integer Overflow Condition
- `systemdirlen` is of type `UINT` (32-bit)
- `filenamelen` is of type `size_t`
- The allocation size is computed as:
```
sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)
```
On 32-bit platforms, `size_t` arithmetic wraps on overflow. If `filenamelen` is large,
the multiplication can overflow, resulting in a much smaller allocation than intended.
### Memory Safety Impact
After allocation, `_tcscpy()` is used twice without any bounds checking. If the buffer
is undersized due to arithmetic wrap-around, this creates a **reliable heap corruption
condition at the code level**, independent of current reachability.
---
## Why This Is Low Severity (Not Informational)
### 1. Heap Corruption Primitive Exists
Even though the current code paths are not attacker-controlled, the function contains
a complete heap corruption pattern (overflowable size calculation + unbounded copy).
This exceeds a stylistic or theoretical issue.
### 2. Violation of libcurlβs Own Defensive Patterns
Other parts of the codebase explicitly guard against integer overflows in allocation
calculations (e.g. `vauth/ntlm.c` using `SIZE_MAX` checks). This inconsistency weakens
the overall security posture and makes future maintenance riskier.
### 3. Long-Term and Supply-Chain Risk
`curl_load_library()` is a general-purpose internal utility. As libcurl evolves or is
embedded by third-party software, future refactoring or reuse could unintentionally
pass unvalidated input to this function, immediately exposing a heap corruption flaw.
### 4. Low-Cost, High-Value Fix
The issue can be resolved with a simple bounds check and without changing runtime
behavior in valid cases. This makes it a practical security fix rather than a
purely informational observation.
---
## Recommended Fix
Add an explicit overflow check before allocation, consistent with existing libcurl
practices:
``` c
if(filenamelen > (SIZE_MAX / sizeof(TCHAR)) - systemdirlen - 1) {
return NULL;
}
TCHAR *path = curlx_malloc(sizeof(TCHAR) *
(systemdirlen + 1 + filenamelen));
```
---
## Severity Assessment
- **Severity:** Low
- **Type:** Integer overflow leading to potential heap-based buffer overflow
- **Current Exploitability:** None identified
- **Risk Category:** Latent memory corruption / future reachability risk
---
## References
- CWE-190: Integer Overflow or Wraparound
- CWE-122: Heap-based Buffer Overflow
- CERT C: INT30-C (Ensure that unsigned integer operations do not wrap)
- libcurl precedent: overflow checks in `vauth/ntlm.c`
## Impact
### Impact
At present, no direct attacker-controlled input reaches this code path, and no
immediate exploitation scenario is identified in the current libcurl codebase.
However, this implementation contains a complete heap corruption primitive
(integer overflow in allocation size calculation followed by unbounded string
copies). If this function were to become reachable through future refactoring,
new features, or third-party reuse, an attacker could potentially achieve:
- Heap memory corruption on 32-bit Windows builds
- Process crash (denial of service)
- Potential arbitrary code execution, depending on allocator behavior and
surrounding memory layout
Because libcurl is a widely embedded library, such latent issues increase
software supply-chain risk and maintenance fragility. Fixing this proactively
eliminates a memory corruption condition before it becomes externally reachable.
Basic Information
ID
H1:3479019
Published
Dec 26, 2025 at 13:31
Modified
Dec 27, 2025 at 13:47