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

Reply via email to