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.

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.