Axel Beckert wrote:
> Full debdiff attached again, sole changes compared to Salvatore's
> debdiff are in debian/changelog (NMU → MU).

Forgot the attachment. Here is it.

                Regards, Axel
-- 
 ,''`.  |  Axel Beckert <a...@debian.org>, https://people.debian.org/~abe/
: :' :  |  Debian Developer, ftp.ch.debian.org Admin
`. `'   |  4096R: 2517 B724 C5F6 CA99 5329  6E61 2FF9 CD59 6126 16B5
  `-    |  1024D: F067 EA27 26B9 C3FC 1486  202E C09E 1D89 9593 0EDE
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-19 00:42:42.000000000 +0200
@@ -1,3 +1,13 @@
+screen (4.9.1-3) unstable; urgency=medium
+
+  [ Salvatore Bonaccorso ]
+  * 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)
+
+ -- Axel Beckert <a...@debian.org>  Mon, 19 May 2025 00:42:42 +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-19 00:26:08.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-19 00:26:08.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-19 00:26:08.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-19 00:26:08.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

Reply via email to