Screen 中的多个安全问题
#本地 #CVE #root-exploit目录
- 1) 引言
- 2) Screen 配置和版本概述
- 3) 安全问题
- 4) Screen 的 setuid-root 实现中可能存在的其他问题
- 5) 一般性建议
- 6) 有问题的协调披露流程和上游状态
- 7) 影响矩阵
- 8) 上游错误修复
- 时间线
- 参考文献
- 变更历史
1) 引言
2024 年 7 月,Screen 上游维护者 请求我们检查当前的 Screen 代码库。我们对此请求的优先级较低,因为我们几年前已经粗略看过 Screen,未发现任何问题。当我们真正有时间再次检查时,我们惊讶地发现 Screen 5.0.0 主要版本更新中存在一个本地 root 提权漏洞,影响了将其配置为 setuid-root 的发行版(Arch Linux 和 NetBSD1)。我们还发现了一些其他不太严重的问��,其中一些也影响了大多数发行版中仍然存在的较旧 Screen 版本。
我们提供了两组针对本报告中描述问题的补丁,一组用于 screen-4.9.1,另一组用于 screen-5.0.0。这些补丁集分别适用于 screen-4.9.1 和 screen-5.0.0 发布包。
上游 发布了 Screen 5.0.1,应该可以解决本报告中发现的问题。发布包尚未提供下载,但很快就会出现在 GNU 下载服务器上。有关上游错误修复的更多详细信息,请参阅第 8 部分。
下一节概述了常见 Linux 和 UNIX 发行版中找到的 Screen 配置和版本。第 3 部分详细讨论了我们发现的每个安全问题。第 4 部分探讨了 Screen setuid-root 实现中可能存在的其他问题。第 5 部分提供了一般性建议,以改进 Screen 的安全状况。第 6 部分指出了我们在这些问题协调披露过程中遇到的问题。第 7 部分提供了一个影响矩阵,概��了各种 Linux 和 UNIX 系统上的情况。
2) Screen 配置和版本概述
2024 年 8 月,Screen 发布了 5.0.0 主要版本。目前 Arch Linux、Fedora 42 和 NetBSD 10.1 已经发布了这个新版本的 Screen。大量的重构更改已融入到这个 Screen 版本中,有些甚至可以追溯到十多年前。本报告中讨论的一些问题仅在 Screen 5.0.0 版本中引入,而另一些问题也影响 Screen 4.9.1(及更早版本),后者在撰写本文时仍然是大多数 Linux 和 UNIX 发行版中的版本。
本报告中出现的源代码引用基于上游 5.0.0 发布标签,除非另有说明。下文讨论的每个漏洞都提供了当前 5.0.0 版本和更广泛使用的 4.9.1 Screen 版本的影响信息。
注意:在撰写本文时,我们经常遇到 HTTP 502 “Bad Gateway” 错误,尝试访问 Screen 的 Git Web 前端。稍后重试通常可以解决该错误。
关于 Screen 多用户模式
Screen 提供多用户模式,允许连接到系统中其他用户的 Screen 会话(如果具有适当的凭据)。这些多用户功能仅在 Screen 以 setuid-root 权限安装时可用。Screen 的此配置会导致攻击面显著增加,因为在这种情况下,复杂的 Screen 代码以 root 权限运行。
Screen 多用户会话由其名称标识,该名称需要带有 `
user1$ screen -S user1/my-multi-user-session
为了管理多用户会话的访问权限,Screen 维护着访问控制列表(ACL),这些列表可以在 Screen 的配置文件(`~/.screenrc`)中配置,或者通过向正在运行的 Screen 会话发送命令(参见 screen(1) man page)进行配置。这些 ACL 基于其他用户的账户名称,并且可以选择通过密码进行保护。访问权限可以限制为“只读”模式,在该模式下无法将输入发送到终端。
在我们检查过的系统中,只有 Arch Linux、FreeBSD 和 NetBSD 将 Screen 安装为 setuid-root。在 Gentoo Linux 上,如果设置了“multiuser” USE 标志,则可以选择性地分配 setuid-root 位。一些发行版将 Screen 安装为 setgid 位,使其能够以特定的组凭据运行。Gentoo Linux 默认就是这种情况,它将 Screen 安装为 setgid-utmp,允许 Screen 在系统范围的 utmp 数据库中创建登录记录。Fedora Linux 将 Screen 安装为 setgid-screen,这允许 Screen 将套接字放置在 `/run/screen` 中的系统范围目录中。
3) 安全问题
3.a) 通过 logfile_reopen() 进行本地 root 提权 (CVE-2025-23395)
此问题影响 Screen 5.0.0 以 setuid-root 权限运行时。函数 logfile_reopen() 在操作用户提供的路径时不会放弃权限。这允许未经授权的用户创建具有 root 所有权、调用者(实际)组所有权和文件模式 0644 的任意位置的文件。写入 Screen PTY 的所有数据都将记录到此文件中。即使是已存在的文件也可以通过这种方式进行日志记录:数据将被追加到相关文件中,但文件模式和所有权将保持不变。
Screen 在最初打开日志文件时会正确放弃权限。权限升级的可能性在于 Screen 认为有必要重新打开日志文件。Screen 通过在写入文件之前调用 stolen_logfile() 来检查这一点。当最初打开的日志文件的链接计数降至零,或者其大小意外更改时,会调用 logfile_reopen()。未经授权的用户可以随时触发此条件。
这是一个重现器,演示了如何在受影响的系统上实现基本的本地 root 提权。
# create a Screen session using a custom logfile path
(shell1) user$ screen -Logfile $HOME/screen.log
# enter the key combination to enable logging to the configured path
(screen) user$ <ctrl-a> H
# in another shell remove the logfile that Screen just created and
# replace it by a symlink to a privileged location
(shell2) user$ rm $HOME/screen.log; ln -s /etc/profile.d/exploit.sh \
$HOME/screen.log
# back in the Screen session, echo an exploit command which will be logged to
# the now redirected logfile.
#
# This needs to be done via `echo` for adding a leading newline to prevent the
# bash prompt from breaking the exploit. Similarly the trailing semicolon
# is necessary to prevent following control characters from becoming part of
# the shell command.
(screen) user$ echo -e "\nchown $USER /root;"
# now perform a new login as root and watch the exploit being executed.
# you will likely see a range of shell errors during login as well.
root# ls -lhd /root
drwxr-x--- 5 user root 4.0K Dec 30 2020 .
这只是一种实现本地 root 提权的简单方法,它并不隐蔽(由于奇怪的错误消息),并且需要实际的 root 用户登录才能触发。很可能存在许多其他利用方法,例如通过为 sudo 等工具编写新的配置文件,或者将代码追加到 `/usr/bin` 及其类似位置的特权 shell 脚本中。
错误修复
该问题是通过一个 旧提交 441bca708bd 引入的,该提交现在才成为 5.0.0 版本的一部分。在此提交中,移除了被认为是不必要的 lf_secreopen() 函数。
补丁 0001 在 screen-5.0.0-patches.tar.gz 中,通过重新引入日志文件重开时的安全文件处理来解决此问题。
受影响的发行版
Arch Linux
Arch Linux 完全受此问题影响,因为它发布了 5.0.0 版本并设置了 setuid-root 位。Screen 默认不安装在 Arch 上,但。
作为对这些安全问题的回应,setuid-root 位已在 Arch Linux 中被 移除,经过 一些讨论。
Fedora Linux
受影响的 5.0.0 版本仅在最近发布的 Fedora 42 中找到。Screen 在那里以 setgid-screen 凭据运行,以便能够写入 `/run/screen` 目录。在该目录中,为每个运行 Screen 多用户会话的用户创建一个模式为 0700 的私有目录。因此,利用此漏洞无法写入其他用户的会话目录,只能直接在 `/run/screen` 中创建文件。我们唯一能设想到的攻击向量是,如果其他用户的会话目录尚不存在,则通过声称拥有这些目录的名称来导致本地 DoS 场景。另一个攻击向量可能是尝试填满 /run 文件系统(一个 TMPFS)的可用磁盘空间,以破坏其他系统服务。
Gentoo Linux
Gentoo Linux 在其稳定的 Screen ebuild 中不受影响,该 ebuild 仍基于 Screen 版本 4.9.1。
但是,当使用 Gentoo 的不稳定版本 `app-misc/screen-9999` ebuild 时,将安装受影响的 5.0.0 版本。如果还设置了“multiuser” USE 标志,则会设置 setuid-root 位,导致 Screen 完全易受攻击。
如果没有此 USE 标志,Screen 在 Gentoo Linux 上将作为 setgid-utmp 运行,这使得可以使用此漏洞覆盖 `/var/log/wtmp` 数据库。这使得破坏数据库的完整性,甚至伪造可能对依赖此信息的其他特权系统程序产生不利影响的登录条目成为可能。
FreeBSD
FreeBSD 仍使用 4.9.1 版本。如果 Screen 升级到 5.0.0,FreeBSD 也会受到影响,因为 Screen 默认安装为 setuid-root。
NetBSD
在 NetBSD 上,可以安装受影响的 Screen 5.0.0 版本,并且它将默认以 setuid-root 权限运行。这使其完全受到此问题的影响。
3.b) 在附加到多用户会话时劫持 TTY (CVE-2025-46802)
此问题存在于 Attach() 函数中,当设置了 `multiattach` 标志时(即 Screen 尝试附加到多用户会话)。该函数 执行对当前 TTY 的 chmod() 操作,模式为 0666。当前 TTY 的路径存储在 `attach_tty` 字符串中。
if ((how == MSG_ATTACH || how == MSG_CONT) && multiattach) {
/* snip */
if (chmod(attach_tty, 0666))
Panic(errno, "chmod %s", attach_tty);
tty_oldmode = tty_mode;
}
幸运的是,在 Screen 中计算出的 TTY 路径已充分进行了正确性检查。特别是,FD 0(用于确定 TTY 路径)需要为 true,并且生成的路径需要位于 /dev。否则,此 chmod() 将导致另一个本地 root 提权漏洞。
原始 TTY 模式在函数 第 284 行结束时恢复。我们不完全确定此临时权限更改的目的,也许是为了允许目标会话的 Screen 守护进程(可能具有不同的凭据)访问客户端的 TTY 以便进行附加过程。
此临时 TTY 模式更改的问题在于它引入了一个竞争条件,允许系统中的任何其他用户在短时间内读取和写入调用者的 TTY。我们基于 Linux 的 inotify API 进行了一些简单的测试,通过一个简单的 Python 脚本,我们每尝试一到两次就能成功打开受影响的 TTY。
此问题的影响是攻击者可以拦截输入到 TTY 的数据,并向其中注入数据。攻击者可以尝试误导 TTY 的所有者输入密码,或获取其他敏感信息。此外,控制序列可以被注入到受影响的 TTY 中,这为混淆受害者或利用涉及的终端模拟器中的问题提供了更多可能性。
在 Attach() 函数中也存在返回路径,其中原始模式永远不会再次恢复。例如,在 第 160 行,如果目标会话未找到且设置了“quiet”命令行参数,则进程会明确退出。此方面的一个简单重现器如下:
# inspect the current TTY permissions, which are safe
user$ ls -l `tty`
crw--w---- 1 user tty 136, 1 Feb 5 12:18 /dev/pts/1
# attempt to attach to some non-existing session of the root user.
# note that this only works if the target user's session directory (e.g.
# in $HOME/.screen) already exists, otherwise the logic terminates early
# and the `chmod()` does not happen.
user$ screen -r -S root/some-session -q
# observe the now unsafe TTY permissions
user$ ls -l `tty`
crw-rw-rw- 1 user tty 136, 1 Feb 5 12:19 /dev/pts/1
`Panic()` 函数(主要在 `Attach()` 中用于停止进程执行)会 正确恢复旧的 TTY 模式。只有使用 `return` 或 `eexit()` 的代码路径才会受到此 TTY 模式恢复缺失的影响。
错误修复
我们认为有问题的 chmod() 调用很可能是过去遗留下来的,当时使用这种不安全的方法来授予目标 Screen 会话访问新客户端 PTY 的权限。如今,Screen 通过 UNIX 域套接字将 PTY 文件描述符安全地传递给目标会话。
因此,为了解决这个问题,可以删除临时 chmod() 到模式 666 的操作。这已在 screen-4.9.1-patches.tar.gz 中的 补丁 0001 中完成,以及在 screen-5.0.0-patches.tar.gz 中的 补丁 0004 中完成。
在发布本报告前不久,有人指出此补丁 可能会破坏 Screen 中某些重新附加用例。我们确认了这个问题,但同时发现,即使在 Screen 4.9.1 中,这个特定的用例显然已经损坏。因此,我们决定不再推迟发布日期,也不急于调整此补丁,以免结果不确定。该补丁仍然修复了安全问题,并且上游现在可以公开修复这个似乎已经存在了更早的回归。
受影响的发行版
与前一个问题不同,这个问题不仅限于当前的 5.0.0 版本。观察到的行为至少自 2005 年以来就存在于 Screen 版本中。我们检查过的所有 Linux 发行版和 BSD 发行版都会受到影响,前提是它们通过将 Screen 安装为 setuid-root 来提供多用户支持。
这个问题理论上也影响 Screen,即使它 *不* 是以 setuid-root 权限安装的,因为调用者始终有权修改其自身的 TTY 模式。然而,如果目标会话不属于调用者且没有 root 权限可用,Screen 会拒绝继续操作。当用户出于某种原因尝试加入自己的多用户会话时,仍会触发有问题的代码。一个导致此问题的示例如下:`screen -r -S $USER/some-session -q`。受此轻微变体问题影响的系统在第 7 部分标记为部分受影响。
3.c) Screen 默认创建世界可写 PTY (CVE-2025-46803)
在 Screen 5.0.0 版本中,Screen 分配的伪终端(PTY)的默认模式从 0620 更改为 0622,从而允许任何人写入系统中的任何 Screen PTY。从安全角度来看,这会导致一些问题,如问题 3.b 中所述,但没有信息泄露方面的影响。
Screen 中默认 PTY 模式的历史相当复杂。让我们看看 4.9.1 版本(以及许多旧版本)的情况。
- 在 `
process.c` 的 第 207 行的代码中存在 0622 的默认模式。这只是一个备用选项,除非代码以不寻常的方式编译,否则不应激活。 - 在 `
configure.ac` 的 第 811 行中应用了 0620 的默认模式,这在使用 autotools 编译 Screen 时会产生安全的默认值。 -
在 `
acconfig.h` 的 第 81 行中,有如下说明:定义 PTYMODE,如果您不喜欢 0622 的默认值,它允许公开写入您的 pty。
因此,在该版本中,autoconf 级别的默认模式与源代码级别的默认模式之间存在不一致,但最终(安全的)autoconf 默认值占优。
现在让我们看看 Screen 5.0.0 的情况。
- configure.ac 文件在 提交 df1c012227 中被重写。此更改在 autoconf 级别放弃了 0620 的默认模式。
- 在后续的 提交 78a961188f7 中,重新引入了 pty-mode 配置开关,这次默认模式为 0622。
- 因此,在 5.0.0 版本中,源代码级别的默认值和 autoconf 级别的默认值之间不再存在不匹配,但默认值现在不安全。
错误修复
我们未能找到 Screen 5.0.0 的任何发行说明,除了少数 ChangeLog 条目。看来更改默认 PTY 模式为 0622 并非有意为之。
补丁 0002 在 screen-5.0.0-patches.tar.gz 中,通过在 configure.ac 脚本中恢复安全的默认 PTY 模式来解决此问题。请注意,您需要运行 `autoreconf` 才能使更改生效。
我们建议打包人员主动传递 configure 开关 `--with-pty-mode=0620`,以便在旧版本的 Screen 上也能明确选择此项。
受影响的发行版
Gentoo Linux 和 Fedora Linux 向 Screen 的 configure 脚本传递了明确的安全 `--with-pty-mode`。对于未在下方列为受影响的发行版,我们没有检查它们是否也在执行此操作,或者它们是否依赖于旧版本 Screen 中存在的安全默认值。
Arch Linux
在 Arch Linux 上,包构建不传递 `--with-pty-mode` 开关,导致应用了新的默认值,从而使当前 Arch Linux 上的 Screen 易受此问题的影响。
NetBSD
NetBSD 受此问题的影响与 Arch Linux 相同。
3.d) 通过套接字查找错误消息进行文件存在性测试 (CVE-2025-46804)
当 Screen 以 setuid-root 权限运行时,这是一个轻微的信息泄露,存在于较旧的 Screen 版本以及 5.0.0 版本中。Screen.c 中 从第 849 行开始的代码以 root 权限检查生成的 `SocketPath`,并提供错误消息,允许未经授权的用户推断出原本无法获得的信息。
一种简单的方法是使用 `SCREENDIR` 环境变量。以下是一个在当前 Arch Linux 上有效���示例:
# this can be used to test whether /root/.lesshst exists and is a regular file
user$ SCREENDIR=/root/.lesshst screen
/root/.lesshst is not a directory.
# this allows to deduce that the directory /root/.cache exists
user$ SCREENDIR=/root/.cache screen
bind (/root/.cache/1426.pts-0.mgarch): Permission denied
# this tells us that the path /root/test does not exist
user $ SCREENDIR=/root/test screen
Cannot access /root/test: No such file or directory
错误修复
补丁 0002 在 screen-4.9.1-patches.tar.gz 中,以及 补丁 0005 在 screen-5.0.0-patches.tar.gz 中,通过在 Screen 以 setuid-root 权限安装并且目标路径不受进程实际 UID 控制时仅输出通用错误消息来解决此问题。
受影响的发行版
我们考虑过的所有发行版都受到影响。
3.e) 发送信号时的竞争条件 (CVE-2025-46805)
在 socket.c 的 第 646 行和 第 882 行存在与向 setuid-root 上下文中的用户提供的 PID 发送信号相关的时间检查/时间使用(TOCTOU)竞争条件。
`CheckPid()` 函数会 CheckPid() 函数将权限降至真实用户 ID,并检查内核是否允许使用这些凭据向目标 PID 发送信号。实际的信号稍后通过 `Kill()` 发送,可能使用完整的 root 权限。此时,之前检查过的 PID 可能已被另一个特权进程替换。也有可能通过欺骗(特权)Screen 守护进程向其自身发送信号,因为进程总是被允许向自己发送信号。
目前这只应允许发送 SIGCONT 和 SIGHUP 信号,因此影响可能仅限于本地拒绝服务或轻微的完整性损坏。
此问题影响 Screen 5.0.0 和较旧的 4.x 版本,当 Screen 以 setuid-root 权限安装时。此问题源于对 CVE-2023-24626 的一个 不完整修复:在此不完整修复之前,即使没有赢得竞争条件,也可以将相关信号发送到任意进程。
错误修复
补丁 0003 在 screen-4.9.1-patches.tar.gz 中,以及 补丁 0006 在 screen-5.0.0-patches.tar.gz 中,通过以真实 UID 权限发送实际信号(就像 `CheckPid()` 所做的那样)来解决此问题。
受影响的发行版
我们考虑过的所有发行版都受到影响。
3.f) 使用 strncpy() 不当导致发送命令时崩溃
我们认为这是一个非安全问题,但仍应优先修复。该问题仅在 Screen 5.0.0 版本中发现。
在 提交 0dc67256 中,一些 `strcpy()` 调用被替换为 `strncpy()`。作者显然不知道 `strncpy()` 的不幸语义。此函数并非用于安全字符串处理,而是用于维护固定长度的零填充缓冲区。因此,`strncpy()` 在遇到第一个 `\0` 字节时不会停止将数据写入目标缓冲区,而是写入零直到缓冲区完全填满。
除了导致性能不佳外,这还会触发 attacher.c 第 465 行的一个错误。以下更改已应用于此处:
- strcpy(p, *av);
+ strncpy(p, *av, MAXPATHLEN);
p += len;
这些行是以下 for 循环的一部分,该循环处理命令行参数以将它们发送到正在运行的 Screen 会话。
for (; *av && n < MAXARGS - 1; ++av, ++n) {
size_t len;
len = strlen(*av) + 1;
if (p + len >= m.m.command.cmd + ARRAY_SIZE(m.m.command.cmd) - 1)
break;
strncpy(p, *av, MAXPATHLEN);
p += len;
}
`strncpy()` 调用始终将 `MAXPATHLEN` 字节作为目标缓冲区大小传递。对于 `for` 循环的第一次迭代,当 `p` 指向 `screen.h` 第 148 行中声明的 `struct Message.command.cmd` 缓冲区开头时,这是正确的。然而,对于 `for` 循环的后续迭代,当 `p` 被 `len` 递增时,则不再正确。这意味着后续的 `strncpy()` 调用将在缓冲区末尾写入过量的 `\0` 字节。
当向正在运行的 Screen 实例传递多个命令参数时,可以在当前 Arch Linux 上观察到此结果:
# create a new screen session
user$ screen -S myinstance
# and detach from it again
(screen) user$ <Ctrl A> d
# now try to send a command to the running session
user$ screen -S myinstance -X blankerprg /home/$USER/blanker
*** buffer overflow detected ***: terminated
Aborted (core dumped)
两个命令参数导致上面描述的 `for` 循环进行两次迭代;第二次迭代将触发缓冲区溢出检测。仅在 Screen 编译时启用了 `_FORTIFY_SOURCE` 功能时才会出现可见错误。否则,即使在编译时使用 `-fsanitize=address` 也没有看到错误,这可能是因为目标缓冲区之后跟着另一个长缓冲区 `char message[MAXPATHLEN * 2]`(因此只覆盖了应用程序有效载荷数据)。
此问题允许调用者用零覆盖 `cmd` 缓冲区之后的 `MAXPATHLEN` 字节内存,这可能导致 Screen 中的完整性损坏,尤其是在以 setuid-root 权限运行时。但是,由于内存中跟着一个等大的缓冲区 `writeback[MAXPATHLEN]`,因此攻击者应该没有办法利用此问题。
为了解决这个问题,需要将 `MAXPATHLEN` 替换为 `p` 中实际剩余的字节数。此外,理想情况下,所有 `strncpy()` 调用都应替换为 `snprintf(target, target_size, "%s", source)`,以避免目标缓冲区意外进行零填充。
我们想知道为什么这个问题会在 Screen 5.0.0 中存在这么长时间而没有人注意到。一部分解释可能是 Screen 5.0.0 版本目前只在少数发行版中可用。另一个方面是,可能只有少数用户使用此功能向正在运行的 Screen 会话发送命令。我们仍然在 screen-users 邮件列表中找到了一个不太久远的关于 此问题的报告。
错误修复
补丁 0003 在 screen-5.0.0-patches.tar.gz 中,通过将 `strncpy()` 更改为 `snprintf()` 并正确传递目标缓冲区中剩余的空间量来解决此问题。
受影响的发行版
所有提供 screen-5.0.0 的发行版都受到影响。
4) Screen 的 setuid-root 实现中可能存在的其他问题
在修复问题 3.e 的错误修复期间,我们还注意到对 CVE-2023-24626 的原始(不完整)错误修复在目标会话以非 root 权限运行时,对 Screen 的多用户模式引入了回归。在这种情况下,目标会话将权限降至某个 UID X,然后尝试向某个 UID Y(客户端)发送信号,这将始终失败。
这表明在 Screen 的多用户模式中实际上需要考虑三个不同的 UID:用于执行特权操作的有效 UID 0、创建会话的用户真实 UID 和附加会话的用户真实 UID。我们不认为当前的 Screen 代码正确地考虑了这一点。
这还引起了我们的注意,由 `root` 创建的 Screen 多用户会话将“降权”为创建用户的真实 UID,即 UID 0,从而实际上根本不执行降权。
5) 一般性建议
从 Screen 5.0.0 的更改中,我们可以看到长期以来一直在尝试重构代码库,而在此之前,代码库仍以 K&R 风格 C 编写。然而,在此重构过程中,一些长期建立的安全逻辑已被破坏,导致了问题 3.a 和 3.c。在进行进一步重构之前,某种测试套件可能有助于验证实现的各种安全属性。此外,任何处理此代码库的人显然都应该了解 setuid-root 二进制文件中存在的许多危险。
即使在修复了我们在审查期间发现的问题之后,仍然存在许多让我们担忧的领域,如上一节所述。此外,还有一系列文件系统操作,其安全性岌岌可危。
此外,Screen 还有一个广泛的设计问题:它始终以提升的权限运行,并且仅选择性地为被认为危险的操作放弃权限。对于健壮的 setuid-root 程序,应该是反过来的:默认情况下应放弃权限,仅为实际需要特权的操作提高权限。
为了使 Screen 能够以 setuid-root 权限运行,我们建议在这方面实施设计更改,并仔细审查剩余的每个特权操作的安全性。我们还建议添加逻辑以删除除在 setuid-root 上下文中明确允许的环境变量之外的所有环境变量。应清理 PATH 等其他环境变量,使其仅指向受信任的系统目录。
鉴于以上所有情况,我们不建议目前安装 Screen setuid-root(无论是 5.0.0 版本还是较旧的 4.9 版本)。另一种选择是仅以选择加入的方式提供多用户功能,例如,只允许受信任组的成员运行多用户版本的 Screen。
6) 有问题的协调披露流程和上游状态
当我们于 2025 年 2 月向 Screen 上游报告这些问题时,我们根据 我们的政策提供了通常的协调披露流程。上游表示非常有兴趣将这些问题保密,以便在发布前开发错误修复。为此沟通了为期一到两个月的时间。我们对这个漫长的禁运期不太满意,但我们理解许多上游缺乏资源,因此我们同意了这些条款。
大约一个月后,上游开始有一些活动,并开始了关于错误修复的讨论。这些讨论并非非常有成效,但我们仍然认为上游能够处理这些问题——鉴于上游本身要求我们进行 Screen 安全审查。
然而,直到我们提供的最长 90 天禁运期结束前约两周,我们才进行进一步沟通。当时,我们询问了上游的当前状态,并指出发布日期临近。我们不得不发现,上游直到此时都未利用这段长时间来处理错误修复。与此同时,NetBSD 等更多发行版更新到 Screen 5.0.0,完全受到问题 3.a 的影响,却不知道风险。
正是在这个时候,我们才意识到上游对 Screen 代码库的熟悉程度不够,无法完全理解我们报告的安全问题,并且他们没有明确说明他们需要比我们只审查他们提出的补丁更多的帮助。
与上游的沟通变得越来越困难:上游突然希望比我们建议的更早发布错误修复,尽管许多问题仍未解决。我们试图劝阻上游,并迅速联系了 distros 邮件列表,让其他发行商了解这些问题。我们特别向该列表建议了一个超出我们通常提供的最长 90 天禁运期的发布日期,以适应禁运最终陷入的混乱局面。
在与上游合作开发补丁的进一步尝试(并非非常有成效)之后,我们决定自己处理此事。我们开发了缺失的错误修复,并调整和妥善记录了上游已起草的补丁。在此过程中,我们推断出,一个专注的上游可能能够在约两周内完成协调披露流程。
我们对此次协调披露的进展不满意,并将努力在未来更早地关注此类问题。这次经历也揭示了 Screen 上游的整体状况。它似乎缺乏人力和专业知识,这对于如此广泛的开源实用程序来说是令人担忧的。我们希望这次发布能帮助引起人们对这一点的关注,并在未来改善这一状况。
7) 影响矩阵
| 系统 | Screen 版本 | 特殊权限 | 受影响 | 注释 |
|---|---|---|---|---|
| Arch Linux | 5.0.0 | setuid-root | 3.a, 3.b, 3.c, 3.d, 3.e, 3.f | |
| Debian 12.10 | 4.9.0 | 3.b (部分) | ||
| Ubuntu 24.04.2 | 4.9.1 | 3.b (部分) | ||
| Fedora 42 | 5.0.0 | setgid-screen | 3.b (部分), 3.f | 5.0.0 仅在最近发布的 Fedora 42 中找到 |
| Gentoo | 4.9.1 | setgid-utmp (如果设置了 multiuser USE 标志则为 setuid-root) | 3.b (部分) | 5.0.0 可通过不稳定 ebuild 使用 |
| openSUSE TW | 4.9.1 | 3.b (部分) | ||
| FreeBSD 14.2 | 4.9.1 | setuid-root | 3.b, 3.d, 3.e | 版本 5.0.0 可选提供但尚未稳定。 |
| NetBSD 10.1 | 5.0.0 | setuid-root | 3.a, 3.b, 3.c, 3.d, 3.e, 3.f (无明显崩溃) | 基于 pkgsrc 包1,最近才发布了 5.0.0 的更新。 |
| OpenBSD 7.7 | 4.9.1 | 3.b (部分) |
8) 上游错误修复
Screen 4.9.1
上游已将 Screen 4.9.1 的错误修复推送到其 screen-v4 分支。可以在此处找到以下错误修复:
- 提交 049b26b22e1 修复了 PTY 模式问题(第 3.b 项,CVE-2025-46802)。
- 提交 e0eef5aac45 修复了文件存在性测试问题(第 3.d 项,CVE-2025-46804)。
- 提交 161f85b98b7 修复了信号发送问题(第 3.e 项,CVE-2025-46805)。
我们不知道上游是否有发布 4.9.2 错误修复版本的努力,也没有包含这些修复的新 Git 标签。
Screen 5.0.1
为了修复在 Screen 5.0.0 中发现的问题,上游 宣布了 5.0.1 错误修复版本。上游已将错误修复推送到其 screen-v5 分支。可以在此处找到以下错误修复:
- 提交 e894caeff 修复了日志文件重开问题(第 3.a 项,CVE-2025-23395)。
- 提交 d10eb5b2f 修复了 PTY 模式问题(第 3.b 项,CVE-2025-46802)。
- 提交 d5d7bf43f 修复了默认 PTY 模式问题(第 3.c 项,CVE-2025-46803)。
- 提交 710cda5c7 修复了文件存在性测试问题(第 3.d 项,CVE-2025-46804)。
- 提交 a17b0da26 修复了信号发送问题(第 3.e 项,CVE-2025-46805)。
- 提交 2bdebfc98 修复了与 strncpy 相关的崩溃(第 3.f 项)。
还有一个 v.5.0.1 Git 标签,包含这些修复。
时间线
| 2024-07-01 | 上游 转发了一个审查请求给我们。 |
| 2025-01-08 | 我们开始审查工作。 |
| 2025-02-07 | 我们通过电子邮件私下将问题报告给了 Screen 上游,并提供了协调披露。 |
| 2025-02-07 | 上游表示他们需要 1-2 个月的时间来处理这些问题,可能需要我们提供的 90 天最长禁运期的大部分时间。 |
| 2025-02-11 | 我们在 GNU Savannah 错误跟踪器中创建了 私有错误来处理每个发现。 |
| 2025-03-11 | 在 GNU Savannah 私有错误中,关于一些发现的补丁开始了一些讨论。 |
| 2025-04-29 | 近一个月没有明显活动,并且 90 天的最长禁运期即将到来,我们询问了上游的当前状态和报告发布程序。 |
| 2025-04-30 | 上游开始重新工作,试图在 90 天禁运期结束前提出修复方案。我们在 GNU Savannah 私有错误中就各种补丁提供了建议。 |
| 2025-04-30 | 在与上游就 CVE 分配的讨论中出现了一些不明确之处后,我们决定为相关安全问题分配 CVE。 |
| 2025-04-30 | 上游宣布他们打算在周末发布一些内容,而错误修复仍然缺失。我们敦促他们不要这样做。鉴于此,我们迅速将本报告的草稿转发给了 distros 邮件列表,让其他发行商有机会在这些发现公开前做出反应。 |
| 2025-05-05 | 尽管我们没有得到明确答复,但上游最终没有单方面发布。鉴于混乱的局面,我们向 distros 邮件列表建议了一个发布日期 2025-05-12,这比我们通常为上游提供的最长 90 天禁运期晚了几天。 |
| 2025-05-07 | 与上游合作开发缺失的错误修复的进一步尝试似乎徒劳无功。我们开始自己开发所有必需的补丁,其中一些是基于上游 Savannah 错误中已经讨论过的补丁。我们将完成并测试的 Screen 4.9.1 和 Screen 5.0.0 补丁分享给了 distros 邮件列表和上游。 |
| 2025-05-08 | 上游抱怨我们分发的某些补丁中的 `Author:` 标签不正确(我们没有收到上游正式完成的补丁,只有复制粘贴的片段)。因此,我们调整了这些补丁的作者信息以解决此投诉,并再次与 distros 邮件列表分享了更新的结果。 |
| 2025-05-12 | 本报告按计划在我们的博客和 oss-security 邮件列表上发布。 |
| 2025-05-13 | 我们审查了目前已发布的上游 screen-v4 和 screen-v5 分支中的提交。 |
参考文献
- Screen GNU Savannah 项目主页
- openSUSE Bugzilla Screen 审查 Bug
- 指向私有的 GNU Savannah Bug 的链接(发布后上游似乎也无法使其可访问)
变更历史
| 2025-05-14 | 添加了上游发布信息。修正了一些补丁包下载名称的不完整标签。 |
| 2025-05-30 | 添加了关于 NetBSD 使用 pkgsrc 二进制文件的说明1。添加了关于 Arch Linux 作为对这些问题反应而移除 setuid-root 位的信息。 |