skip to content
Back to GitHub.com
Home Bounties CodeQL Research Advisories Get Involved Events
March 25, 2021

GHSL-2021-045: Integer Overflow in GLib - CVE-2021-27219

Kevin Backhouse

Coordinated Disclosure Timeline

Summary

The function g_bytes_new has an integer overflow due to an implicit cast from 64 bits to 32 bits. The overflow could potentially lead to a memory corruption vulnerability.

Product

GLib

Tested Versions

Details

Issue 1: Integer overflow in g_bytes_new (GHSL-2021-045)

On 64-bit platforms, an integer overflow can occur in g_bytes_new, due to an implicit cast from gsize to guint. The overflow happens in the call to g_memdup (gbytes.c, line 98). The reason is that size is a 64-bit gsize, but g_memdup takes a 32-bit guint.

GBytes *
g_bytes_new (gconstpointer data,
             gsize         size)
{
  g_return_val_if_fail (data != NULL || size == 0, NULL);

  return g_bytes_new_take (g_memdup (data, size), size);  <===  integer overflow
}

When the overflow occurs, it does not cause the code to crash immediately. Instead, g_memdup creates a much smaller buffer than it should. This causes g_bytes_new to return a GBytes object containing a much smaller data buffer than it’s size would suggest. For example, if size is 0x100000008 then g_bytes_new will return a GBytes object that claims to contain a 4GB buffer, but actually contains an 8 byte buffer.

We have attached a proof-of-concept which demonstrates that it is possible to trigger the overflow. The proof-of-concept triggers the overflow via polkit-agent-helper-1, which is a SUID binary. Luckily the poc only causes polkit-agent-helper-1 to crash with a SIGABRT, due to an assertion failure. However, GLib is a very widely used library, so it is possible that other attack vectors exist.

To run the poc:

gcc polkithelperabort.c -o polkithelperabort
./polkithelperabort <username>

The poc will ask for the user’s password, which is sent to polkit-agent-helper-1 in the normal way, along with a 4GB “cookie”, which triggers the overflow. Although the poc will only work with a valid password, it will work for any user account. So if you are worried about plugging a genuine password into the poc, just create a temporary user account for running the poc, and delete it when you are done.

The poc should trigger an assertion failure, with an error message like this:

GLib-GIO:ERROR:../glib/gio/gdbusmessage.c:2399:append_value_to_blob: assertion failed: (g_utf8_validate (v, -1, &end) && (end == v + len))
Bail out! GLib-GIO:ERROR:../glib/gio/gdbusmessage.c:2399:append_value_to_blob: assertion failed: (g_utf8_validate (v, -1, &end) && (end == v + len))

Impact

The poc which we have provided only causes a harmless crash. We are not currently aware of an exploitable attack vector for this issue. However, there is a risk that it could lead to memory corruption vulnerability, which could potentially be used to gain code execution in an application that uses GLib.

Resources

Source code for poc: polkithelperabort.c

CVE

Credit

This issue was discovered and reported by GHSL team member @kevinbackhouse (Kevin Backhouse).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2021-045 in any communication regarding this issue.