As described in part one, I discovered in late 2018 through manual code analysis that the Yubico libu2f-host host-side C library contained an out of bounds write vulnerability.

Shortly after the fix was released in February 2019, I found a second, closely related vulnerability in the same code section which can result in information disclosure through leaked memory. MITRE assigned CVE-2019-9578 for this issue.

Consulting

I’m a freelance Security Consultant and currently available for new projects. If you are looking for assistance to secure your projects or organization, contact me.

The vulnerability

Please see the previous code descriptions in part one for the relevant background information.

After the 1.1.7 patch, the relevant part of init_device looked like this:

if (u2fh_sendrecv
    (devs, dev->id, U2FHID_INIT, nonce, sizeof (nonce), resp,
     &resplen) == U2FH_OK)
  {
    U2FHID_INIT_RESP initresp;
    if (resplen > sizeof (initresp))
    {
      return U2FH_MEMORY_ERROR;
    }
    memcpy (&initresp, resp, resplen);
    dev->cid = initresp.cid;
    dev->versionInterface = initresp.versionInterface;
    dev->versionMajor = initresp.versionMajor;
    dev->versionMinor = initresp.versionMinor;
    dev->capFlags = initresp.capFlags;
  }

devs.c

The if (resplen > sizeof (initresp)) guard condition prevents malicious inputs from overflowing the target struct by disallowing larger resplen values. This resolves the buffer overflow.

However, this code still allows a malicious U2F token to specify a smaller than expected resplen value.
If resplen is reported to be 0 by the token, the memcpy operation does not do anything and the initresp struct is used with its original uninitialized memory contents. As a consequence, previously discarded stack memory is written to dev->cid and other fields.

Since the CID is used during the following communication with the U2F token, four bytes of discarded stack memory are leaked to the USB bus. Similarly, other userspace programs might be able to obtain up to four bytes of leaked information via the version and capability fields exposed by the library.

Attack scenario and security implications

Similar to the previous vulnerability, the attack applies to host systems which use of libu2f-host through

  • an authentication module like pam_u2f.so (privileged execution)
  • other userspace applications that depend on libu2f-host such as yubikey-manager
  • the command-line tool bundled with libu2f-host

Any malicious USB device which enumerates as a recognized U2F token class can perform this attack (potentially repeatedly) to obtain discarded memory contents. libu2f-host versions before 1.1.7 are affected as well.

It is difficult to assess the exact practical impact of the leaked memory since the relevant memory contents are system- and execution-specific. To my knowledge, the information leak cannot be used to read into currently reserved memory such as the value of stack canaries, so it does not weaken protections that are relevant to the previously reported buffer overflow vulnerability.

CVSS score

I would rate this with a CVSSv3 score of 2.1 via AV:P/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N.

Mitigations

Stack canaries and other hardening techniques do not detect information leaks and therefore offer no meaningful protection. The use of Memory Sanitizer would detect and prevent the leaks, but Memory Sanitizer is not meant to be included as a hardening feature in production binaries.

Fingerprinting

As noted in the previous article, libu2f-host used a fixed “nonce” of { 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1 } to communicate with tokens, which gave tokens an excellent way to recognize the library. The fix briefly missed the 1.1.7 release, so the fingerprinting technique is still relevant for the information leak as well.

The nonce issue was fixed with the 1.1.8 release.

Responsible disclosure

I responsibly disclosed the vulnerability to Yubico in February.

Due to the lower severity, they did not issue a second security advisory. They agreed to track it with a second CVE, which I requested from MITRE. MITRE assigned CVE-2019-9578 for the issue.

The fix was shipped less than two weeks after the initial disclosure, which is a very decent time for an issue resolution.

Relevant projects

See the previous article for the full list of relevant sources.

product source fix vendor references CVE
Yubico libu2f-host library GitHub 1.1.8 via 1 Release notes CVE-2019-9578

Gentoo and Fedora included the fix in their patch releases for the previous vulnerability. SUSE issued a separate advisory.

Detailed timeline

Please see the timeline of the previous libu2f-host vulnerability article for reference.

Date info
2019-02-20 Second vulnerability is disclosed to Yubico
2019-02-21 Yubico confirms the issue
2019-03-05 Patched version 1.1.8 is released
2019-03-05 CVE is assigned by MITRE
2019-04-09 Fedora releases a patch for Fedora30
2019-05-19 Fedora releases a patch for Fedora29
2019-06-05 Gentoo switches to a patched version
2019-07-19 SUSE publishes a security advisory

Bug bounty

Yubico provided a number of their hardware products as a bug bounty for this issue.