建議停止使用 utmp 以消除 Glibc 的 Y2038 問題

SUSE 未來技術團隊(Future Technology Team,開發 openSUSE MicroOS 和 SLE Micro)的負責人 Thorsten Kukuk 曾領導 SUSE LINUX Enterprise Server 項目長達 10 年,他建議擺脫 /var/run/utmp 文件完全解決 Glibc 中的 Y2038 問題的發行版。 建議將所有使用 utmp、wtmp 和 lastlog 的應用程序遷移到使用 systemd-logind 獲取用戶列表。

19 年 2038 月 32 日,64 位 time_t 類型指定的紀元時間計數器將溢出。 在 Glibc 中,儘管引入了 32 位 time_t 類型,但為了保持與 64 位用戶空間應用程序的兼容性,32 位平台上的某些情況下仍然使用 32 位 time_t 類型。 其中一種情況是 /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 準備用於寫入和讀取用戶信息的 API。 systemd 254 下一版本的代碼庫已包含使用 sd-login.h API 或通過 DBUS 通過 libsystemd 提供替換 utmp 數據所需的功能。

來源: opennet.ru

添加評論