Xu Biang reported a bug in the eap-mschapv2 plugin related to handling failure packets on the client that can lead to a crash or even remote code execution.
Buffer Overflow When Handling EAP-MSCHAPv2 Failure Requests
The eap-mschapv2 plugin doesn't correctly check the length of an EAP-MSCHAPv2 Failure Request packet on the client, which can cause an integer underflow that leads to a crash and, depending on the compiler options, even a heap-based buffer overflow that's potentially exploitable for remote code execution. Affected are all strongSwan versions since 4.2.12.
CVE-2025-62291 has been assigned for this vulnerability.
Incorrect Length Check for Failure Requests in eap-mschapv2 Plugin
The eap-mschapv2 plugin implements the MS-CHAP-v2 authentication method (defined in a long expired Internet Draft) for the Extensible Authentication Protocol (EAP) that can be used with IKEv2.
If the authentication fails, e.g. because the password is incorrect, the server will send a Failure Request packet. Its payload consists of a formatted string such as "E=eee R=r C=ccccc V=vvvv M=<msg>".
Before parsing such a packet, the plugin verifies that it contains at least a minimal EAP-MSCHAPv2 header, which is 6 bytes. It then intends to ensure that at least an error code, such as "E=1", is received. So it expects 3 characters at this point. However, it does compare against the size of the complete packet and not just its payload.
So when the code then subtracts the length of the full header, which is 9 bytes, the result can become negative if the size is between 6 and 8 bytes. This length is then used to create a copy of the string, which looks like this (eap->data points to the payload of the packet):
message = malloc(message_len + 1);
memcpy(message, eap->data, message_len);
message[message_len] = '\0';
Note that message_len is an int and both malloc() and memcpy() take an unsigned size_t argument for the length. So a negative value causes an integer underflow when passing it to those functions.
If the packet has a length of 6 or 7, message_len is -3 or -2, respectively. Due to the underflow, the allocation of a huge amount of memory is requested (if size_t is 64 bits wide, around 16384 PiB). This call should fail as it exceeds the hard upper limit of PTRDIFF_MAX. So NULL is returned and that in turn causes a segmentation fault when memcpy() is called.
With a packet length of 8, message_len is -1. This results in the allocation of 0 bytes, which is fine and results in a valid pointer.
But passing -1 to memcpy() then causes a heap-based buffer overflow (possibly causing a segmentation fault due to the huge number).
Fortunately, if the plugin is compiled with -D_FORTIFY_SOURCE=3, which is the default on e.g. Ubuntu, and optimizations are enabled (our configure script sets -O2 by default) then the compiler will use __memcpy_chk() as both calls are in the same context, which prevents the buffer overflow and instead aborts the process immediately. Note that -D_FORTIFY_SOURCE=2 is not enough as the size of the buffer is dynamic.
Remote code execution might be possible due to this issue.
As mentioned in the introduction, credit to Xu Biang of HUST CSE (GitHub: BIIIANG) for finding this vulnerability and reporting it responsibly.
Mitigation
Clients that don't use EAP authentication are not vulnerable.
Clients that use EAP authentication but have a specific, non-tunneling EAP method configured (e.g. auth = eap-tls or auth = eap-md5 and not just auth = eap or auth=eap-peap) are not vulnerable.
Clients that use EAP authentication but don't configure a specific EAP method and have the eap-mschapv2 plugin loaded are vulnerable as the server may initiate the EAP-MSCHAPv2 method. If the method is not actually required, the plugin may be disabled to avoid the issue.
As described above, the buffer overflow is prevented if the plugin was compiled with optimization and -D_FORTIFY_SOURCE=3. However, the vulnerability can still be exploited for a DoS attack.
The just released strongSwan 6.0.3 fixes this vulnerability. For older releases, we provide a patch that fixes the vulnerability and should apply with appropriate hunk offsets (patches for versions before 4.4.0 are currently not provided).
In order to assess the risk for unpatched clients, it's important to note that in many cases only authenticated servers are in a position to send crafted messages. It depends on where the EAP-MSCHAPv2 authentication is terminated and whether it's tunneled in a TLS-based EAP method:
- If it's terminated on the IKEv2 server, that server itself has to be malicious because the EAP exchange is protected by IKEv2 and only started after the client authenticated the server with a certificate. So no on-path attacks are possible in this case.
- If EAP-MSCHAPv2 is terminated on a RADIUS server, likewise, that server itself has to be malicious if EAP-MSCHAPv2 is tunneled in EAP-PEAP or EAP-TTLS. However, if that's not the case, it's possible that an on-path attacker in possession of the RADIUS authentication password and located between the IKEv2 and RADIUS servers (or the IKEv2 server itself) could inject a crafted message.