알 수 없는 시스템 호출 후 sshd 연결이 끊어집니다.

알 수 없는 시스템 호출 후 sshd 연결이 끊어집니다.

저는 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실행 중인 프로세스에 연결하면 다음과 같은 출력이 표시됩니다.sshdstrace -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

~처럼사용자 414777이 댓글을 달았습니다., 누락된 시스템 호출은 다음과 같습니다.clock_nanosleep_time64. 이것은 원래 커널에 추가되었습니다5.6 지점솔루션의 일부로2038년 문제, 5.1부터 모든 브랜치로 백포트되었습니다.

GNU C 라이브러리는 v2.31에서 이러한 64비트 시간 함수를 사용하기 시작했으며 OpenSSH에서 겪고 있는 문제는 다음과 같습니다.릴리즈 노트:

시간 시스템 호출에 대한 시스템 호출 래퍼는 이제 사용 가능한 경우 새로운 time64 시스템 호출을 사용합니다. 32비트 대상에서 이러한 래퍼는 새 시스템 호출을 먼저 호출하려고 시도하고 존재하지 않는 경우 이전 32비트 시간 시스템 호출로 대체합니다. 이는 -ENOSYS를 반환하여 지원되지 않는 시스템 호출을 정상적으로 처리할 수 없는 환경에서 문제를 일으킬 수 있습니다. Seccomp 샌드박스는 이 문제의 영향을 받습니다.

내 문제를 해결하기 위해 다음을 수행할 수 있습니다.

  1. 커널을 5.1 이상으로 업데이트하세요.
  2. glibc를 2.30으로 다운그레이드
  3. time64 시스템 호출을 생략하도록 glibc 2.32 패치
  4. 다른 샌드박스를 사용하여 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

관련 정보