Bugzilla – Bug 997239
p11-kit-trust.so tries to use mmap with write+exec
Last modified: 2016-09-14 09:29:33 UTC
when p11-kit tries to load the p11-kit-trust.so we run into the following code: ``` 1623 mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x3834e70b000 ``` This gets killed by the grsec kernel with: ``` 8097.931220] PAX: From 127.0.0.1: execution attempt in: <anonymous mapping>, 3532a352000-3532a354000 3532a352000 [ 8097.931223] PAX: terminating task: /usr/bin/pdnsutil(pdnsutil):23868, uid/euid: 0/0, PC: 000003532a352010, SP: 000003ab64903928 [ 8097.931224] PAX: bytes at PC: 4c 8d 15 f9 ff ff ff ff 25 03 00 00 00 0f 1f 00 68 b1 25 27 [ 8097.931230] PAX: bytes at SP-8: 000000472c954320 0000035328ba3ef2 0000000000000000 0000000000000000 000000472c954320 000000472c954320 000003ab649039d0 000003ab649039e0 000003ab64903bf0 000003ab64903bd8 0000000000000002 ``` moving /usr/share/p11-kit/modules/p11-kit-trust.module away, "solves" the issue, as the module is no longer loaded. During the discussion with the maintainer of the pkcs#11 part in powerdns, he mentioned that in the future systemd will have a DenyWriteExec option to deny WRITE+EXEC pages there as well. so the grsec kernel will not be the only way to trigger this bug. complete strace is available if needed. kernel-grsec-guest-kvm-4.7.2-2.1 obs://build.opensuse.org/home:dsterba:grsecurity/openSUSE_Tumbleweed/68ce05d9439e32ada1b1151bf6f9b7e8-kernel-grsec-guest-kvm
the only mmap p11-kit implements itself (p11_mmap_open in common/compat.c) uses PROT_READ so the mmap you see is from dlopen, ie glibc.
I run other daemons on the same host that use dlopen just fine. it is only the 2 packages which use that fail to start. so in doubt this is libtasn or so that does something weird.
which use p11-kit....
I see not reason why I should invest time here to debug issues you get with a custom kernel. Feel free to report upstream.
because we might want to set DenyWriteExec in service files with future systemd versions.
https://github.com/systemd/systemd/issues/3319
this could be caused by bind_ffi_closure (gdb) bt #0 __mmap (addr=addr@entry=0x0, len=len@entry=4096, prot=prot@entry=7, flags=flags@entry=34, fd=fd@entry=-1, offset=offset@entry=0) at ../sysdeps/unix/sysv/linux/wordsize-64/mmap.c:33 #1 0x00007ffff71a9a0d in dlmmap (length=length@entry=4096, offset=0, fd=-1, flags=34, prot=3, start=0x0) at ../../../libffi/src/closures.c:536 #2 0x00007ffff71aa4f3 in sys_alloc (m=0x7ffff73af220 <_gm_>, nb=56) at ../../../libffi/src/dlmalloc.c:3515 #3 dlmalloc (bytes=48) at ../../../libffi/src/dlmalloc.c:4245 #4 ffi_closure_alloc (size=size@entry=48, code=code@entry=0x60a158) at ../../../libffi/src/closures.c:616 #5 0x00007ffff7bae870 in bind_ffi_closure (wrapper=wrapper@entry=0x60a150, binding_data=binding_data@entry=0x609f10, binding_func=0x7ffff7bacd80 <binding_C_Initialize>, args=args@entry=0x7ffff7dd3cb0 <function_info+48>, bound_func=0x60a158) at p11-kit/virtual.c:2660 #6 0x00007ffff7baeada in init_wrapper_funcs (wrapper=0x60a150) at p11-kit/virtual.c:2701 #7 p11_virtual_wrap (virt=virt@entry=0x609f10, destroyer=<optimized out>) at p11-kit/virtual.c:2755 #8 0x00007ffff7b92cd1 in prepare_module_inlock_reentrant (mod=0x609520, flags=<optimized out>, module=0x6108d0) at p11-kit/modules.c:1861 #9 0x00007ffff7b93c30 in p11_modules_load_inlock_reentrant (flags=0, results=0x7fffffffd750) at p11-kit/modules.c:1919 #10 0x00007ffff7b93d97 in p11_kit_modules_load (reserved=<optimized out>, flags=0) at p11-kit/modules.c:1991 #11 0x00007ffff7b941ba in p11_kit_modules_load_and_initialize (flags=flags@entry=0) at p11-kit/modules.c:2103 #12 0x0000000000401ebe in print_modules () at p11-kit/lists.c:210 #13 p11_kit_list_modules (argc=1, argv=0x7fffffffe328) at p11-kit/lists.c:289 #14 0x00007ffff73d0711 in __libc_start_main (main=0x401bf0 <main>, argc=2, argv=0x7fffffffe328, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe318) at ../csu/libc-start.c:289 #15 0x0000000000401c29 in _start () at ../sysdeps/x86_64/start.S:118 gdb --args p11-kit list-modules catch syscall mmap condition 1 $rdx==7
some more findings: compile libffi-gcc5 with the following patch: https://gist.github.com/darix/35996fe2be10d40680a359316c045256 makes the tools work even with paxctl -v /usr/bin/p11* /usr/bin/p11-kit: XATTR_PAX : PEMRS /usr/bin/p11tool: XATTR_PAX : PEMRS
libffi -> gcc
I don't see how this is _not_ an issue with GRSEC. If we are allowed to mmap a PROT_WRITE|PROT_EXEC mapping (no error when doing that) but then get killed when actually executing from it then something is broken. Yes, libffi seems to have "dances" around similar issues in SElinux but "misses" the GRsec case. Hmm, in fact it _does_ have it! See the emutramp_enabled_check () in closures.c: /* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */ #ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX #include <stdlib.h> static int emutramp_enabled = -1; static int emutramp_enabled_check (void) { char *buf = NULL; size_t len = 0; FILE *f; int ret; f = fopen ("/proc/self/status", "r"); if (f == NULL) return 0; ret = 0; while (getline (&buf, &len, f) != -1) if (!strncmp (buf, "PaX:", 4)) { char emutramp; if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) ret = (emutramp == 'E'); break; } free (buf); fclose (f); return ret; } #define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ : (emutramp_enabled = emutramp_enabled_check ())) but that needs to be enabled at configure time it seems (--enable-pax_emutramp) Can you check if using a libffi built with that flag works?
This is a fix that makes it work https://github.com/libffi/libffi/pull/282
osc rdiff {,home:darix:branches:}devel:gcc/gcc5