建议停止使用 utmp 以消除 Glibc 的 Y2038 问题

SUSE 未来技术开发小组(Future Technology Team,开发 openSUSE MicroOS 和 SLE Micro)的负责人 Thorsten Kukuk 曾领导 SUSE LINUX Enterprise Server 项目长达 10 年,他建议摆脱 /var/run/utmp 文件在发行版中完全解决 Glibc 中的 2038 问题。 建议将所有使用 utmp、wtmp 和 lastlog 的应用程序转换为使用 systemd-logind 获取用户列表。

19 年 2038 月 32 日,64 位 time_t 类型指定的纪元时间计数器将溢出。 尽管引入了 32 位 time_t 类型,Glibc 在某些情况下仍会在 64 位平台上继续使用 32 位 time_t 类型,以保持与 32 位用户空间应用程序的兼容性。 其中一种情况是 /var/run/utmp 文件,它存储有关当前登录系统的用户的数据。 utmp 中的时间字段使用 XNUMX 位 time_t 值指定。

简单地将 utmp 中的时间字段从 32 位类型替换为 64 位类型是行不通的,因为这将导致 Glibc ABI 发生变化(类型将在诸如 login()、getutid() 和 utmpname 等函数中发生变化()) 并破坏与使用 utmp 的应用程序的兼容性,包括 w、who、uptime、login、su、sudo、useradd、systemd、sysvinit、tcsh、xterm 显示管理器、emacs、openssh、qemu、samba、rsyslog 等。 由于存在大量可能的陷阱和复杂性,替换 utmp 中 time_t 类型的想法被 Glibc 开发人员拒绝了。 出于同样的原因,使用 utmp 结构中的可用空闲空间来添加额外的 64 位时间字段的选项被丢弃。

另外,改变utmp中的类型位深度并不能解决其他现有问题,我也想摆脱这些问题。 例如,写入 utmp 需要特殊权限,这需要授予进程额外的权限。 另一个问题是,utmp架构允许本地用户进行DoS攻击,通过操纵文件锁导致utmp服务中断,从而无法确保utmp的内容反映了系统的真实状态。 建议使用额外的后台进程来处理对 utmp 的访问,但对于此类任务,已经有一个 systemd-logind 进程,因此不建议启动另一个专门进程(应用程序必须同时将数据传输到两个处理程序)。

同时,即使解决了DoS攻击的问题,utmp的内容仍然只是信息性的,并不能保证反映现实。 例如,不同的模拟器和终端多路复用器会以不同的方式反映其状态 - 启动 XNUMX 个 GNOME 终端将导致 XNUMX 个用户反映在 utmp 中,而在 KDE 中启动 XNUMX 个 konsole 或 xterm 终端将导致 XNUMX 个用户。 screen 和 tmux 的行为也同样不同:在第一种情况下,每个会话都被视为一个单独的用户,而在第二种情况下,所有会话仅反映一个用户。

因此,作为最简单的解决方案,建议将所有应用程序转移到使用已经存在的替代systemd-logind服务,并且在当前没有程序访问utmp后,停止记录到utmp。 为了取代 wtmp,建议使用 systemd-journald 准备用于写入和读取用户信息的软件接口。 systemd 254 下一版本的代码库已包含使用 sd-login.h API 或通过 DBUS 通过 libsystemd 提供 utmp 替换数据所需的功能。

来源: opennet.ru

添加评论