| Summary: | seccomp issue after upgrading openssl | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Product: | Portable OpenSSH | Reporter: | brunni | ||||||
| Component: | sshd | Assignee: | Assigned to nobody <unassigned-bugs> | ||||||
| Status: | CLOSED FIXED | ||||||||
| Severity: | major | CC: | ahmedsayeed1982, blowfist, djm, dtucker, tg | ||||||
| Priority: | P5 | ||||||||
| Version: | 8.1p1 | ||||||||
| Hardware: | Other | ||||||||
| OS: | Linux | ||||||||
| Bug Depends on: | |||||||||
| Bug Blocks: | 3217 | ||||||||
| Attachments: |
|
||||||||
|
Description
brunni
2019-10-31 12:02:26 AEDT
> Is it possible that there are still issues?
it's possible, but it depends on many variables. If you build with
./configure --with-sandbox=seccomp_filter --with-cflags=-DSANDBOX_SECCOMP_FILTER_DEBUG
then connect to it you should get a log message with the syscall that's being denied (but note that the resulting binary is not signal safe, so do not deploy it in production).
It won't compile with --with-cflags=-DSANDBOX_SECCOMP_FILTER_DEBUG
Kernel headers in /usr/include are from 4.9.195 - it looks like ggc does not like them?
cc -g -O2 -pipe -Wno-error=format-truncation -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fno-builtin-memset -fstack-protector-strong -DSANDBOX_SECCOMP_FILTER_DEBUG -fPIE -I. -I. -I/usr/lib/ssl/include -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -DSSHDIR=\"/etc\" -D_PATH_SSH_PROGRAM=\"/tmp/openssh/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/tmp/openssh/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/tmp/openssh/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/tmp/openssh/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/tmp/openssh/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c sandbox-seccomp-filter.c -o sandbox-seccomp-filter.o
In file included from /usr/include/bits/types/siginfo_t.h:6:0,
from /usr/include/signal.h:57,
from /usr/include/sys/param.h:28,
from includes.h:26,
from sandbox-seccomp-filter.c:38:
/usr/include/bits/types/__sigval_t.h:24:7: error: redefinition of 'union sigval'
union sigval
^~~~~~
In file included from /usr/include/asm/siginfo.h:14:0,
from sandbox-seccomp-filter.c:32:
/usr/include/asm-generic/siginfo.h:7:15: note: originally defined here
typedef union sigval {
^~~~~~
/usr/include/bits/types/siginfo_t.h:58:14: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
__pid_t si_pid; /* Sending process ID. */
^
/usr/include/bits/types/siginfo_t.h:65:10: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
int si_tid; /* Timer ID. */
^
/usr/include/bits/types/siginfo_t.h:73:14: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
__pid_t si_pid; /* Sending process ID. */
^
/usr/include/bits/types/siginfo_t.h:81:14: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
__pid_t si_pid; /* Which child. */
^
/usr/include/bits/types/siginfo_t.h:91:12: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
void *si_addr; /* Faulting insn/memory ref. */
^
/usr/include/bits/types/siginfo_t.h:110:21: error: expected ':', ',', ';', '}' or '__attribute__' before '.' token
__SI_BAND_TYPE si_band; /* Band event for SIGPOLL. */
^
In file included from /usr/include/signal.h:57:0,
from /usr/include/sys/param.h:28,
from includes.h:26,
from sandbox-seccomp-filter.c:38:
/usr/include/bits/types/siginfo_t.h:124:5: error: conflicting types for 'siginfo_t'
} siginfo_t __SI_ALIGNMENT;
^~~~~~~~~
In file included from /usr/include/asm/siginfo.h:14:0,
from sandbox-seccomp-filter.c:32:
/usr/include/asm-generic/siginfo.h:118:24: note: previous declaration of 'siginfo_t' was here
} __ARCH_SI_ATTRIBUTES siginfo_t;
^~~~~~~~~
/usr/include/bits/siginfo-consts.h:38:3: error: expected identifier before '-' token
SI_DETHREAD = -7, /* Sent by execve killing subsidiary
^
/usr/include/bits/siginfo-consts.h:73:3: error: expected identifier before '(' token
ILL_ILLOPC = 1, /* Illegal opcode. */
^
/usr/include/bits/siginfo-consts.h:96:3: error: expected identifier before '(' token
FPE_INTDIV = 1, /* Integer divide by zero. */
^
/usr/include/bits/siginfo-consts.h:121:3: error: expected identifier before '(' token
SEGV_MAPERR = 1, /* Address not mapped to object. */
^
/usr/include/bits/siginfo-consts.h:140:3: error: expected identifier before '(' token
BUS_ADRALN = 1, /* Invalid address alignment. */
^
/usr/include/bits/siginfo-consts.h:157:3: error: expected identifier before '(' token
TRAP_BRKPT = 1, /* Process breakpoint. */
^
/usr/include/bits/siginfo-consts.h:174:3: error: expected identifier before '(' token
CLD_EXITED = 1, /* Child has exited. */
^
/usr/include/bits/siginfo-consts.h:191:3: error: expected identifier before '(' token
POLL_IN = 1, /* Data input available. */
^
In file included from /usr/include/signal.h:62:0,
from /usr/include/sys/param.h:28,
from includes.h:26,
from sandbox-seccomp-filter.c:38:
/usr/include/bits/types/sigval_t.h:16:20: error: conflicting types for 'sigval_t'
typedef __sigval_t sigval_t;
^~~~~~~~
In file included from /usr/include/asm/siginfo.h:14:0,
from sandbox-seccomp-filter.c:32:
/usr/include/asm-generic/siginfo.h:10:3: note: previous declaration of 'sigval_t' was here
} sigval_t;
^~~~~~~~
In file included from /usr/include/signal.h:66:0,
from /usr/include/sys/param.h:28,
from includes.h:26,
from sandbox-seccomp-filter.c:38:
/usr/include/bits/types/sigevent_t.h:22:16: error: redefinition of 'struct sigevent'
typedef struct sigevent
^~~~~~~~
In file included from /usr/include/asm/siginfo.h:14:0,
from sandbox-seccomp-filter.c:32:
/usr/include/asm-generic/siginfo.h:290:16: note: originally defined here
typedef struct sigevent {
^~~~~~~~
In file included from /usr/include/signal.h:66:0,
from /usr/include/sys/param.h:28,
from includes.h:26,
from sandbox-seccomp-filter.c:38:
/usr/include/bits/types/sigevent_t.h:42:5: error: conflicting types for 'sigevent_t'
} sigevent_t;
^~~~~~~~~~
In file included from /usr/include/asm/siginfo.h:14:0,
from sandbox-seccomp-filter.c:32:
/usr/include/asm-generic/siginfo.h:303:3: note: previous declaration of 'sigevent_t' was here
} sigevent_t;
^~~~~~~~~~
/usr/include/bits/sigevent-consts.h:29:3: error: expected identifier before numeric constant
SIGEV_SIGNAL = 0, /* Notify via signal. */
^
make: *** [Makefile:166: sandbox-seccomp-filter.o] Error 1
Please try -current, or cherry-pick this commit: commit 3ef92a657444f172b61f92d5da66d94fa8265602 Author: Lonnie Abelbeck <lonnie@abelbeck.com> Date: Tue Oct 1 09:05:09 2019 -0500 Deny (non-fatal) shmget/shmat/shmdt in preauth privsep child. New wait_random_seeded() function on OpenSSL 1.1.1d uses shmget, shmat, and shmdt in the preauth codepath, deny (non-fatal) in seccomp_filter sandbox. (In reply to Damien Miller from comment #3) > Please try -current, or cherry-pick this commit: > > commit 3ef92a657444f172b61f92d5da66d94fa8265602 I am using the latest release and that commit is part of my source: #ifdef __NR_stat64 SC_DENY(__NR_stat64, EACCES), #endif #ifdef __NR_shmget SC_DENY(__NR_shmget, EACCES), #endif #ifdef __NR_shmat SC_DENY(__NR_shmat, EACCES), #endif #ifdef __NR_shmdt SC_DENY(__NR_shmdt, EACCES), #endif /* Syscalls to permit */ #ifdef __NR_brk SC_ALLOW(__NR_brk), #endif ok, then you'll either need to get the seccomp debugging working on your system to figure out which syscall is failing, or you could strace. (In reply to Damien Miller from comment #5) > ok, then you'll either need to get the seccomp debugging working on > your system to figure out which syscall is failing, or you could > strace. Does this help? [pid 26960] getuid32() = 39 [pid 26960] geteuid32() = 39 [pid 26960] SYS_340(0, 0x1, 0xffb91c3c, 0, 0x56668aa9) = 0 [pid 26960] SYS_340(0, 0x7, 0xffb91c3c, 0, 0x56668aa9) = 0 [pid 26960] SYS_340(0, 0x6, 0xffb91c3c, 0, 0x56668aa9) = 0 [pid 26960] prctl(0x26, 0x1, 0, 0, 0) = 0 [pid 26960] prctl(0x16, 0x2, 0x566caf1c, 0x5662064e, 0) = 0 [pid 26960] write(7, "\0\0\0I\0\0\0\5\0\0\0Alist_hostkey_types: r"..., 77 <unfinished ...> [pid 26958] <... poll resumed> ) = 2 ([{fd=5, revents=POLLIN|POLLHUP}, {fd=6, revents=POLLHUP}]) [pid 26960] +++ killed by SIGSYS +++ --- SIGCHLD (Child exited) @ 0 (0) --- No, I guess the syscall violation took down the process before strace got a chance to see what what being attempted. What's the hardware platform (you selected "other", I'm guessing S/390?) (In reply to Darren Tucker from comment #8) > What's the hardware platform (you selected "other", I'm guessing > S/390?) x86 (64 bit kernel running a 32 bit Linux) (In reply to Damien Miller from comment #5) > ok, then you'll either need to get the seccomp debugging working on > your system to figure out which syscall is failing, or you could > strace. It seems it's not my fault openssh is not compiling with seccomp debugging. See https://bugs.gentoo.org/651740 Prepare for 8.2 release; retarget bugs Created attachment 3382 [details] A patch that fixed my seccomp syscall issue I did what was suggested on the thread for the Bug 3085 and found out that my issue was caused to the syscall number 72 being denied. I found out it is the syscall pselect6 which *should* in fact be allowed. It turns out that including the syscall header file properly sets __NR_pselect6 and thus fixes this issue. (In reply to Nicholas Niro from comment #12) > Created attachment 3382 [details] > A patch that fixed my seccomp syscall issue > > I did what was suggested on the thread for the Bug 3085 and found > out that my issue was caused to the syscall number 72 being denied. > I found out it is the syscall pselect6 which *should* in fact be > allowed. It turns out that including the syscall header file > properly sets __NR_pselect6 and thus fixes this issue. I didn't expect that attaching a file would erase the rest of my comment. I just mentioned that I had exactly the same issue as the person that created this post. I compiled openssh v8.2p1 on an aarch64 system with musl-libc (statically linked and without openssl) for my project jailTools https://github.com/nniro/jailTools . This bug only seems to happen on my pine book pro. On my x86_64 system I don't have any issues. Comment on attachment 3382 [details] A patch that fixed my seccomp syscall issue Thanks for the analysis. >+#include <sys/syscall.h> I'm not sure if every distro and/or version has that file. Of the ones I have at hand, Fedora 30 (x86-64) had it at /usr/include/sys/syscall.h, while Debian (arm64) and Ubuntu (x86-64) do not (but did have it some other place that the compiler could find it). http://man7.org/linux/man-pages/man2/syscall.2.html documents it, so maybe we can rely on it... I've applied it without a configure test, we can add one later if necessary. Thanks. brunni: could you please see if this resolves your problem? (In reply to Darren Tucker from comment #15) > I've applied it without a configure test, we can add one later if > necessary. Thanks. > > brunni: could you please see if this resolves your problem? We are talking about this change? >+#include <sys/syscall.h> No I still get the same compile error with SANDBOX_SECCOMP_FILTER_DEBUG after applying that patch. In other news I had a big migration to a 64bit toolchain (gcc 7.5.0 with glibc 2.31) and successfully upgraded to openssh-8.2p1 running the seccomp_filter sandbox some days before. I still have a server with the old 32bit toolchain though in case you want to do further analysis. (In reply to brunni from comment #16) > (In reply to Darren Tucker from comment #15) > > I've applied it without a configure test, we can add one later if > > necessary. Thanks. > > > > brunni: could you please see if this resolves your problem? > > We are talking about this change? > > >+#include <sys/syscall.h> > > No I still get the same compile error with > SANDBOX_SECCOMP_FILTER_DEBUG after applying that patch. Try it without that flag at first, see if it fixes your issue. If it still doesn't fix it, you'll need this flag to debug the seccomp filter (and yes, I had compilation issues with that flag too. I could provide you with how I fixed it on my side if you like). > > In other news I had a big migration to a 64bit toolchain (gcc 7.5.0 > with glibc 2.31) and successfully upgraded to openssh-8.2p1 running > the seccomp_filter sandbox some days before. I still have a server > with the old 32bit toolchain though in case you want to do further > analysis. I think I just found the cause of the issue. It's a configuration issue for 32bit systems. The file config.h contains : #define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 even for 32bit systems. I managed to hack fix it by changing X86_64 to I386 and that seems to make sshd with seccomp work correctly. Darren Tucker: I think you'll have more work than expected with your configure script :). (upon checking configure.ac : I notice that at first sight, I386 should be supported but there's obviously a detection bug lurking there.). brunni: can you confirm the value of the variable SECCOMP_AUDIT_ARCH in your config.h? (In reply to Nicholas Niro from comment #18) > I think I just found the cause of the issue. It's a configuration > issue for 32bit systems. The file config.h contains : #define > SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 even for 32bit systems. I > managed to hack fix it by changing X86_64 to I386 and that seems to > make sshd with seccomp work correctly. > > Darren Tucker: I think you'll have more work than expected with your > configure script :). (upon checking configure.ac : I notice that at > first sight, I386 should be supported but there's obviously a > detection bug lurking there.). > > brunni: can you confirm the value of the variable SECCOMP_AUDIT_ARCH > in your config.h? Actually, upon further investigation on the host I'm testing this on, it seems the host is indeed X86_64 but all the compilation tool set and libraries are 32bit. This ought to confuse any configure script. brunni: I wonder if you are in the same situation too. Darren Tucker: Maybe we could detect the host based on gcc's -dumpmachine output? It would be hackish though and it is a pretty special case. Anyhow, the "correct" way to fix this in the user stand point is by passing something like --host=i686-linux-gnu to the configure script. (In reply to Nicholas Niro from comment #19) > Actually, upon further investigation on the host I'm testing this > on, it seems the host is indeed X86_64 but all the compilation tool > set and libraries are 32bit. This ought to confuse any configure > script. From my experience, 99% of them work out of the box with that setup. > brunni: I wonder if you are in the same situation too. Exactly. 64bit kernel running 32bit binaries and toolchain. On my old machine. The reason for this was that the spectre/meltdown patches for the kernel were 64bit only when they came out. And yes, config.h contains #define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 on my old machine. > Anyhow, the "correct" way to fix this in the user stand point is by > passing something like --host=i686-linux-gnu to the configure script. I'm glad I don't have to worry about such things any more as I finally made the step to 64bit. Retarget bugs to 8.4 release It looks like the only thing remaining from this bug is the SECCOMP_AUDIT_ARCH setting in configure. Can you tell me what configure identifies your host system as? Maybe we can fix this. Look for the line like: checking host system type... x86_64-pc-linux-gnu (In reply to Damien Miller from comment #22) > It looks like the only thing remaining from this bug is the > SECCOMP_AUDIT_ARCH setting in configure. Can you tell me what > configure identifies your host system as? Maybe we can fix this. > Look for the line like: > > checking host system type... x86_64-pc-linux-gnu I still have the old system with the 64bit kernel and the 32bit toolchain. Which version of openSSH should I use? For testing this, any really. OpenSSH 8.3 is ideal since it uses the most recent version of GNU configure. (In reply to Damien Miller from comment #22) > It looks like the only thing remaining from this bug is the > SECCOMP_AUDIT_ARCH setting in configure. Can you tell me what > configure identifies your host system as? Maybe we can fix this. > Look for the line like: > > checking host system type... x86_64-pc-linux-gnu ./configure checking for cc... cc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether cc accepts -g... yes checking for cc option to accept ISO C89... none needed checking build system type... x86_64-pc-linux-gnu checking host system type... x86_64-pc-linux-gnu Created attachment 3427 [details]
Detect X32 when setting seccomp audit_arch
Please try this patch. It should detect X32 and set the audit arch to i386.
(In reply to Damien Miller from comment #26) > Created attachment 3427 [details] > Detect X32 when setting seccomp audit_arch > > Please try this patch. It should detect X32 and set the audit arch > to i386. Nope: checking for seccomp architecture... "AUDIT_ARCH_X86_64" grep SECCOMP_AUDIT_ARCH config.h #define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 I applied the patch and called autoconf and then configure. I also manually checked configure contains the patch. $ac_cv_sizeof_size_t is 4 for me btw - not 32. Sounds about right. So I changed it to:
if test "$ac_cv_sizeof_size_t" = "4" ; then
And that looks better:
grep SECCOMP_AUDIT_ARCH config.h
#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386
OpenSSH also compiles fine then. Did not do any further tests.
corrected fix committed and will be in OpenSSH 8.4 - thanks I’m afraid commit 5b56bd0affea7b02b540bdbc4d1d271b0e4fc885
is completely bogus and must be reverted.
Let me first clarify a few things regarding x86 systems.
We have three architectures that belong to the x86 group of architectures:
- i386 (the original), 32-bit CPU, 32-bit instructions, ILP32 addressing model
#if defined(__i386__)
kernel + userland
GNU: i386-linux-gnu
- amd64 (“x86_64”), 64-bit CPU, 64-bit instructions, LP64 addressing model
#if defined(__x86_64__) && !defined(__ILP32__)
GNU: x86_64-linux-gnu
kernel + userland
- x32 (amd64ilp32), 64-bit CPU, 64-bit instructions, ILP32 addressing model
#if defined(__x86_64__) && defined(__ILP32__)
GNU: x86_64-linux-gnux32
userland only
(I think the BSD equivalent would be MACHINE=x32 MACHINE_ARCH=amd64 for x32.)
Now, the amd64 Linux kernel can run *all three* kinds of machines:
- amd64 ELF64 binaries (native to the amd64 kernel)
- amd64 ELF32 binaries (a.k.a. x32 binaries)
- i386 ELF32 binaries (native to the i386 kernel)
This introduces two new problems:
• “uname -m” prints x86_64 on an amd64 kernel, no matter what
the userland architecture is
⇒ people running “32-bit” applications on a “64-bit” kernel
(such as the initial reporter of this issue) need to run
them under the “linux32” tool, which fixes up uname:
$ uname -m; linux32 uname -m
x86_64
i686
The reporter could also have used --build=i386-linux-gnu
to force configure to end up in the correct switch case,
but using linux32 in these cases is the generally accepted
correct solution (any errors from not doing so are normally
closed as user mistake); I even have (very old) VMs running
with i386 userland and amd64 kernel where I made /sbin/init
into this shell script:
#!/bin/sh
exec /usr/bin/linux32 /sbin/init.real "$@"
• GNU autofools’ config.guess does not detect x32 correctly;
they recently forbade use of $CPP for detection, for some
reason, but asking the selected compiler for those predefined
macros I noted above is the *only* reliable way to do that,
so on x32 users (or generic build system wrappers) need to
*always* pass --build=x86_64-linux-gnux32 to DTRT (Debian
does this)
In short, the reporter did not run x32 but i386 (userland) on
their amd64 kernel. People saying “32 bit” generally (as in,
99.999% safe) mean i386, not x32 (because x32 is so special¹
people say x32 there).
① x32 “breaks up” the conventional 32-bit/64-bit mode of
thinking; this is not unique (there’s an amd64ilp32 out
there which is ARMv8 ILP32 userland, 64-bit instructions)
nor new (MIPS has o32/n32/n64, and n32 is also kind of
a “64-bit” mode but ILP32), but it’s the first, TTBOMK,
to be a userland-only architecture
8.4p1 now mis-detects x32 as i386 for seccomp architecture;
on x32, it must be AUDIT_ARCH_X86_64 like on amd64 (x32 is
handled, in the sandbox, by checking for __ILP32__). This
completely breaks openssh on x32.
My advice is to revert the commit and have the original reporter
use the linux32 wrapper around their i386 system.
In fact, if seccomp_audit_arch is used in C code _only_
I’d even suggest to let the preprocessor determine it,
not autoconf.
5b56bd0a has been reverted close bugs that were resolved in OpenSSH 8.5 release cycle [spam removed] |