wok rev 25841

Up screen CVEs (CVE-2025-[46802,46804,46805)
author Stanislas Leduc <shann@slitaz.org>
date Wed May 14 16:32:36 2025 +0200 (4 weeks ago)
parents 88ba5b5ddfcd
children 3e7bcaeb68e6
files screen/receipt screen/stuff/CVE-2025-46802.patch screen/stuff/CVE-2025-46804.patch screen/stuff/CVE-2025-46805.patch
line diff
     1.1 --- a/screen/receipt	Mon May 12 17:27:22 2025 +0000
     1.2 +++ b/screen/receipt	Wed May 14 16:32:36 2025 +0200
     1.3 @@ -26,6 +26,14 @@
     1.4  # Rules to configure and make the package.
     1.5  compile_rules()
     1.6  {
     1.7 +	# CVEs
     1.8 +	# see https://www.cve.org/CVERecord?id=CVE-2025-46802
     1.9 +	# see https://www.cve.org/CVERecord?id=CVE-2025-46804
    1.10 +	# see https://www.cve.org/CVERecord?id=CVE-2025-46805
    1.11 +	patch -p1 < $stuff/CVE-2025-46802.patch
    1.12 +	patch -p1 < $stuff/CVE-2025-46804.patch
    1.13 +	patch -p1 < $stuff/CVE-2025-46805.patch
    1.14 +
    1.15  	./autogen.sh &&
    1.16  	./configure					\
    1.17  		--with-sys-screenrc=/etc/screenrc	\
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/screen/stuff/CVE-2025-46802.patch	Wed May 14 16:32:36 2025 +0200
     2.3 @@ -0,0 +1,140 @@
     2.4 +From 049b26b22e197ba3be9c46e5c193032e01a4724a Mon Sep 17 00:00:00 2001
     2.5 +From: Matthias Gerstner <matthias.gerstner@suse.de>
     2.6 +Date: Mon, 12 May 2025 15:15:38 +0200
     2.7 +Subject: fix CVE-2025-46802: attacher.c - prevent temporary 0666 mode on PTYs
     2.8 +
     2.9 +This temporary chmod of the PTY to mode 0666 is most likely a remnant of
    2.10 +past times, before the PTY file descriptor was passed to the target
    2.11 +session via the UNIX domain socket.
    2.12 +
    2.13 +This chmod() causes a race condition during which any other user in the
    2.14 +system can open the PTY for reading and writing, and thus allows PTY
    2.15 +hijacking.
    2.16 +
    2.17 +Simply remove this logic completely.
    2.18 +---
    2.19 + src/attacher.c | 27 ---------------------------
    2.20 + src/screen.c   | 19 -------------------
    2.21 + 2 files changed, 46 deletions(-)
    2.22 +
    2.23 +diff --git a/attacher.c b/attacher.c
    2.24 +index c35ae7a..16b151e 100644
    2.25 +--- a/attacher.c
    2.26 ++++ b/attacher.c
    2.27 +@@ -73,7 +73,6 @@ extern int MasterPid, attach_fd;
    2.28 + #ifdef MULTIUSER
    2.29 + extern char *multi;
    2.30 + extern int multiattach, multi_uid, own_uid;
    2.31 +-extern int tty_mode, tty_oldmode;
    2.32 + # ifndef USE_SETEUID
    2.33 + static int multipipe[2];
    2.34 + # endif
    2.35 +@@ -160,9 +159,6 @@ int how;
    2.36 + 
    2.37 +       if (pipe(multipipe))
    2.38 + 	Panic(errno, "pipe");
    2.39 +-      if (chmod(attach_tty, 0666))
    2.40 +-	Panic(errno, "chmod %s", attach_tty);
    2.41 +-      tty_oldmode = tty_mode;
    2.42 +       eff_uid = -1;	/* make UserContext fork */
    2.43 +       real_uid = multi_uid;
    2.44 +       if ((ret = UserContext()) <= 0)
    2.45 +@@ -174,11 +170,6 @@ int how;
    2.46 + 	    Panic(errno, "UserContext");
    2.47 + 	  close(multipipe[1]);
    2.48 + 	  read(multipipe[0], &dummy, 1);
    2.49 +-	  if (tty_oldmode >= 0)
    2.50 +-	    {
    2.51 +-	      chmod(attach_tty, tty_oldmode);
    2.52 +-	      tty_oldmode = -1;
    2.53 +-	    }
    2.54 + 	  ret = UserStatus();
    2.55 + #ifdef LOCK
    2.56 + 	  if (ret == SIG_LOCK)
    2.57 +@@ -224,9 +215,6 @@ int how;
    2.58 +       xseteuid(multi_uid);
    2.59 +       xseteuid(own_uid);
    2.60 + #endif
    2.61 +-      if (chmod(attach_tty, 0666))
    2.62 +-	Panic(errno, "chmod %s", attach_tty);
    2.63 +-      tty_oldmode = tty_mode;
    2.64 +     }
    2.65 + # endif /* USE_SETEUID */
    2.66 + #endif /* MULTIUSER */
    2.67 +@@ -423,13 +411,6 @@ int how;
    2.68 +       ContinuePlease = 0;
    2.69 + # ifndef USE_SETEUID
    2.70 +       close(multipipe[1]);
    2.71 +-# else
    2.72 +-      xseteuid(own_uid);
    2.73 +-      if (tty_oldmode >= 0)
    2.74 +-        if (chmod(attach_tty, tty_oldmode))
    2.75 +-          Panic(errno, "chmod %s", attach_tty);
    2.76 +-      tty_oldmode = -1;
    2.77 +-      xseteuid(real_uid);
    2.78 + # endif
    2.79 +     }
    2.80 + #endif
    2.81 +@@ -505,14 +486,6 @@ AttacherFinit SIGDEFARG
    2.82 + 	  close(s);
    2.83 + 	}
    2.84 +     }
    2.85 +-#ifdef MULTIUSER
    2.86 +-  if (tty_oldmode >= 0)
    2.87 +-    {
    2.88 +-      if (setuid(own_uid))
    2.89 +-        Panic(errno, "setuid");
    2.90 +-      chmod(attach_tty, tty_oldmode);
    2.91 +-    }
    2.92 +-#endif
    2.93 +   exit(0);
    2.94 +   SIGRETURN;
    2.95 + }
    2.96 +diff --git a/screen.c b/screen.c
    2.97 +index 7653cd1..1a23e1a 100644
    2.98 +--- a/screen.c
    2.99 ++++ b/screen.c
   2.100 +@@ -230,8 +230,6 @@ char *multi_home;
   2.101 + int multi_uid;
   2.102 + int own_uid;
   2.103 + int multiattach;
   2.104 +-int tty_mode;
   2.105 +-int tty_oldmode = -1;
   2.106 + #endif
   2.107 + 
   2.108 + char HostName[MAXSTR];
   2.109 +@@ -1009,9 +1007,6 @@ int main(int ac, char** av)
   2.110 + 
   2.111 +     /* ttyname implies isatty */
   2.112 +     SetTtyname(true, &st);
   2.113 +-#ifdef MULTIUSER
   2.114 +-    tty_mode = (int)st.st_mode & 0777;
   2.115 +-#endif
   2.116 + 
   2.117 +     fl = fcntl(0, F_GETFL, 0);
   2.118 +     if (fl != -1 && (fl & (O_RDWR|O_RDONLY|O_WRONLY)) == O_RDWR)
   2.119 +@@ -2170,20 +2165,6 @@ DEFINE_VARARGS_FN(Panic)
   2.120 +       if (D_userpid)
   2.121 +         Kill(D_userpid, SIG_BYE);
   2.122 +     }
   2.123 +-#ifdef MULTIUSER
   2.124 +-  if (tty_oldmode >= 0) {
   2.125 +-
   2.126 +-# ifdef USE_SETEUID
   2.127 +-    if (setuid(own_uid))
   2.128 +-      xseteuid(own_uid);	/* may be a loop. sigh. */
   2.129 +-# else
   2.130 +-      setuid(own_uid);
   2.131 +-# endif
   2.132 +-
   2.133 +-    debug1("Panic: changing back modes from %s\n", attach_tty);
   2.134 +-    chmod(attach_tty, tty_oldmode);
   2.135 +-  }
   2.136 +-#endif
   2.137 +   eexit(1);
   2.138 + }
   2.139 + 
   2.140 +-- 
   2.141 +cgit v1.1
   2.142 +
   2.143 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/screen/stuff/CVE-2025-46804.patch	Wed May 14 16:32:36 2025 +0200
     3.3 @@ -0,0 +1,125 @@
     3.4 +From e0eef5aac453fa98a2664416a56c50ad1d00cb30 Mon Sep 17 00:00:00 2001
     3.5 +From: Matthias Gerstner <matthias.gerstner@suse.de>
     3.6 +Date: Mon, 12 May 2025 15:26:11 +0200
     3.7 +Subject: fix CVE-2025-46804: avoid file existence test information leaks
     3.8 +
     3.9 +In setuid-root context the current error messages give away whether
    3.10 +certain paths not accessible by the real user exist and what type they
    3.11 +have. To prevent this only output generic error messages in setuid-root
    3.12 +context.
    3.13 +
    3.14 +In some situations, when an error is pertaining a directory and the
    3.15 +directory is owner by the real user then we can still output more
    3.16 +detailed diagnostics.
    3.17 +
    3.18 +This change can lead to less helpful error messages when Screen is
    3.19 +install setuid-root. More complex changes would be needed to avoid this
    3.20 +(e.g.  only open the `SocketPath` with raised privileges when
    3.21 +multi-attach is requested).
    3.22 +
    3.23 +There might still be lingering some code paths that allow such
    3.24 +information leaks, since `SocketPath` is a global variable that is used
    3.25 +across the code base. The majority of issues should be caught with this
    3.26 +fix, however.
    3.27 +---
    3.28 + src/screen.c | 45 ++++++++++++++++++++++++++++++++++-----------
    3.29 + src/socket.c |  9 +++++++--
    3.30 + 2 files changed, 41 insertions(+), 13 deletions(-)
    3.31 +
    3.32 +diff --git a/screen.c b/screen.c
    3.33 +index 1a23e1a..6eec151 100644
    3.34 +--- a/screen.c
    3.35 ++++ b/screen.c
    3.36 +@@ -1122,15 +1122,28 @@ int main(int ac, char** av)
    3.37 + #endif
    3.38 +   }
    3.39 + 
    3.40 +-  if (stat(SockPath, &st) == -1)
    3.41 +-    Panic(errno, "Cannot access %s", SockPath);
    3.42 +-  else
    3.43 +-    if (!S_ISDIR(st.st_mode))
    3.44 ++  if (stat(SockPath, &st) == -1) {
    3.45 ++    if (eff_uid == real_uid) {
    3.46 ++      Panic(errno, "Cannot access %s", SockPath);
    3.47 ++    } else {
    3.48 ++      Panic(0, "Error accessing %s", SockPath);
    3.49 ++    }
    3.50 ++  } else if (!S_ISDIR(st.st_mode)) {
    3.51 ++    if (eff_uid == real_uid || st.st_uid == real_uid) {
    3.52 +       Panic(0, "%s is not a directory.", SockPath);
    3.53 ++    } else {
    3.54 ++      Panic(0, "Error accessing %s", SockPath);
    3.55 ++    }
    3.56 ++  }
    3.57 + #ifdef MULTIUSER
    3.58 +   if (multi) {
    3.59 +-    if ((int)st.st_uid != multi_uid)
    3.60 +-      Panic(0, "%s is not the owner of %s.", multi, SockPath);
    3.61 ++    if ((int)st.st_uid != multi_uid) {
    3.62 ++      if (eff_uid == real_uid || st.st_uid == real_uid) {
    3.63 ++        Panic(0, "%s is not the owner of %s.", multi, SockPath);
    3.64 ++      } else {
    3.65 ++        Panic(0, "Error accessing %s", SockPath);
    3.66 ++      }
    3.67 ++    }
    3.68 +   }
    3.69 +   else
    3.70 + #endif
    3.71 +@@ -1144,9 +1157,13 @@ int main(int ac, char** av)
    3.72 +       Panic(0, "You are not the owner of %s.", SockPath);
    3.73 + #endif
    3.74 +   }
    3.75 +-
    3.76 +-  if ((st.st_mode & 0777) != 0700)
    3.77 +-    Panic(0, "Directory %s must have mode 700.", SockPath);
    3.78 ++  if ((st.st_mode & 0777) != 0700) {
    3.79 ++    if (eff_uid == real_uid || st.st_uid == real_uid) {
    3.80 ++      Panic(0, "Directory %s must have mode 700.", SockPath);
    3.81 ++    } else {
    3.82 ++      Panic(0, "Error accessing %s", SockPath);
    3.83 ++    }
    3.84 ++  }
    3.85 +   if (SockMatch && index(SockMatch, '/'))
    3.86 +     Panic(0, "Bad session name '%s'", SockMatch);
    3.87 +   SockName = SockPath + strlen(SockPath) + 1;
    3.88 +@@ -1184,8 +1201,14 @@ int main(int ac, char** av)
    3.89 +       else
    3.90 +         exit(9 + (fo || oth ? 1 : 0) + fo);
    3.91 +     }
    3.92 +-    if (fo == 0)
    3.93 +-      Panic(0, "No Sockets found in %s.\n", SockPath);
    3.94 ++    if (fo == 0) {
    3.95 ++      if (eff_uid == real_uid || st.st_uid == real_uid) {
    3.96 ++        Panic(0, "No Sockets found in %s.\n", SockPath);
    3.97 ++      } else {
    3.98 ++        Panic(0, "Error accessing %s", SockPath);
    3.99 ++      }
   3.100 ++    }
   3.101 ++
   3.102 +     Msg(0, "%d Socket%s in %s.", fo, fo > 1 ? "s" : "", SockPath);
   3.103 +     eexit(0);
   3.104 +   }
   3.105 +diff --git a/socket.c b/socket.c
   3.106 +index 54d8cb8..6c3502f 100644
   3.107 +--- a/socket.c
   3.108 ++++ b/socket.c
   3.109 +@@ -169,8 +169,13 @@ bool *is_sock;
   3.110 +   xsetegid(real_gid);
   3.111 + #endif
   3.112 + 
   3.113 +-  if ((dirp = opendir(SockPath)) == 0)
   3.114 +-    Panic(errno, "Cannot opendir %s", SockPath);
   3.115 ++  if ((dirp = opendir(SockPath)) == 0) {
   3.116 ++    if (eff_uid == real_uid) {
   3.117 ++      Panic(errno, "Cannot opendir %s", SockPath);
   3.118 ++    } else {
   3.119 ++      Panic(0, "Error accessing %s", SockPath);
   3.120 ++    }
   3.121 ++  }
   3.122 + 
   3.123 +   slist = 0;
   3.124 +   slisttail = &slist;
   3.125 +-- 
   3.126 +cgit v1.1
   3.127 +
   3.128 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/screen/stuff/CVE-2025-46805.patch	Wed May 14 16:32:36 2025 +0200
     4.3 @@ -0,0 +1,118 @@
     4.4 +From 161f85b98b7e1d5e4893aeed20f4cdb5e3dfaaa4 Mon Sep 17 00:00:00 2001
     4.5 +From: Matthias Gerstner <matthias.gerstner@suse.de>
     4.6 +Date: Mon, 12 May 2025 15:38:19 +0200
     4.7 +Subject: fix CVE-2025-46805: socket.c - don't send signals with root
     4.8 + privileges
     4.9 +
    4.10 +The CheckPid() function was introduced to address CVE-2023-24626, to
    4.11 +prevent sending SIGCONT and SIGHUP to arbitrary PIDs in the system. This
    4.12 +fix still suffers from a TOCTOU race condition. The client can replace
    4.13 +itself by a privileged process, or try to cycle PIDs until a privileged
    4.14 +process receives the original PID.
    4.15 +
    4.16 +To prevent this, always send signals using the real privileges. Keep
    4.17 +CheckPid() for error diagnostics. If sending the actual signal fails
    4.18 +later on then there will be no more error reporting.
    4.19 +
    4.20 +It seems the original bugfix already introduced a regression when
    4.21 +attaching to another's user session that is not owned by root. In this
    4.22 +case the target sessions runs with real uid X, while for sending a
    4.23 +signal to the `pid` provided by the client real uid Y (or root
    4.24 +privileges) are required.
    4.25 +
    4.26 +This is hard to properly fix without this regression. On Linux pidfds
    4.27 +could be used to allow safely sending signals to other PIDs as root
    4.28 +without involving race conditions. In this case the client PID should
    4.29 +also be obtained via the UNIX domain socket's SO_PEERCRED option,
    4.30 +though.
    4.31 +---
    4.32 + src/socket.c | 21 +++++++++++++--------
    4.33 + 1 file changed, 13 insertions(+), 8 deletions(-)
    4.34 +
    4.35 +diff --git a/socket.c b/socket.c
    4.36 +index 6c3502f..d6621fa 100644
    4.37 +--- a/socket.c
    4.38 ++++ b/socket.c
    4.39 +@@ -831,6 +831,11 @@ int pid;
    4.40 +   return UserStatus();
    4.41 + }
    4.42 + 
    4.43 ++static void KillUnpriv(pid_t pid, int sig) {
    4.44 ++    UserContext();
    4.45 ++    UserReturn(kill(pid, sig));
    4.46 ++}
    4.47 ++
    4.48 + #ifdef hpux
    4.49 + /*
    4.50 +  * From: "F. K. Bruner" <napalm@ugcs.caltech.edu>
    4.51 +@@ -916,14 +921,14 @@ struct win *wi;
    4.52 +             {
    4.53 + 	      Msg(errno, "Could not perform necessary sanity checks on pts device.");
    4.54 + 	      close(i);
    4.55 +-	      Kill(pid, SIG_BYE);
    4.56 ++	      KillUnpriv(pid, SIG_BYE);
    4.57 + 	      return -1;
    4.58 +             }
    4.59 +           if (strcmp(ttyname_in_ns, m->m_tty))
    4.60 +             {
    4.61 + 	      Msg(errno, "Attach: passed fd does not match tty: %s - %s!", ttyname_in_ns, m->m_tty[0] != '\0' ? m->m_tty : "(null)");
    4.62 + 	      close(i);
    4.63 +-	      Kill(pid, SIG_BYE);
    4.64 ++	      KillUnpriv(pid, SIG_BYE);
    4.65 + 	      return -1;
    4.66 + 	    }
    4.67 + 	  /* m->m_tty so far contains the actual name of the pts device in the
    4.68 +@@ -940,19 +945,19 @@ struct win *wi;
    4.69 + 	{
    4.70 + 	  Msg(errno, "Attach: passed fd does not match tty: %s - %s!", m->m_tty, myttyname ? myttyname : "NULL");
    4.71 + 	  close(i);
    4.72 +-	  Kill(pid, SIG_BYE);
    4.73 ++	  KillUnpriv(pid, SIG_BYE);
    4.74 + 	  return -1;
    4.75 + 	}
    4.76 +     }
    4.77 +   else if ((i = secopen(m->m_tty, O_RDWR | O_NONBLOCK, 0)) < 0)
    4.78 +     {
    4.79 +       Msg(errno, "Attach: Could not open %s!", m->m_tty);
    4.80 +-      Kill(pid, SIG_BYE);
    4.81 ++      KillUnpriv(pid, SIG_BYE);
    4.82 +       return -1;
    4.83 +     }
    4.84 + #ifdef MULTIUSER
    4.85 +   if (attach)
    4.86 +-    Kill(pid, SIGCONT);
    4.87 ++    KillUnpriv(pid, SIGCONT);
    4.88 + #endif
    4.89 + 
    4.90 + #if defined(ultrix) || defined(pyr) || defined(NeXT)
    4.91 +@@ -965,7 +970,7 @@ struct win *wi;
    4.92 + 	{
    4.93 + 	  write(i, "Attaching from inside of screen?\n", 33);
    4.94 + 	  close(i);
    4.95 +-	  Kill(pid, SIG_BYE);
    4.96 ++	  KillUnpriv(pid, SIG_BYE);
    4.97 + 	  Msg(0, "Attach msg ignored: coming from inside.");
    4.98 + 	  return -1;
    4.99 + 	}
   4.100 +@@ -976,7 +981,7 @@ struct win *wi;
   4.101 + 	  {
   4.102 + 	      write(i, "Access to session denied.\n", 26);
   4.103 + 	      close(i);
   4.104 +-	      Kill(pid, SIG_BYE);
   4.105 ++	      KillUnpriv(pid, SIG_BYE);
   4.106 + 	      Msg(0, "Attach: access denied for user %s.", user);
   4.107 + 	      return -1;
   4.108 + 	  }
   4.109 +@@ -1294,7 +1299,7 @@ ReceiveMsg()
   4.110 +             Msg(0, "Query attempt with bad pid(%d)!", m.m.command.apid);
   4.111 +           }
   4.112 +           else {
   4.113 +-            Kill(m.m.command.apid,
   4.114 ++            KillUnpriv(m.m.command.apid,
   4.115 +                (queryflag >= 0)
   4.116 +                    ? SIGCONT
   4.117 +                    : SIG_BYE); /* Send SIG_BYE if an error happened */
   4.118 +-- 
   4.119 +cgit v1.1
   4.120 +
   4.121 +