Coordinated Disclosure Timeline
- 2021-11-08: Reported to Ubuntu using launchpad: issue 1950149.
- 2021-11-08: Acknowledged by Ubuntu security team.
- 2021-11-09: CVE-2021-3939 assigned.
- 2021-11-10: Coordinated disclosure planned for 2021-11-16 18:00:00 UTC.
- 2021-11-16: Fixed and disclosed.
- 2021-12-09: PoC published.
Summary
accountsservice has a double-free bug, which can be triggered by an unprivileged local user, by calling the SetLanguage
D-Bus method.
Product
Note: as far as we know, the bug only exists in Ubuntu’s fork of accountsservice. The bug is in a patch file named 0010-set-language.patch
, which we do not believe is included on other distributions, such as Debian.
Tested Version
0.6.55-0ubuntu13.2
Tested on Ubuntu 21.10
Details
Issue 1: double-free in the SetLanguage D-Bus method (GHSL-2021-1011
)
The function user_get_fallback_value
has a static variable named system_formats_locale
, which is allocated and initialized on the first call and then returned on subsequent calls:
static gchar *
user_get_fallback_value (User *user,
const gchar *property)
{
static gchar *system_language;
static gchar *system_formats_locale; <===== ONLY ALLOCATED ONCE
if (g_strcmp0 (property, "Language") == 0 && system_language)
return system_language;
if (g_strcmp0 (property, "FormatsLocale") == 0 && system_formats_locale)
return system_formats_locale; <===== RETURNED TO CALLER
...
Since this memory is only allocated once, it should not be freed by the caller. However, in user_change_language_authorized_cb
, the pointer is stored in a variable named fallback_locale
, which has a g_autofree
annotation, so the memory is freed at the end of the enclosing block:
if (!is_in_pam_environment (user, "FormatsLocale")) {
/* set the user formats (certain LC_* variables) explicitly
in order to prevent surprises when LANG is changed */
g_autofree gchar *fallback_locale = user_get_fallback_value (user, "FormatsLocale"); <===== NO ALLOC
g_autofree gchar *validated_locale = user_locale_validate (user, fallback_locale, context);
gchar *formats_locale = user_update_environment (user,
validated_locale,
"save-to-pam-env",
context);
if (formats_locale != NULL)
accounts_user_set_formats_locale (ACCOUNTS_USER (user), formats_locale);
<===== fallback_locale AUTOMATICALLY FREED HERE
}
This leads to a double free, if the SetLanguage
D-Bus method is called multiple times.
An unprivileged user can trigger the bug like this:
rm -f ~/.pam_environment
dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetLanguage string:hi
The first step, deleting ~/.pam_environment
, is required to trigger the vulnerable code path. If you run those instructions a few times accounts-daemon
will crash due to a double-free.
Impact
This is a memory corruption vulnerability in a process that runs with root privileges, so it could be exploited by an unprivileged local attacker to escalate privileges.
Issue 2: memory leak in user_update_environment
This issue is just a regular bug, not a security vulnerability, but it might be worth fixing at the same time as the other bug.
The function user_update_environment
allocates a string (in the local variable validated_data
) and returns it. At all three call sites of user_update_environment
the memory is not freed. The easiest one to trigger is this one in user_change_formats_locale_authorized_cb
:
gchar *locale = user_update_environment (user,
validated_locale,
"save-to-pam-env",
context);
You can (slowly) leak memory like this:
while true
do
dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetFormatsLocale string:en_US.UTF-8
dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts/User1001 org.freedesktop.Accounts.User.SetFormatsLocale string:en_GB.UTF-8
done
It leaks memory far too slowly to cause any problems, so from an attacker’s perspective it’s mainly of interest for heap grooming purposes. (The poc attached to this report does not use it though.)
CVE
- CVE-2021-3939
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-1011
in any communication regarding this issue.