Coordinated Disclosure Timeline
- 2021-02-04: Reported as private issue: https://gitlab.gnome.org/GNOME/glib/-/issues/2319
- 2021-02-04: Fix merged: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1926
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
- Ubuntu 20.04 (x86_64): version 2.64.6-1
- CentOS Stream (x86_64): version 2.56.4-9
- archlinux (x86_64): 2.66.4-2
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
- CVE-2021-27219
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.