Compiler Optimization Removal or Modification of Security-critical Code Affecting mbedtls package, versions [,3.6.4)


Severity

Recommended
0.0
medium
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

EPSS
0.02% (3rd percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-CONAN-MBEDTLS-10645568
  • published8 Jul 2025
  • disclosed4 Jul 2025
  • creditSolar Designer

Introduced: 4 Jul 2025

NewCVE-2025-52496  (opens in a new tab)
CWE-733  (opens in a new tab)

How to fix?

Upgrade mbedtls to version 3.6.4 or higher.

Overview

Affected versions of this package are vulnerable to Compiler Optimization Removal or Modification of Security-critical Code due to a race condition in AESNI detection when certain compiler optimizations are applied. An attacker can extract sensitive cryptographic keys or perform unauthorized message forgeries by exploiting concurrent execution in a multithreaded environment.

Note:

This issue affects users of x86 or amd64 processors that have the AESNI instruction.

Workaround

Users who do not need their code to work on processors without AESNI and CLMUL instructions can compile Mbed TLS with the configuration option MBEDTLS_AES_USE_HARDWARE_ONLY enabled. This option disables the table-based implementations of AES and GCM, leaving only the hardware-accelerated implementations.

As soon as one call to mbedtls_aesni_has_support() has completed in a program instance, subsequent calls will use the correct value. Therefore a program is not vulnerable if one thread performs an AES operation before any other thread starts an AES operation. Single-threaded programs are not affected.

The race condition is only present if the compiler orders the variable updates in a problematic way. It have been observed that GCC up to 6.x tends to produce vulnerable binaries at higher optimization levels (-Os, -O2 and above). Vulnerable binaries were not observed with GCC 7.x and above, or with Clang, but this may vary between versions, optimization levels and programs. GCC 10.x and above are safe thanks to a memory barrier in its __cpuid intrinsic.

PoC

The library function mbedtls_aesni_has_support() detects the presence of AESNI and CLMUL. The first time this function is called, it queries the processor features. The function caches the result in a global variable c for subsequent calls, and uses another global variable done to indicate that the result in c has been filled. The simplified code looks like this:

static int done = 0;
static unsigned c = 0;
if (!done) {
    c = cpuid(...); // query processor features
    done = 1;
}

Depending on compiler optimizations in mbedtls_aesni_has_support(), the compiled program may execute a store instruction for the variable done before the store of c. Hence the following race condition may be possible in a multithreaded program:

  • Thread 1 starts an AES or GCM operation, and calls mbedtls_aesni_has_support(). That is the first invocation of the function. It incorrectly updates done before it has updated c.
  • Thread 2 starts an AES or GCM operation, and calls mbedtls_aesni_has_support(). That invocation reads done which tells it that c contains the detection result. But c still contains the startup default value 0, which indicates that the feature is not present. Therefore the AES or GCM operation in thread 2 will use the portable, table-based implementation.
  • Thread 1 updates c. It and subsequent callers will use the actual hardware capabilities.

On its own, the vulnerability is unlikely to be exploitable, since the window of vulnerability is very small. However, if the attacker can block thread 1 from progressing, the window of vulnerability may be large.

CVSS Base Scores

version 4.0
version 3.1