Bug 14796 - 64 bit time and seccomp conflict (OpenSSH server crash)
Summary: 64 bit time and seccomp conflict (OpenSSH server crash)
Status: RESOLVED FIXED
Alias: None
Product: buildroot
Classification: Unclassified
Component: Other (show other bugs)
Version: 2022.02
Hardware: All Linux
: P5 major
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-05-10 06:54 UTC by Lacky
Modified: 2022-09-18 15:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lacky 2022-05-10 06:54:57 UTC
I found that glibc with support for 64-bit time could crash OpenSSH (sshd) process with enabled seccomp. Test environment:
-Kernel 4.14.x with enabled seccomp
-32 bit ARM CPU
-glibc 2.34
-OpenSSH 8.9p1 with enabled seccomp sandbox
-Toolchain: GCC 10

Syscall wrappers like a clock_gettime (https://github.com/bminor/glibc/blob/glibc-2.34/sysdeps/unix/sysv/linux/clock_gettime.c) first run syscall dedicated for kernels that support 64 bit time. If this syscall failed with ENOSYS error, then glibc calls traditional variant for 32 bit time. If you run sshd with strace you can find entries like this:

4628 clock_gettime64(CLOCK_BOOTTIME, 0xbe8c1488) = -1 ENOSYS (Function not implemented)
4628 clock_gettime(CLOCK_BOOTTIME, {tv_sec=247, tv_nsec=653301168}) = 0

Usually this is not a problem, but sshd uses seccomp. OpenSSH in its source code adds to seccomp syscalls that can be found in kernel headers (https://github.com/openssh/openssh-portable/blob/master/sandbox-seccomp-filter.c). If you use kernel without support for 64 bit time then related syscalls are not registered as allowed in seccomp. If sshd tries to use clock_gettime from glibc after initializing seccomp, the process will be killed:

4637 clock_gettime64(CLOCK_BOOTTIME, <unfinished ...>
4637 <... clock_gettime64 resumed> <unfinished ...>) = ?
4637 +++ killed by SIGSYS +++
4628 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=4637, si_uid=101, si_status=SIGSYS, si_utime=4, si_stime=0} ---
4628 kill(4637, SIGKILL)

From user's perspective it looks like connection with server was closed before any password prompt.

Support for 64-bit time has been added in kernel 5.1 (https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.1-Year-2038-Syscalls). Older (but still supported) kernels like 4.14 don’t have this feature.

Temporary solutions to fix this bug are:
-Building OpenSSH without seccomp
-Building kernel without seccomp
-Patching glibc to remove clock_gettime64 syscall (and other syscalls that use 64 bit time).

Disabling seccomp is the easiest workaround, but it decreases security of sshd.
Comment 1 Thomas Petazzoni 2022-09-18 13:06:01 UTC
Peter Korsgaard and I finally had a look at this today, and we think we finally understand what is going on.

glibc does not care about the kernel headers when deciding whether to use the clock_gettime64() syscall or not: it always use it, and if that fails at runtime, it falls back to clock_gettime(). This is how glibc ends up using clock_gettime64() even if your kernel does not support it.

On the other hand, the OpenSSL seccomp code relies on kernel headers to decide whether the clock_gettime64() syscall should be in the allowed list of syscalls or not.

So when you are in a situation where glibc is recent, but your kernel is older, you get into precisely the problem you have: glibc tries to use clock_gettime64, but OpenSSH seccomp configuration prevents that, which does not allow glibc to gracefully fallback to clock_gettime.

The only solution that we see is to disable seccomp support in OpenSSH. Peter will send a patch for this. I will keep this bug open until this patch is posted and hopefully merged.
Comment 2 Yann E. MORIN 2022-09-18 15:06:52 UTC
Lacky, All,

Thanks for the report.

We believe this has now been fixed with commit f204766b8fd8 (package/openssh:
allow sandboxing to be disabled as workaround for seccomp issues) from Peter,
that has just been applied.

I've now closed this bug report. If there is still an issue, please reopen.

Regards,
Yann E. MORIN.