{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreig4xot3hal3lypdaqn7pgj53zckx5leh3qyz6pvahoe2sx3yytgoy",
"uri": "at://did:plc:3pjw65epwlo3rzajhx6xg4br/app.bsky.feed.post/3mjmvfguii3r2"
},
"path": "/2026/04/16/cosmic-greeter.html",
"publishedAt": "2026-04-16T00:00:00.000Z",
"site": "https://security.opensuse.org",
"tags": [
"a Linux desktop environment",
"a D-Bus service",
"cosmic-greeter",
"daemon/src/main.rs",
"method does",
"a comment",
"as regular user\naccounts",
"commit 63cd93bddd0",
"upstream release 1.0.9",
"Cosmic Website",
"openSUSE cosmic-greeter review bug",
"cosmic-greeter privilege drop bugfix",
"Upstream Release 1.0.9 containing the bugfix"
],
"textContent": "# Table of Contents\n\n * Introduction\n * Overview\n * Security Issues\n * Suggested Fixes\n * Upstream Bugfix\n * CVE Assignment\n * Timeline\n * References\n\n\n\n# Introduction\n\nCosmic is a Linux desktop environment written in the Rust programming language. There is an ongoing effort to package it for openSUSE Tumbleweed; in this context we reviewed a number of Cosmic components, among them a D-Bus service found in cosmic-greeter. We found issues when the service accesses home directories of unprivileged users, which will be described further below. This report is based on cosmic-greeter version 1.0.8.\n\n# Overview\n\n`cosmic-greeter-daemon` is implemented in daemon/src/main.rs, runs with full root privileges and offers a D-Bus interface “com.system76.CosmicGreeter” on the D-Bus system bus. The interface only provides a single D-Bus method “com.system76.CosmicGreeter.GetUserData”.\n\nThis D-Bus method is only allowed to be called by members of the `cosmic-greeter` group, not by arbitrary other unprivileged users. What the method does is basically looking up all non-system user accounts in `/etc/passwd` and gathering Cosmic configuration data from every user’s home directory.\n\n# Security Issues\n\nThe code contains a comment, outlining that it is important to drop privileges to the owner of the home directory being processed, to prevent security issues. While this is a good starting point, the actual implementation of this logic is still lacking in a number of spots.\n\nFollowing is an excerpt of an `strace` of the `cosmic-greeter-daemon` process during invocation of the D-Bus method. The output will help illustrate some of the issues in question:\n\n\n setresuid(-1, 1000, -1) = 0\n <...>\n statx(AT_FDCWD, \"/var/lib/AccountsService/icons/<user>\", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7feb5d5f8a50) = -1 ENOENT (No such file or directory)\n statx(AT_FDCWD, \"/home/<user>/.local/share/cosmic/com.system76.CosmicTheme.Mode/v1\", AT_STATX_SYNC_AS_STAT, STATX_ALL, 0x7feb5d5f8800) = -1 ENOENT (No such file or directory)\n mkdir(\"/home/<user>/.config/cosmic/com.system76.CosmicTheme.Mode/v1\", 0777) = -1 EEXIST (File exists)\n statx(AT_FDCWD, \"/home/<user>/.config/cosmic/com.system76.CosmicTheme.Mode/v1\", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0755, stx_size=4096, ...}) = 0\n statx(AT_FDCWD, \"/home/<user>/.config/cosmic/com.system76.CosmicTheme.Mode/v1/is_dark\", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFCHR|0666, stx_size=0, ...}) = 0\n mkdir(\"/home/<user>/.config/cosmic/com.system76.CosmicTheme.Dark/v1\", 0777) = -1 EEXIST (File exists)\n openat(AT_FDCWD, \"/home/<user>/.config/cosmic/com.system76.CosmicTheme.Dark/v1/palette\", O_RDONLY|O_CLOEXEC) = 11\n <...>\n setresuid(-1, 0, -1 <unfinished ...>\n\n\nWhat we are seeing here is that the privilege drop only concerns the effective user ID of the `cosmic-greeter-daemon` process. The root group credentials are retained. This means any potential attacks by the owner of a home directory can still try to leverage root group credentials to their advantage.\n\nGiven this, the file operations performed in the user’s home directory are subject to a range of security issues:\n\n * directory components within the path can be replaced by symbolic links. E.g. if a user places a symlink like this:\n\n $HOME/.config/cosmic → /root/.config/cosmic\n\n\nthen the daemon would actually process root’s Cosmic configuration files, provided that root’s home directory is accessible for members of the root group.\n\n * since the daemon also attempts to create directories under some conditions, these directories could be created in arbitrary locations where the root group has write permission.\n * the daemon checks the type of files via `stat()` before trying to open configuration files, for example. This is a typical Time-of-Check/Time-of-Use (TOCTOU) race condition, however, because the owner of the home directory can attempt to replace a regular file by a symbolic link or special file by the time the actual `open()` call is performed by the daemon. This can lead to the following potential issues:\n * parsing of private files accessible to the root group. Whether the data parsed from such files could ever leak into the context of a local attacker is a matter that we did not investigate more closely for the purpose of this report.\n * by placing a symbolic link to e.g. `/dev/zero`, an out-of-memory situation can be triggered in the daemon, causing it to be killed by the kernel, leading to a local Denial-of-Service (DoS).\n * by placing a FIFO named pipe in the location the daemon would block on it forever, also leading to a local DoS.\n * the daemon considers accounts with user IDs ≥ 1000 as regular user\naccounts. On many Linux distributions this means that also the `nobody` user account is included (UID 65534). As a result, the daemon also attempts to process Cosmic configuration in `/var/lib/nobody` on OpenSUSE. This grants processes operating with `nobody` privileges the opportunity to attempt to exploit the daemon’s logic.\n\n\n\nThe severity of these issues is reduced by the fact that only members of the `cosmic-greeter` group are allowed to invoke the `GetUserData` D-Bus method, thus potential attackers have to wait for an authorized process to call the function to attempt to exploit it. We don’t have enough insight into the bigger picture of the Cosmic desktop environment, but it could be possible that local users are able to indirectly trigger the execution of this D-Bus method by using other APIs made available by Cosmic.\n\n# Suggested Fixes\n\nWe suggested the following improvements to upstream to deal with the issues:\n\n * the privileges should be fully dropped to the target user account, including group ID and the supplementary group IDs.\n * to prevent potential DoS attack surface, the daemon should carefully open target paths element by element, passing `O_NOFOLLOW|O_NONBLOCK` to prevent symlink attacks, then perform an `fstat()` on the open file to determine its type in a race-free fashion.\n * the `nobody` user account should be explicitly excluded based on its name for distributions that set a valid shell for this account.\n * as additional hardening, the systemd unit `cosmic-greeter-daemon.service` can be extended with directives like `ProtectSystem=full`. This needs some tuning, though, since the daemon still needs to be able to read files in home directories of other users.\n\n\n\n# Upstream Bugfix\n\nUpstream implemented commit 63cd93bddd0 containing the following changes:\n\n * the daemon properly drops its group and supplementary group IDs to the target user’s.\n * only user IDs in the range defined by `UID_MIN` and `UID_MAX` as configured in `/etc/login.defs` will be considered.\n * icon files in `/var/lib/accountservice` will be opened with `O_NOFOLLOW` (actually an unrelated change / security hardening).\n\n\n\nThis bugfix is part of upstream release 1.0.9 and newer.\n\nWhat is still missing from our point of view is the prevention of local DoS attack surface when accessing files in the user’s home directory. We informed upstream about this but have not heard back about this topic for a while.\n\n# CVE Assignment\n\nUpstream has not expressed any wishes regarding CVE assignment, or whether one should be assigned at all. We decided to assign a single CVE-2026-25704 from our pool to track the main aspect of this report, the incomplete privilege drop in the daemon.\n\n# Timeline\n\n2026-03-11 | We forwarded this report to security@system76.com and the main developer of cosmic-greeter, offering coordinated disclosure.\n---|---\n2026-03-11 | Upstream confirmed the issue and opted out of coordinated disclosure.\n2026-03-11 | We got a follow-up response asking us to keep the information private for while longer after all.\n2026-03-11 | We received a patch from upstream corresponding to commit 63cd93bddd0 and have been asked to review it.\n2026-03-12 | Upstream meanwhile created a public pull request based on this bugfix and informed us that the report no longer needed to be private.\n2026-03-13 | We assigned CVE-2026-25704 to track the main aspect of the vulnerability, an incomplete privilege drop.\n2026-03-13 | We shared the CVE with upstream and provided feedback on the bugfix, mainly pointing out that local Denial-of-Service (DoS) attack service still remains.\n2026-03-13 | Upstream informed us that they are going to address these remaining issues as well.\n2026-03-24 | We asked upstream about the status of the additional fixes, but received no response so far.\n2026-04-16 | Publication of this report.\n\n# References\n\n * Cosmic Website\n * openSUSE cosmic-greeter review bug\n * cosmic-greeter privilege drop bugfix\n * Upstream Release 1.0.9 containing the bugfix\n\n",
"title": "cosmic-greeter: Unsafe File System Operations in User Home Directories (CVE-2026-25704)"
}