Description
A signed integer overflow (CWE-190) was discovered in the PORT command
handler when parsing the port number portion of the h1,h2,h3,h4,p1,p2
format. The val variable (type int) can overflow during repeated
val *= 10 operations with no overflow check.
Affected Code
source/ftpSession.cpp, function FtpSession::PORT()`, lines 2941-2962:
int val = 0; // line 2941
for (auto p = portString; *p; ++p)
{
// ...
val *= 10; // line 2959 - NO overflow check
val += *p - '0'; // line 2960
}
// Check comes AFTER overflow already occurred:
if (val > 0xFF || port > 0xFF) // line 2964
Proof of Concept
Compiled with UBSAN (-fsanitize=signed-integer-overflow):
$ echo 'PORT 1,2,3,4,5,99999999999999' | nc
UBSAN output:
ftpSession.cpp:2959:21: runtime error: signed integer overflow:
1666666666 * 10 cannot be represented in type 'int'
Impact
• Signed integer overflow is undefined behavior per the C++ standard
• While the subsequent > 0xFF check catches most overflowed values, compiler optimizations may eliminate that check under UB assumptions
• Requires authentication (USER/PASS) before PORT is available
• CVSS 3.1 estimate: 2.3 (Low) — AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L
Proposed Fix
Add an overflow check before the multiplication:
if (val > INT_MAX / 10) // prevent overflow
{
sendResponse("501 %s\r\n", std::strerror(EINVAL));
return;
}
val *= 10;
Environment
• mtheall/ftpd v3.2.1
• Discovered via AFL++ 4.32a fuzzing with UBSAN
• Clang 15, Ubuntu 24.04
Description
A signed integer overflow (CWE-190) was discovered in the PORT command
handler when parsing the port number portion of the
h1,h2,h3,h4,p1,p2format. The
valvariable (typeint) can overflow during repeatedval *= 10operations with no overflow check.Affected Code
source/ftpSession.cpp
, functionFtpSession::PORT()`, lines 2941-2962:int val = 0; // line 2941
for (auto p = portString; *p; ++p)
{
// ...
val *= 10; // line 2959 - NO overflow check
val += *p - '0'; // line 2960
}
// Check comes AFTER overflow already occurred:
if (val > 0xFF || port > 0xFF) // line 2964
Proof of Concept
Compiled with UBSAN (-fsanitize=signed-integer-overflow):
$ echo 'PORT 1,2,3,4,5,99999999999999' | nc
UBSAN output:
ftpSession.cpp:2959:21: runtime error: signed integer overflow:
1666666666 * 10 cannot be represented in type 'int'
Impact
• Signed integer overflow is undefined behavior per the C++ standard
• While the subsequent > 0xFF check catches most overflowed values, compiler optimizations may eliminate that check under UB assumptions
• Requires authentication (USER/PASS) before PORT is available
• CVSS 3.1 estimate: 2.3 (Low) — AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L
Proposed Fix
Add an overflow check before the multiplication:
if (val > INT_MAX / 10) // prevent overflow
{
sendResponse("501 %s\r\n", std::strerror(EINVAL));
return;
}
val *= 10;
Environment
• mtheall/ftpd v3.2.1
• Discovered via AFL++ 4.32a fuzzing with UBSAN
• Clang 15, Ubuntu 24.04