** Information type changed from Private Security to Public Security -- You received this bug notification because you are a member of Desktop Packages, which is subscribed to accountsservice in Ubuntu. https://bugs.launchpad.net/bugs/1900255
Title: accountsservice drop privileges denial of service (GHSL-2020-187, GHSL-2020-188) Status in accountsservice package in Ubuntu: Fix Released Bug description: # GitHub Security Lab (GHSL) Vulnerability Report: `GHSL-2020-187`, `GHSL-2020-188` The [GitHub Security Lab](https://securitylab.github.com) team has identified potential security vulnerabilities in [accountsservice](https://git.launchpad.net/ubuntu/+source/accountsservice/). We are committed to working with you to help resolve these issues. In this report you will find everything you need to effectively coordinate a resolution of these issues with the GHSL team. If at any point you have concerns or questions about this process, please do not hesitate to reach out to us at `security...@github.com` (please include `GHSL-2020-187` or `GHSL-2020-188` as a reference). If you are _NOT_ the correct point of contact for this report, please let us know! ## Summary The accountsservice daemon drops privileges to perform certain operations. For example while performing the `org.freedesktop.Accounts.User.SetLanguage` D-Bus method, which can be triggered by an unprivileged user, accounts-daemon temporarily drops privileges to the same UID as the user, to avoid being tricked into opening a file which the unprivileged user should not be able to access. Unfortunately, by changing its [RUID](https://en.wikipedia.org/wiki/User_identifier#Real_user_ID) it has given the user permission to send it signals. This means that the unprivileged user can send accounts-daemon a `SIGSTOP` signal, which stops the process and causes a denial of service. ## Product [accountsservice](https://git.launchpad.net/ubuntu/+source/accountsservice/) ## Tested Version * accountsservice, version 0.6.55-0ubuntu12~20.04.1 * Tested on Ubuntu 20.04.1 LTS Note: I believe these issues only exist in Ubuntu's version of accountsservice. I couldn't find the vulnerable functions in the git repos maintained by [freedesktop](https://gitlab.freedesktop.org/accountsservice/accountsservice) or [debian](https://salsa.debian.org/freedesktop- team/accountsservice). I originally discovered the vulnerable code in the version of the code that I had obtained by running `apt-get source accountsservice`, but I struggled to figure out where it came from when I started searching the official repositories. I eventually tracked it down to this patch file: [0010-set- language.patch](https://git.launchpad.net/ubuntu/+source/accountsservice/tree/debian/patches/0010 -set-language.patch?h=ubuntu/focal- updates&id=e0347185d4c5554b026c13ccca691577c239afd5). ## Details ### Issue 1: accountsservice drop privileges `SIGSTOP` denial of service (`GHSL-2020-187`) A [source code patch](https://git.launchpad.net/ubuntu/+source/accountsservice/tree/debian/patches/0010 -set-language.patch?h=ubuntu/focal- updates&id=e0347185d4c5554b026c13ccca691577c239afd5) that (as far as I know) only exists in Ubuntu's version of accountsservice, adds a function named [`user_drop_privileges_to_user`](https://git.launchpad.net/ubuntu/+source/accountsservice/tree/debian/patches/0010 -set-language.patch?h=ubuntu/focal- updates&id=e0347185d4c5554b026c13ccca691577c239afd5#n66): ```c static gboolean user_drop_privileges_to_user (User *user) { if (setresgid (user->gid, user->gid, -1) != 0) { g_warning ("setresgid() failed"); return FALSE; } if (setresuid (accounts_user_get_uid (ACCOUNTS_USER (user)), accounts_user_get_uid (ACCOUNTS_USER (user)), -1) != 0) { g_warning ("setresuid() failed"); return FALSE; } return TRUE; } ``` This function is used to drop privileges while doing operations on behalf of an unprivileged user. Dropping the [EUID](https://en.wikipedia.org/wiki/User_identifier#Effective_user_ID) is a sensible precaution, which prevents accountsservice from accessing a file which the unprivileged user cannot access themselves. Unfortunately, dropping the [RUID](https://en.wikipedia.org/wiki/User_identifier#Real_user_ID) has the opposite effect of making security worse, because it enables the unprivileged user to send signals to accountsservice. For example, they can send a `SIGSTOP` which stops the accountsservice daemon and causes a denial of service. The vulnerability can be triggered via multiple different D-Bus methods. Many of them involve precise timing to send the `SIGSTOP` signal at just the right moment. But there is a much simpler and more reliable way to reproduce the vulnerability by combining the privilege dropping vulnerability (`GHSL-2020-187`) with the infinite loop vulnerability (`GHSL-2020-188`), which is described next. So please see the description of `GHSL-2020-188`, below, for a proof-of-concept that triggers both vulnerabilities. #### Impact An unprivileged local user can cause a local denial of service that affects all users of the system. Stopping the accountsservice daemon prevents the login screen from working, because `gdm3` needs to talk to accounts-daemon (via D-Bus). Unfortunately, the impact is worse than just local denial of service, because this vulnerability can be chained with a separate vulnerability in gdm3 to achieve privilege escalation. Please see the description of `GHSL-2020-188`, below, for a proof-of-concept of the privilege escalation vulnerability. #### Remediation When dropping privileges, only drop the EUID and not the RUID. ### Issue 2: accountsservice `.pam_environment` infinite loop (GHSL-2020-188) A [source code patch](https://git.launchpad.net/ubuntu/+source/accountsservice/tree/debian/patches/0010 -set-language.patch?h=ubuntu/focal- updates&id=e0347185d4c5554b026c13ccca691577c239afd5) that (as far as I know) only exists in Ubuntu's version of accountsservice, adds a function named [`is_in_pam_environment`](https://git.launchpad.net/ubuntu/+source/accountsservice/tree/debian/patches/0010 -set-language.patch?h=ubuntu/focal- updates&id=e0347185d4c5554b026c13ccca691577c239afd5#n366): ```c static gboolean is_in_pam_environment (User *user, const gchar *property) { gboolean ret = FALSE; const gchar *prefix; FILE *fp; g_autofree gchar *pam_env = NULL; if (g_strcmp0 (property, "Language") == 0) prefix = "LANG"; else if (g_strcmp0 (property, "FormatsLocale") == 0) prefix = "LC_TIME"; else return FALSE; pam_env = g_build_path ("/", accounts_user_get_home_directory (ACCOUNTS_USER (user)), ".pam_environment", NULL); if (!user_drop_privileges_to_user (user)) return FALSE; if ((fp = fopen (pam_env, "r"))) { gchar line[50]; while ((fgets (line, 50, fp)) != NULL) { if (g_str_has_prefix (line, prefix)) { ret = TRUE; break; } } fclose (fp); } user_regain_privileges (); return ret; } ``` This function parses the contents of a file named `.pam_environment` in the (unprivileged) user's home directory. The user can trigger an infinite loop by creating a symlink to `/dev/zero`: ```bash ln -s /dev/zero ~/.pam_environment ``` The infinite loop can then be triggered by sending a D-Bus message to the accountsservice daemon: ```bash dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply=literal /org/freedesktop/Accounts/User`id -u` org.freedesktop.Accounts.User.SetLanguage string:kevwozere & ``` Because the accountsservice daemon is now stuck in an infinite loop, and has dropped privileges, it is now easy to also demonstrate `GHSL-2020-187`: ```bash kill -SIGSTOP `pidof accounts-daemon` ``` The accountsservice daemon is now unresponsive, which means that the GNOME login screen no longer works. Unfortunately, this vulnerability can be chained with a separate vulnerability in gdm3 (which I have reported simultaneously to GNOME) to get privilege escalation. The steps (tested on Ubuntu Desktop 20.04.1 LTS) are as follows: * An unprivileged user logs into their account. * They send a `SIGSTOP` to accountsservice, using the instructions above. * They log out of their account. * They open a text console (usually with a key combination such as Ctrl-Alt-F3). * They login to the text console. * They send accounts-daemon a `SIGSEGV`, followed by a `SIGCONT`, which causes accounts-daemon to crash. * Because the accountsservice daemon was unresponsive, gdm3 is under the mistaken impression that there are zero user accounts on the system. So it triggers `gnome-initial-setup`, because it thinks this is a first-time installation. * The user clicks through the `gnome-initial-setup` dialog boxes and creates a new account for themselves. The new account is a member of the `sudo` group. I have made a video of this proof-of-concept, which you can see [here](https://drive.google.com/file/d/1rpRbXW1PRKMKRcxft3x- 9tprjEbHLgOQ/view?usp=sharing). The video is only visible to people who have the link, so it as safe as long as you are careful who you share the link with. #### Impact An unprivileged local user can cause a local denial of service that affects all users of the system. Making the accountsservice daemon unresponsive prevents the login screen from working, because `gdm3` needs to talk to accounts-daemon (via D-Bus). Unfortunately, the impact is worse than just local denial of service, because this vulnerability can be chained with a separate vulnerability in gdm3 to achieve privilege escalation, as explained in the proof-of-concept above. #### Remediation I would recommend using `fstat` to check that the file is a regular file before reading it. ## Credit These issues were discovered and reported by GHSL team member [@kevinbackhouse (Kevin Backhouse)](https://github.com/kevinbackhouse). ## Contact You can contact the GHSL team at `security...@github.com`, please include a reference to `GHSL-2020-187` or `GHSL-2020-188`in any communication regarding this issue. ## Disclosure Policy This report is subject to our [coordinated disclosure policy](https://securitylab.github.com/disclosures#policy). To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/accountsservice/+bug/1900255/+subscriptions -- Mailing list: https://launchpad.net/~desktop-packages Post to : desktop-packages@lists.launchpad.net Unsubscribe : https://launchpad.net/~desktop-packages More help : https://help.launchpad.net/ListHelp