Ssh

未知系統呼叫後 sshd 斷開連接

  • March 24, 2021

我正在開發一個嵌入式系統(基於 Cortex-A8 CPU),執行 Linux 核心 4.19、OpenSSH_8.3p1、OpenSSL 1.1.1h、glibc 2.32,使用 buildroot 使用 GCC 10.2 編譯。

當客戶端嘗試通過 ssh 連接時,控制台會記錄以下消息,並且客戶端會斷開連接:

[  120.954119] audit: type=1326 audit(1599913110.890:2): auid=4294967295 uid=1001 gid=1001 ses=4294967295 pid=430 comm="sshd" exe="/usr/sbin/sshd" sig=31 arch=40000028 syscall=407 compat=0 ip=0xb6b5b080 code=0x0
[  120.979667] audit: type=1701 audit(1599913110.910:3): auid=4294967295 uid=1001 gid=1001 ses=4294967295 pid=430 comm="sshd" exe="/usr/sbin/sshd" sig=31 res=1

添加審計包後,ausearch -i有以下輸出:

type=SECCOMP msg=audit(09/12/20 12:32:13.500:4) : auid=unset uid=sshd gid=sshd ses=unset pid=369 comm=sshd exe=/usr/sbin/sshd sig=SIGSYS arch=armeb syscall=unknown-syscall(407) compat=0 ip=0xb6b3f080 code=kill
----
type=ANOM_ABEND msg=audit(09/12/20 12:32:13.510:5) : auid=unset uid=sshd gid=sshd ses=unset pid=369 comm=sshd exe=/usr/sbin/sshd sig=SIGSYS res=yes

當我通過執行附加strace到正在執行的sshd程序時strace -y -p $(pgrep sshd),我得到以下輸出:

[pid  2248] write(5<socket:[8970]>, "\0\0\0\16ssh-connection\0\0\0\0", 22 <unfinished ...>
[pid  2244] read(6<socket:[8971]>,  <unfinished ...>
[pid  2248] <... write resumed>)        = 22
[pid  2244] <... read resumed>"\0\0\0\27", 4) = 4
[pid  2248] clock_gettime(CLOCK_BOOTTIME,  <unfinished ...>
[pid  2244] read(6<socket:[8971]>,  <unfinished ...>
[pid  2248] <... clock_gettime resumed>{tv_sec=1838, tv_nsec=947294512}) = 0
[pid  2244] <... read resumed>"\4\0\0\0\16ssh-connection\0\0\0\0", 23) = 23
[pid  2248] clock_nanosleep_time64(CLOCK_REALTIME, 0, {tv_sec=0, tv_nsec=22439932944646645},  <unfinished ...>
[pid  2244] poll([{fd=6<socket:[8971]>, events=POLLIN}, {fd=7<pipe:[8972]>, events=POLLIN}], 2, -1 <unfinished ...>
[pid  2248] <... clock_nanosleep_time64 resumed> <unfinished ...>) = ?
[pid  2244] <... poll resumed>)         = 1 ([{fd=7, revents=POLLHUP}])
[pid  2244] read(7<pipe:[8972]>,  <unfinished ...>
[pid  2248] +++ killed by SIGSYS +++

當我使用 GCC 9.3 和 glibc 2.31 建構系統時,這個問題也存在。

有沒有辦法找出這個未知的系統呼叫是什麼?核心中是否缺少某些內容?

正如user414777 所評論的,缺少的系統呼叫是clock_nanosleep_time64。這最初是作為2038 年問題解決方案的一部分添加到5.6 分支的核心中,並且從 5.1 開始向後移植到每個分支。

GNU C 庫在 v2.31 中開始使用這些 64 位時間函式,我在使用 OpenSSH 時遇到的問題在發行說明中有所提及:

時間系統呼叫的系統呼叫包裝器現在使用新的 time64 系統呼叫(如果可用)。在 32 位目標上,這些包裝器嘗試首先呼叫新的系統呼叫,如果它們不存在,則回退到舊的 32 位時間系統呼叫。這可能會導致無法通過返回 -ENOSYS 來正常處理不受支持的系統呼叫的環境中出現問題。Seccomp 沙箱受此問題影響。

要解決我的問題,我可以:

  1. 將核心更新到至少 5.1
  2. 將 glibc 降級到 2.30
  3. 修補 glibc 2.32 以省略 time64 系統呼叫
  4. 使用不同的沙箱編譯 OpenSSH

我決定採用核心更新路徑,因為這似乎是最具前瞻性的。

引用自:https://unix.stackexchange.com/questions/618737