Coordinated Disclosure Timeline
- 2023-06-16: reported to Ubuntu: https://bugs.launchpad.net/ubuntu/+source/accountsservice/+bug/2024182
- 2023-06-16: reply received
- 2023-06-16: CVE-2023-3297 assigned
- 2023-06-16: fix proposed
- 2023-06-28: CVE-2023-3297 disclosed
Summary
An unprivileged local attacker can trigger a use-after-free vulnerability in accountsservice by sending a D-Bus message to the accounts-daemon process.
Product
accountsservice
Tested Version
The bug is easier to observe on Ubuntu 23.04 than on Ubuntu 22.04 LTS, but it is present on both.
Details
Use-after-free when throw_error
is called (GHSL-2023-139
)
After receiving a D-Bus method call, a D-Bus server is expected to send either a METHOD_RETURN
or a ERROR
message back to the client, but not both. This is done incorrectly in several places in accountsservice. For example, in user_change_language_authorized_cb
:
static void
user_change_language_authorized_cb (Daemon *daemon,
User *user,
GDBusMethodInvocation *context,
gpointer data)
{
const gchar *language = data;
if (!user_HOME_available (user)) {
/* SetLanguage was probably called from a login greeter,
and HOME not mounted and/or not decrypted.
Hence don't save anything, or else accountsservice
and ~/.pam_environment would become out of sync. */
throw_error (context, ERROR_FAILED, "not access to HOME yet so language not saved"); <===== 1
goto out;
}
<snip>
out:
accounts_user_complete_set_language (ACCOUNTS_USER (user), context); <===== 2
}
If user_HOME_available
returns an error, then throw_error
is called at 1 to send an ERROR
message, but a regular METHOD_RETURN
is also sent at 2. This is incorrect D-Bus protocol, but the more serious problem is that it causes a use-after-free because both throw_error
and accounts_user_complete_set_language
decrease the reference count on context
. In other words, context
is freed by throw_error
and a UAF occurs in accounts_user_complete_set_language
.
An attacker can trigger the bug above by causing user_HOME_available
to fail, which they can do by deleting all the files from their home directory. But there are other incorrect uses of throw_error
in user.c
which are less inconvenient to trigger. For example, this command triggers a call to throw_error
in user_update_environment
due to the invalid characters in the string:
dbus-send --system --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts/User`id -u` org.freedesktop.Accounts.User.SetLanguage string:'**'
On Ubuntu 23.04, the above command causes accounts-daemon
to crash with a SIGSEGV
. But on Ubuntu 22.04 LTS it doesn’t cause any visible harm. The difference is due to a recent change in GLib’s memory allocation: older versions of GLib used the “slice” allocator, but newer version uses the system allocator. The system allocator trashes the memory when it’s freed in a way that causes the use-after-free to trigger a SIGSEGV, whereas the “slice” allocator trashes the memory in a way that causes the UAF to go unnoticed.
Impact
Exploitation is likely to be difficult, but this bug could potentially enable a local unprivileged attacker to gain root privileges.
CVE
- CVE-2023-3297
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-2023-139
in any communication regarding this issue.