Package: release.debian.org Severity: normal X-Debbugs-Cc: scr...@packages.debian.org, Axel Beckert (Debian Developer) <a...@debian.org>, Christian Hofstaedtler <z...@debian.org>, debian-b...@lists.debian.org, k...@debian.org, car...@debian.org Control: affects -1 + src:screen User: release.debian....@packages.debian.org Usertags: unblock
Hi Release team, [Cc'ing as well debian-boot and Cyril, as screen produces a udeb and needs an ack for d-i, additionally we are freezing udebs for the d-i preparation] Please unblock package screen screen as announced in [oss-security] is affected by several vulnerabilities, furtunately by default in Debian screen is not installed setuid. We think that having fixes for those (and later maybe via point release in bookworm as well) might be sensible. The concrete CVEs are CVE-2025-46802, CVE-2025-46804 and CVE-2025-46805. [oss-security]: <https://www.openwall.com/lists/oss-security/2025/05/12/1> One very important remark for the CVE-2025-46802 patches, from the finding: | Shortly before the publication of this report it was pointed out to us | that this patch likely breaks some reattach use cases [12] in screen. | We can confirm this problem, but at the same time found out that this | specific use case was obviously already broken before, even in Screen | 4.9.1 [13]. For this reason we decided not to move the publication | date again or to adjust this patch in a hurry with uncertain results. | The patch still fixes the security issue and upstream can now fix this | regression, that already seems to have existed earlier, in the open. Additionally there is an Upload from Chris Hofstaedtler <z...@debian.org> which has not yet migrated to testing (but would if the additional time would pass without RC report). Talking with Chris he would be fine to have additional time to wait for his change to go in and so the we can either wait for the second upload and first make 4.9.1-2 go to testing or override the upload. Currently with the udeb freeze it cannot move anyway. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] Talking to Axel, I might not do the actual upload but the upload might come from the maintainer himself (very welcome, thanks Axel!) so there would be the making it a maintainer upload. unblock screen/4.9.1-2.1 Let us know if you need anything else for clarification. Regards, Salvatore
diff -Nru screen-4.9.1/debian/changelog screen-4.9.1/debian/changelog --- screen-4.9.1/debian/changelog 2025-05-10 22:28:23.000000000 +0200 +++ screen-4.9.1/debian/changelog 2025-05-16 17:46:51.000000000 +0200 @@ -1,3 +1,13 @@ +screen (4.9.1-2.1) unstable; urgency=medium + + * Non-maintainer upload (with maintainers approval) + * attacher.c - prevent temporary 0666 mode on PTYs (CVE-2025-46802) + (Closes: #1105191) + * avoid file existence test information leaks (CVE-2025-46804) + * socket.c - don't send signals with root privileges (CVE-2025-46805) + + -- Salvatore Bonaccorso <car...@debian.org> Fri, 16 May 2025 17:46:51 +0200 + screen (4.9.1-2) unstable; urgency=medium * Team upload (debian/ namespace). diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,134 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:15:38 +0200 +Subject: fix CVE-2025-46802: attacher.c - prevent temporary 0666 mode on PTYs +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=049b26b22e197ba3be9c46e5c193032e01a4724a +Bug-Debian: https://bugs.debian.org/1105191 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46802 + +This temporary chmod of the PTY to mode 0666 is most likely a remnant of +past times, before the PTY file descriptor was passed to the target +session via the UNIX domain socket. + +This chmod() causes a race condition during which any other user in the +system can open the PTY for reading and writing, and thus allows PTY +hijacking. + +Simply remove this logic completely. +--- + src/attacher.c | 27 --------------------------- + src/screen.c | 19 ------------------- + 2 files changed, 46 deletions(-) + +--- a/attacher.c ++++ b/attacher.c +@@ -73,7 +73,6 @@ extern int MasterPid, attach_fd; + #ifdef MULTIUSER + extern char *multi; + extern int multiattach, multi_uid, own_uid; +-extern int tty_mode, tty_oldmode; + # ifndef USE_SETEUID + static int multipipe[2]; + # endif +@@ -160,9 +159,6 @@ int how; + + if (pipe(multipipe)) + Panic(errno, "pipe"); +- if (chmod(attach_tty, 0666)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = tty_mode; + eff_uid = -1; /* make UserContext fork */ + real_uid = multi_uid; + if ((ret = UserContext()) <= 0) +@@ -174,11 +170,6 @@ int how; + Panic(errno, "UserContext"); + close(multipipe[1]); + read(multipipe[0], &dummy, 1); +- if (tty_oldmode >= 0) +- { +- chmod(attach_tty, tty_oldmode); +- tty_oldmode = -1; +- } + ret = UserStatus(); + #ifdef LOCK + if (ret == SIG_LOCK) +@@ -224,9 +215,6 @@ int how; + xseteuid(multi_uid); + xseteuid(own_uid); + #endif +- if (chmod(attach_tty, 0666)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = tty_mode; + } + # endif /* USE_SETEUID */ + #endif /* MULTIUSER */ +@@ -423,13 +411,6 @@ int how; + ContinuePlease = 0; + # ifndef USE_SETEUID + close(multipipe[1]); +-# else +- xseteuid(own_uid); +- if (tty_oldmode >= 0) +- if (chmod(attach_tty, tty_oldmode)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = -1; +- xseteuid(real_uid); + # endif + } + #endif +@@ -505,14 +486,6 @@ AttacherFinit SIGDEFARG + close(s); + } + } +-#ifdef MULTIUSER +- if (tty_oldmode >= 0) +- { +- if (setuid(own_uid)) +- Panic(errno, "setuid"); +- chmod(attach_tty, tty_oldmode); +- } +-#endif + exit(0); + SIGRETURN; + } +--- a/screen.c ++++ b/screen.c +@@ -230,8 +230,6 @@ char *multi_home; + int multi_uid; + int own_uid; + int multiattach; +-int tty_mode; +-int tty_oldmode = -1; + #endif + + char HostName[MAXSTR]; +@@ -1009,9 +1007,6 @@ int main(int ac, char** av) + + /* ttyname implies isatty */ + SetTtyname(true, &st); +-#ifdef MULTIUSER +- tty_mode = (int)st.st_mode & 0777; +-#endif + + fl = fcntl(0, F_GETFL, 0); + if (fl != -1 && (fl & (O_RDWR|O_RDONLY|O_WRONLY)) == O_RDWR) +@@ -2170,20 +2165,6 @@ DEFINE_VARARGS_FN(Panic) + if (D_userpid) + Kill(D_userpid, SIG_BYE); + } +-#ifdef MULTIUSER +- if (tty_oldmode >= 0) { +- +-# ifdef USE_SETEUID +- if (setuid(own_uid)) +- xseteuid(own_uid); /* may be a loop. sigh. */ +-# else +- setuid(own_uid); +-# endif +- +- debug1("Panic: changing back modes from %s\n", attach_tty); +- chmod(attach_tty, tty_oldmode); +- } +-#endif + eexit(1); + } + diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,118 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:26:11 +0200 +Subject: fix CVE-2025-46804: avoid file existence test information leaks +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=e0eef5aac453fa98a2664416a56c50ad1d00cb30 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46804 + +In setuid-root context the current error messages give away whether +certain paths not accessible by the real user exist and what type they +have. To prevent this only output generic error messages in setuid-root +context. + +In some situations, when an error is pertaining a directory and the +directory is owner by the real user then we can still output more +detailed diagnostics. + +This change can lead to less helpful error messages when Screen is +install setuid-root. More complex changes would be needed to avoid this +(e.g. only open the `SocketPath` with raised privileges when +multi-attach is requested). + +There might still be lingering some code paths that allow such +information leaks, since `SocketPath` is a global variable that is used +across the code base. The majority of issues should be caught with this +fix, however. +--- + src/screen.c | 45 ++++++++++++++++++++++++++++++++++----------- + src/socket.c | 9 +++++++-- + 2 files changed, 41 insertions(+), 13 deletions(-) + +--- a/screen.c ++++ b/screen.c +@@ -1122,15 +1122,28 @@ int main(int ac, char** av) + #endif + } + +- if (stat(SockPath, &st) == -1) +- Panic(errno, "Cannot access %s", SockPath); +- else +- if (!S_ISDIR(st.st_mode)) ++ if (stat(SockPath, &st) == -1) { ++ if (eff_uid == real_uid) { ++ Panic(errno, "Cannot access %s", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } else if (!S_ISDIR(st.st_mode)) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { + Panic(0, "%s is not a directory.", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + #ifdef MULTIUSER + if (multi) { +- if ((int)st.st_uid != multi_uid) +- Panic(0, "%s is not the owner of %s.", multi, SockPath); ++ if ((int)st.st_uid != multi_uid) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "%s is not the owner of %s.", multi, SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + } + else + #endif +@@ -1144,9 +1157,13 @@ int main(int ac, char** av) + Panic(0, "You are not the owner of %s.", SockPath); + #endif + } +- +- if ((st.st_mode & 0777) != 0700) +- Panic(0, "Directory %s must have mode 700.", SockPath); ++ if ((st.st_mode & 0777) != 0700) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "Directory %s must have mode 700.", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + if (SockMatch && index(SockMatch, '/')) + Panic(0, "Bad session name '%s'", SockMatch); + SockName = SockPath + strlen(SockPath) + 1; +@@ -1184,8 +1201,14 @@ int main(int ac, char** av) + else + exit(9 + (fo || oth ? 1 : 0) + fo); + } +- if (fo == 0) +- Panic(0, "No Sockets found in %s.\n", SockPath); ++ if (fo == 0) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "No Sockets found in %s.\n", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } ++ + Msg(0, "%d Socket%s in %s.", fo, fo > 1 ? "s" : "", SockPath); + eexit(0); + } +--- a/socket.c ++++ b/socket.c +@@ -171,8 +171,13 @@ bool *is_sock; + xsetegid(real_gid); + #endif + +- if ((dirp = opendir(SockPath)) == 0) +- Panic(errno, "Cannot opendir %s", SockPath); ++ if ((dirp = opendir(SockPath)) == 0) { ++ if (eff_uid == real_uid) { ++ Panic(errno, "Cannot opendir %s", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + + slist = schosen = NULL; + slisttail = &slist; diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,113 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:38:19 +0200 +Subject: fix CVE-2025-46805: socket.c - don't send signals with root + privileges +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=161f85b98b7e1d5e4893aeed20f4cdb5e3dfaaa4 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46805 + +The CheckPid() function was introduced to address CVE-2023-24626, to +prevent sending SIGCONT and SIGHUP to arbitrary PIDs in the system. This +fix still suffers from a TOCTOU race condition. The client can replace +itself by a privileged process, or try to cycle PIDs until a privileged +process receives the original PID. + +To prevent this, always send signals using the real privileges. Keep +CheckPid() for error diagnostics. If sending the actual signal fails +later on then there will be no more error reporting. + +It seems the original bugfix already introduced a regression when +attaching to another's user session that is not owned by root. In this +case the target sessions runs with real uid X, while for sending a +signal to the `pid` provided by the client real uid Y (or root +privileges) are required. + +This is hard to properly fix without this regression. On Linux pidfds +could be used to allow safely sending signals to other PIDs as root +without involving race conditions. In this case the client PID should +also be obtained via the UNIX domain socket's SO_PEERCRED option, +though. +--- + src/socket.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +--- a/socket.c ++++ b/socket.c +@@ -832,6 +832,11 @@ int pid; + return UserStatus(); + } + ++static void KillUnpriv(pid_t pid, int sig) { ++ UserContext(); ++ UserReturn(kill(pid, sig)); ++} ++ + #ifdef hpux + /* + * From: "F. K. Bruner" <nap...@ugcs.caltech.edu> +@@ -917,14 +922,14 @@ struct win *wi; + { + Msg(errno, "Could not perform necessary sanity checks on pts device."); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + if (strcmp(ttyname_in_ns, m->m_tty)) + { + Msg(errno, "Attach: passed fd does not match tty: %s - %s!", ttyname_in_ns, m->m_tty[0] != '\0' ? m->m_tty : "(null)"); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + /* m->m_tty so far contains the actual name of the pts device in the +@@ -941,19 +946,19 @@ struct win *wi; + { + Msg(errno, "Attach: passed fd does not match tty: %s - %s!", m->m_tty, myttyname ? myttyname : "NULL"); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + } + else if ((i = secopen(m->m_tty, O_RDWR | O_NONBLOCK, 0)) < 0) + { + Msg(errno, "Attach: Could not open %s!", m->m_tty); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + #ifdef MULTIUSER + if (attach) +- Kill(pid, SIGCONT); ++ KillUnpriv(pid, SIGCONT); + #endif + + #if defined(ultrix) || defined(pyr) || defined(NeXT) +@@ -966,7 +971,7 @@ struct win *wi; + { + write(i, "Attaching from inside of screen?\n", 33); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + Msg(0, "Attach msg ignored: coming from inside."); + return -1; + } +@@ -977,7 +982,7 @@ struct win *wi; + { + write(i, "Access to session denied.\n", 26); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + Msg(0, "Attach: access denied for user %s.", user); + return -1; + } +@@ -1295,7 +1300,7 @@ ReceiveMsg() + Msg(0, "Query attempt with bad pid(%d)!", m.m.command.apid); + } + else { +- Kill(m.m.command.apid, ++ KillUnpriv(m.m.command.apid, + (queryflag >= 0) + ? SIGCONT + : SIG_BYE); /* Send SIG_BYE if an error happened */ diff -Nru screen-4.9.1/debian/patches/series screen-4.9.1/debian/patches/series --- screen-4.9.1/debian/patches/series 2025-05-10 22:23:13.000000000 +0200 +++ screen-4.9.1/debian/patches/series 2025-05-16 17:46:51.000000000 +0200 @@ -15,3 +15,6 @@ 81_session_creation_util.patch 82_session_creation_core.patch 85_bracketed-paste-patch-by-Unit193_dpaste.com_5KJ572GZM.patch +fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch +fix-CVE-2025-46804-avoid-file-existence-test-informa.patch +fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch
diff -Nru screen-4.9.1/debian/changelog screen-4.9.1/debian/changelog --- screen-4.9.1/debian/changelog 2023-09-07 00:10:56.000000000 +0200 +++ screen-4.9.1/debian/changelog 2025-05-16 17:46:51.000000000 +0200 @@ -1,3 +1,23 @@ +screen (4.9.1-2.1) unstable; urgency=medium + + * Non-maintainer upload (with maintainers approval) + * attacher.c - prevent temporary 0666 mode on PTYs (CVE-2025-46802) + (Closes: #1105191) + * avoid file existence test information leaks (CVE-2025-46804) + * socket.c - don't send signals with root privileges (CVE-2025-46805) + + -- Salvatore Bonaccorso <car...@debian.org> Fri, 16 May 2025 17:46:51 +0200 + +screen (4.9.1-2) unstable; urgency=medium + + * Team upload (debian/ namespace). + * 63-add-utempter-switch: fix variable name + * Stop building with utempter + * Disable utmp writing (Closes: #1104514) + * Update ptymode to 0600 in line with rest of the system + + -- Chris Hofstaedtler <z...@debian.org> Sat, 10 May 2025 22:28:23 +0200 + screen (4.9.1-1) unstable; urgency=low * Update upstream's PGP keys to sport the currently published keys. diff -Nru screen-4.9.1/debian/control screen-4.9.1/debian/control --- screen-4.9.1/debian/control 2023-01-07 15:11:07.000000000 +0100 +++ screen-4.9.1/debian/control 2025-05-16 17:46:51.000000000 +0200 @@ -8,12 +8,11 @@ dpkg-dev (>= 1.16.1~), libncurses-dev, libpam0g-dev, - libutempter-dev, texinfo Homepage: https://savannah.gnu.org/projects/screen Vcs-Git: https://salsa.debian.org/debian/screen.git Vcs-Browser: https://salsa.debian.org/debian/screen -Rules-Requires-Root: binary-targets +Rules-Requires-Root: no Package: screen Architecture: any diff -Nru screen-4.9.1/debian/patches/03disable-utmp.patch screen-4.9.1/debian/patches/03disable-utmp.patch --- screen-4.9.1/debian/patches/03disable-utmp.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/03disable-utmp.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,40 @@ +Disable UTMP updating feature. + +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1104514 + +--- a/acconfig.h ++++ b/acconfig.h +@@ -191,7 +191,7 @@ + * If screen is installed with permissions to update /etc/utmp (such + * as if it is installed set-uid root), define UTMPOK. + */ +-#define UTMPOK ++#undef UTMPOK + + /* Set LOGINDEFAULT to one (1) + * if you want entries added to /etc/utmp by default, else set it to +@@ -214,7 +214,7 @@ + * Set CAREFULUTMP to one (1) if you want that users have at least one + * window per screen session logged in. + */ +-#define LOGOUTOK 1 ++#undef LOGOUTOK + #undef CAREFULUTMP + + +--- a/utmp.c ++++ b/utmp.c +@@ -882,6 +882,7 @@ + } + # endif /* BUGGYGETLOGIN */ + ++#ifdef UTMPOK + #if defined(linux) && defined(GETUTENT) + # undef pututline + +@@ -899,4 +900,5 @@ + return u->ut_type == u2->ut_type ? u : 0; + } + #endif ++#endif + diff -Nru screen-4.9.1/debian/patches/63-add-utempter-switch.patch screen-4.9.1/debian/patches/63-add-utempter-switch.patch --- screen-4.9.1/debian/patches/63-add-utempter-switch.patch 2023-09-06 23:22:02.000000000 +0200 +++ screen-4.9.1/debian/patches/63-add-utempter-switch.patch 2025-05-16 17:46:51.000000000 +0200 @@ -10,7 +10,7 @@ [int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs") ) +AC_ARG_ENABLE(utempter, [ --enable-utempter enable utempter support]) -+if test "$enable_pam" = "yes"; then ++if test "$enable_utempter" = "yes"; then AC_CHECKING(ut_host) AC_TRY_COMPILE([ #include <time.h> diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,134 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:15:38 +0200 +Subject: fix CVE-2025-46802: attacher.c - prevent temporary 0666 mode on PTYs +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=049b26b22e197ba3be9c46e5c193032e01a4724a +Bug-Debian: https://bugs.debian.org/1105191 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46802 + +This temporary chmod of the PTY to mode 0666 is most likely a remnant of +past times, before the PTY file descriptor was passed to the target +session via the UNIX domain socket. + +This chmod() causes a race condition during which any other user in the +system can open the PTY for reading and writing, and thus allows PTY +hijacking. + +Simply remove this logic completely. +--- + src/attacher.c | 27 --------------------------- + src/screen.c | 19 ------------------- + 2 files changed, 46 deletions(-) + +--- a/attacher.c ++++ b/attacher.c +@@ -73,7 +73,6 @@ extern int MasterPid, attach_fd; + #ifdef MULTIUSER + extern char *multi; + extern int multiattach, multi_uid, own_uid; +-extern int tty_mode, tty_oldmode; + # ifndef USE_SETEUID + static int multipipe[2]; + # endif +@@ -160,9 +159,6 @@ int how; + + if (pipe(multipipe)) + Panic(errno, "pipe"); +- if (chmod(attach_tty, 0666)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = tty_mode; + eff_uid = -1; /* make UserContext fork */ + real_uid = multi_uid; + if ((ret = UserContext()) <= 0) +@@ -174,11 +170,6 @@ int how; + Panic(errno, "UserContext"); + close(multipipe[1]); + read(multipipe[0], &dummy, 1); +- if (tty_oldmode >= 0) +- { +- chmod(attach_tty, tty_oldmode); +- tty_oldmode = -1; +- } + ret = UserStatus(); + #ifdef LOCK + if (ret == SIG_LOCK) +@@ -224,9 +215,6 @@ int how; + xseteuid(multi_uid); + xseteuid(own_uid); + #endif +- if (chmod(attach_tty, 0666)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = tty_mode; + } + # endif /* USE_SETEUID */ + #endif /* MULTIUSER */ +@@ -423,13 +411,6 @@ int how; + ContinuePlease = 0; + # ifndef USE_SETEUID + close(multipipe[1]); +-# else +- xseteuid(own_uid); +- if (tty_oldmode >= 0) +- if (chmod(attach_tty, tty_oldmode)) +- Panic(errno, "chmod %s", attach_tty); +- tty_oldmode = -1; +- xseteuid(real_uid); + # endif + } + #endif +@@ -505,14 +486,6 @@ AttacherFinit SIGDEFARG + close(s); + } + } +-#ifdef MULTIUSER +- if (tty_oldmode >= 0) +- { +- if (setuid(own_uid)) +- Panic(errno, "setuid"); +- chmod(attach_tty, tty_oldmode); +- } +-#endif + exit(0); + SIGRETURN; + } +--- a/screen.c ++++ b/screen.c +@@ -230,8 +230,6 @@ char *multi_home; + int multi_uid; + int own_uid; + int multiattach; +-int tty_mode; +-int tty_oldmode = -1; + #endif + + char HostName[MAXSTR]; +@@ -1009,9 +1007,6 @@ int main(int ac, char** av) + + /* ttyname implies isatty */ + SetTtyname(true, &st); +-#ifdef MULTIUSER +- tty_mode = (int)st.st_mode & 0777; +-#endif + + fl = fcntl(0, F_GETFL, 0); + if (fl != -1 && (fl & (O_RDWR|O_RDONLY|O_WRONLY)) == O_RDWR) +@@ -2170,20 +2165,6 @@ DEFINE_VARARGS_FN(Panic) + if (D_userpid) + Kill(D_userpid, SIG_BYE); + } +-#ifdef MULTIUSER +- if (tty_oldmode >= 0) { +- +-# ifdef USE_SETEUID +- if (setuid(own_uid)) +- xseteuid(own_uid); /* may be a loop. sigh. */ +-# else +- setuid(own_uid); +-# endif +- +- debug1("Panic: changing back modes from %s\n", attach_tty); +- chmod(attach_tty, tty_oldmode); +- } +-#endif + eexit(1); + } + diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46804-avoid-file-existence-test-informa.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,118 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:26:11 +0200 +Subject: fix CVE-2025-46804: avoid file existence test information leaks +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=e0eef5aac453fa98a2664416a56c50ad1d00cb30 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46804 + +In setuid-root context the current error messages give away whether +certain paths not accessible by the real user exist and what type they +have. To prevent this only output generic error messages in setuid-root +context. + +In some situations, when an error is pertaining a directory and the +directory is owner by the real user then we can still output more +detailed diagnostics. + +This change can lead to less helpful error messages when Screen is +install setuid-root. More complex changes would be needed to avoid this +(e.g. only open the `SocketPath` with raised privileges when +multi-attach is requested). + +There might still be lingering some code paths that allow such +information leaks, since `SocketPath` is a global variable that is used +across the code base. The majority of issues should be caught with this +fix, however. +--- + src/screen.c | 45 ++++++++++++++++++++++++++++++++++----------- + src/socket.c | 9 +++++++-- + 2 files changed, 41 insertions(+), 13 deletions(-) + +--- a/screen.c ++++ b/screen.c +@@ -1122,15 +1122,28 @@ int main(int ac, char** av) + #endif + } + +- if (stat(SockPath, &st) == -1) +- Panic(errno, "Cannot access %s", SockPath); +- else +- if (!S_ISDIR(st.st_mode)) ++ if (stat(SockPath, &st) == -1) { ++ if (eff_uid == real_uid) { ++ Panic(errno, "Cannot access %s", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } else if (!S_ISDIR(st.st_mode)) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { + Panic(0, "%s is not a directory.", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + #ifdef MULTIUSER + if (multi) { +- if ((int)st.st_uid != multi_uid) +- Panic(0, "%s is not the owner of %s.", multi, SockPath); ++ if ((int)st.st_uid != multi_uid) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "%s is not the owner of %s.", multi, SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + } + else + #endif +@@ -1144,9 +1157,13 @@ int main(int ac, char** av) + Panic(0, "You are not the owner of %s.", SockPath); + #endif + } +- +- if ((st.st_mode & 0777) != 0700) +- Panic(0, "Directory %s must have mode 700.", SockPath); ++ if ((st.st_mode & 0777) != 0700) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "Directory %s must have mode 700.", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + if (SockMatch && index(SockMatch, '/')) + Panic(0, "Bad session name '%s'", SockMatch); + SockName = SockPath + strlen(SockPath) + 1; +@@ -1184,8 +1201,14 @@ int main(int ac, char** av) + else + exit(9 + (fo || oth ? 1 : 0) + fo); + } +- if (fo == 0) +- Panic(0, "No Sockets found in %s.\n", SockPath); ++ if (fo == 0) { ++ if (eff_uid == real_uid || st.st_uid == real_uid) { ++ Panic(0, "No Sockets found in %s.\n", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } ++ + Msg(0, "%d Socket%s in %s.", fo, fo > 1 ? "s" : "", SockPath); + eexit(0); + } +--- a/socket.c ++++ b/socket.c +@@ -171,8 +171,13 @@ bool *is_sock; + xsetegid(real_gid); + #endif + +- if ((dirp = opendir(SockPath)) == 0) +- Panic(errno, "Cannot opendir %s", SockPath); ++ if ((dirp = opendir(SockPath)) == 0) { ++ if (eff_uid == real_uid) { ++ Panic(errno, "Cannot opendir %s", SockPath); ++ } else { ++ Panic(0, "Error accessing %s", SockPath); ++ } ++ } + + slist = schosen = NULL; + slisttail = &slist; diff -Nru screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch --- screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch 1970-01-01 01:00:00.000000000 +0100 +++ screen-4.9.1/debian/patches/fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch 2025-05-16 17:46:51.000000000 +0200 @@ -0,0 +1,113 @@ +From: Matthias Gerstner <matthias.gerst...@suse.de> +Date: Mon, 12 May 2025 15:38:19 +0200 +Subject: fix CVE-2025-46805: socket.c - don't send signals with root + privileges +Origin: https://git.savannah.gnu.org/cgit/screen.git/commit/?id=161f85b98b7e1d5e4893aeed20f4cdb5e3dfaaa4 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-46805 + +The CheckPid() function was introduced to address CVE-2023-24626, to +prevent sending SIGCONT and SIGHUP to arbitrary PIDs in the system. This +fix still suffers from a TOCTOU race condition. The client can replace +itself by a privileged process, or try to cycle PIDs until a privileged +process receives the original PID. + +To prevent this, always send signals using the real privileges. Keep +CheckPid() for error diagnostics. If sending the actual signal fails +later on then there will be no more error reporting. + +It seems the original bugfix already introduced a regression when +attaching to another's user session that is not owned by root. In this +case the target sessions runs with real uid X, while for sending a +signal to the `pid` provided by the client real uid Y (or root +privileges) are required. + +This is hard to properly fix without this regression. On Linux pidfds +could be used to allow safely sending signals to other PIDs as root +without involving race conditions. In this case the client PID should +also be obtained via the UNIX domain socket's SO_PEERCRED option, +though. +--- + src/socket.c | 21 +++++++++++++-------- + 1 file changed, 13 insertions(+), 8 deletions(-) + +--- a/socket.c ++++ b/socket.c +@@ -832,6 +832,11 @@ int pid; + return UserStatus(); + } + ++static void KillUnpriv(pid_t pid, int sig) { ++ UserContext(); ++ UserReturn(kill(pid, sig)); ++} ++ + #ifdef hpux + /* + * From: "F. K. Bruner" <nap...@ugcs.caltech.edu> +@@ -917,14 +922,14 @@ struct win *wi; + { + Msg(errno, "Could not perform necessary sanity checks on pts device."); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + if (strcmp(ttyname_in_ns, m->m_tty)) + { + Msg(errno, "Attach: passed fd does not match tty: %s - %s!", ttyname_in_ns, m->m_tty[0] != '\0' ? m->m_tty : "(null)"); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + /* m->m_tty so far contains the actual name of the pts device in the +@@ -941,19 +946,19 @@ struct win *wi; + { + Msg(errno, "Attach: passed fd does not match tty: %s - %s!", m->m_tty, myttyname ? myttyname : "NULL"); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + } + else if ((i = secopen(m->m_tty, O_RDWR | O_NONBLOCK, 0)) < 0) + { + Msg(errno, "Attach: Could not open %s!", m->m_tty); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + return -1; + } + #ifdef MULTIUSER + if (attach) +- Kill(pid, SIGCONT); ++ KillUnpriv(pid, SIGCONT); + #endif + + #if defined(ultrix) || defined(pyr) || defined(NeXT) +@@ -966,7 +971,7 @@ struct win *wi; + { + write(i, "Attaching from inside of screen?\n", 33); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + Msg(0, "Attach msg ignored: coming from inside."); + return -1; + } +@@ -977,7 +982,7 @@ struct win *wi; + { + write(i, "Access to session denied.\n", 26); + close(i); +- Kill(pid, SIG_BYE); ++ KillUnpriv(pid, SIG_BYE); + Msg(0, "Attach: access denied for user %s.", user); + return -1; + } +@@ -1295,7 +1300,7 @@ ReceiveMsg() + Msg(0, "Query attempt with bad pid(%d)!", m.m.command.apid); + } + else { +- Kill(m.m.command.apid, ++ KillUnpriv(m.m.command.apid, + (queryflag >= 0) + ? SIGCONT + : SIG_BYE); /* Send SIG_BYE if an error happened */ diff -Nru screen-4.9.1/debian/patches/series screen-4.9.1/debian/patches/series --- screen-4.9.1/debian/patches/series 2023-09-06 23:22:33.000000000 +0200 +++ screen-4.9.1/debian/patches/series 2025-05-16 17:46:51.000000000 +0200 @@ -1,4 +1,5 @@ # 01-08: fixes to configure, altering preprocessor macros etc. +03disable-utmp.patch 05prefer-libtinfo-over-libcurses.patch # 10-79: "regular" code and documentation fixes 11replace_doc_paths.patch @@ -14,3 +15,6 @@ 81_session_creation_util.patch 82_session_creation_core.patch 85_bracketed-paste-patch-by-Unit193_dpaste.com_5KJ572GZM.patch +fix-CVE-2025-46802-attacher.c-prevent-temporary-0666.patch +fix-CVE-2025-46804-avoid-file-existence-test-informa.patch +fix-CVE-2025-46805-socket.c-don-t-send-signals-with-.patch diff -Nru screen-4.9.1/debian/rules screen-4.9.1/debian/rules --- screen-4.9.1/debian/rules 2021-08-05 15:30:52.000000000 +0200 +++ screen-4.9.1/debian/rules 2025-05-16 17:46:51.000000000 +0200 @@ -17,7 +17,7 @@ TTYGROUP := 5 # Common configure options for .deb and .udeb SCREEN_CONFIGURE=--with-socket-dir=/run/screen \ - --with-pty-mode=0620 \ + --with-pty-mode=0600 \ --with-pty-group=${TTYGROUP} \ --enable-rxvt_osc \ --with-sys-screenrc=/etc/screenrc \ @@ -32,7 +32,7 @@ rm -rf build build-udeb override_dh_auto_configure: - dh_auto_configure -B build -- $(SCREEN_CONFIGURE) --enable-pam --enable-utempter + dh_auto_configure -B build -- $(SCREEN_CONFIGURE) --enable-pam # To minimize the library dependencies, the .udeb binary is # built without "--enable-pam" dh_auto_configure -B build-udeb -- $(SCREEN_CONFIGURE) @@ -55,9 +55,7 @@ rm -f $(ROOT)/usr/bin/screen $(ROOT_UDEB)/usr/bin/screen mv -f $(ROOT)/usr/bin/screen* $(ROOT)/usr/bin/screen mv -f $(ROOT_UDEB)/usr/bin/screen* $(ROOT_UDEB)/usr/bin/screen - # make it setgid utmp only in udeb - chown root:utmp $(ROOT_UDEB)/usr/bin/screen - chmod 2755 $(ROOT_UDEB)/usr/bin/screen + chmod 755 $(ROOT_UDEB)/usr/bin/screen chmod 755 $(ROOT)/usr/bin/screen # Fix package-contains-info-dir-file, remove /usr/share/info/dir.gz rm -f $(ROOT)/usr/share/info/dir* @@ -69,6 +67,3 @@ override_dh_installtmpfiles: dh_installtmpfiles --name=screen-cleanup - -override_dh_fixperms: - dh_fixperms -X/usr/bin/screen