Heiko Schäfer discovered a new security issue in the Yubico yubihsm_pkcs11.so driver library, which we disclosed together to Yubico. The YubiHSM PKCS#11 client-side library is designed to interact with Yubico HSM2 hardware security modules. Due to flaws in the memory handling, the library code accidentally returns 8192 bytes of previously used process memory under some circumstances. This impacts the memory confidentiality of the calling program for some usages.
In get_attribute_opaque(), some function paths overwrite the length parameter - which is passed as a reference - to the actual length of the field for the specific attribute they fetched. However, for at least three specific field types, this does not happen:
As a result, code flows hitting the quoted code lines in get_attribute_opaque() will return to the parent function without writing data into the tmp buffer, without changing the length parameter away from the maximum value, and without returning an error code. By convention, this appears like a successful operation which produced 8192 bytes of new output, although in reality the tmp buffer was not written to at all.
This constellation leads to a problematic memcpy() call which leaks the uninitialized memory contents of tmp into the output:
Typically, the content of uninitialized stack memory variables will contain memory from stack frames which previously occupied the relevant memory region. Copying data from this memory region will likely contain stack variables and other stack-related information (stack canaries, pointers) from previous function calls.
The leaked data will then get returned to the PKCS#11 caller. Since the caller requested some specific certificate information, but instead gets data from an information leak, this represents a security issue. Additionally, since the problematic library function indicates no errors, this information may be passed on by the caller towards other components and trust spheres, depending on the specific behavior of the program.
Programs that use the YubiHSM are likely to handle secrets, possibly including secret key material, or sensitive plaintext. The sensitive key material may include the PIN secret used to secure the HSM communication. Because of this bug, a program that uses yubihsm_pkcs11.so may inadvertently return such information instead of the requested X.509 certificate attributes.
Since the vulnerable component is a flexible library, it is unclear which programs call into the problematic function, and under which circumstances. Additionally, the relevant memory accesses are undefined behavior (UB) in C and may depend on the compiler and system environment. If you have more information about specific integrating applications and their confirmed security impacts, please contact us.
To confirm that this data actually leaks from the tmp variable on the stack, we used a modified yubihsm_pkcs11.so library which specifically marks the memory in question with ASCII ‘A’ characters. During initial debugging, this allowed a straightforward identification of the problematic memory in returned data:
In order to confirm the issue and help Yubico reproduce it, we crafted a proof-of-concept (PoC). The PoC consists of a short dummy program written in C that triggers the issue: pkcs11-memleak.c.
WARNING: use the provided PoC code at your own risk, and only on non-production HSM devices.
Please see the code comments for setup details and explanations. The special put_dummy_secrets_on_stack() function may be of particular interest to understand the leaked output and attack conditions.
Note: this section has been updated to include new information.
By our understanding, this issue was introduced via a combination of two commits:
This commit on Sep 8, 2020 (released with version 2.0.3)
This commit merged on Jan 1, 2023 (released with version 2.4.0)
Commit 1) introduces the weak tmp buffer initialization, and commit 2) introduces problematic code paths and makes the issue reachable.
The main patch improves the problematic code paths in get_attribute_opaque():
The described security issue affects the confidentiality of program memory. Due to the characteristics of the flaw, we think that program memory integrity and program availability is not impacted.
As with other memory- and library-related vulnerabilities, it is difficult to say generally what the sensitive information in memory is going to be, and how the leaked information will be processed or exposed by the caller. As a result, the practical worst-case impact will likely be very target-dependent.
The listed scoring maps the impact on a network-enabled integrating program which allows a remote user to trigger the affected functionality and obtain secrets after some form of authentication as a high-privileged user. Other integrating programs that use the PKCS#11 driver may have different impacts. For example, if a lower-privileged user can trigger the issue, PR: L would turn this into a 5.3 CVSS base score (calculator).
As outlined in the timeline, the first ~60 days out of the overall 90 days of disclosure did not see a lot of activity or feedback from the vendor side. This follows a pattern seen with previous coordinated disclosures to Yubico, which also had significant delays between reporting and technical discussion & assessment coordination with the vendor. We recommend focusing on a quicker initial handling for future disclosures to reduce the time pressure on coordination tasks.
We want to positively mention that Yubico has provided security patches and an advisory on the disclosure date for this disclosure, which is an improvement over the previous issue.
Credits and Commercial Work
During work on integration of YubiHSM2 into an OpenPGP project, Heiko Schäfer found the memory safety issue. Christian Reitter assisted with triage, issue analysis, coordinated disclosure and report writeup. In references to this issue, please credit “Heiko Schäfer and Christian Reitter”.
Heiko Schäfer is available for commercial work with a focus on OpenPGP and Rust: