
私はLinuxカーネル4.19、OpenSSH_8.3p1、OpenSSL 1.1.1h、glibc 2.32を実行し、buildrootを使用してGCC 10.2でコンパイルした組み込みシステム(Cortex-A8 CPUベース)を開発しています。
クライアントが 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
running を介して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を使用してシステムを構築するときにも発生します。
この未知のシステムコールが何であるかを判断する方法はありますか?カーネルに何か抜けましたか?
答え1
〜のようにuser 414777がコメントしました。、欠落しているシステムコールは次のとおりです。clock_nanosleep_time64。これは元のカーネルに追加されました5.6支店ソリューションの一部として2038年の問題、5.1以降、すべてのブランチにバックポートされています。
GNU Cライブラリはv2.31でこれらの64ビット時間関数を使用し始め、OpenSSHで発生している問題は次のとおりです。リリースノート:
タイムシステムコールのシステムコールラッパーは、利用可能な場合は新しいtime64システムコールを使用します。 32ビットターゲットでは、これらのラッパーは最初に新しいシステムコールを呼び出そうとし、存在しない場合は古い32ビットタイムシステムコールに置き換えます。これは、-ENOSYSを返すことでサポートされていないシステムコールを正常に処理できない環境で問題を引き起こす可能性があります。 Seccomp サンドボックスはこの問題の影響を受けます。
私の問題を解決するには、次のことができます。
- カーネルを5.1以上にアップデートしてください。
- glibcを2.30にダウングレード
- time64 システムコールを省略する glibc 2.32 パッチ
- 異なるサンドボックスを使用したOpenSSHのコンパイル
私はカーネルアップデートパスが最も将来の証拠であるように見えるので、それを選択することにしました。
答え2
私も同じ問題があり、顧客が4.19 LTSカーネルの使用に固執したので、glibcパッチ方法を選択しました。
次のパッチは、私のシステム(glibc 2.32、linux 4.19.178、openssh 8.4p1)でこの問題を解決しました。
diff --git a/sysdeps/unix/sysv/linux/time64-support.h b/sysdeps/unix/sysv/linux/time64-support.h
index 8466d37f8f..35bf73f5ee 100644
--- a/sysdeps/unix/sysv/linux/time64-support.h
+++ b/sysdeps/unix/sysv/linux/time64-support.h
@@ -54,6 +54,7 @@ extern int __time64_support attribute_hidden;
static inline bool
supports_time64 (void)
{
+ return false;
#ifdef __ASSUME_TIME64_SYSCALLS
return true;
#else
そして
diff --git a/sysdeps/unix/sysv/linux/arm/arch-syscall.h b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
index 9352319740..7b73ec2a95 100644
--- a/sysdeps/unix/sysv/linux/arm/arch-syscall.h
+++ b/sysdeps/unix/sysv/linux/arm/arch-syscall.h
@@ -29,7 +29,9 @@
#define __NR_clock_gettime 263
#define __NR_clock_gettime64 403
#define __NR_clock_nanosleep 265
+#if 0
#define __NR_clock_nanosleep_time64 407
+#endif
#define __NR_clock_settime 262
#define __NR_clock_settime64 404
#define __NR_clone 120