Bug 1888842 - MemoryDenyWriteExecute causes BTI enabled services to abort.
Summary: MemoryDenyWriteExecute causes BTI enabled services to abort.
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 33
Hardware: aarch64
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Carlos O'Donell
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: ARMTracker
TreeView+ depends on / blocked
 
Reported: 2020-10-15 22:14 UTC by Jeremy Linton
Modified: 2020-11-10 14:33 UTC (History)
22 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2020-11-10 14:32:21 UTC
Type: Bug


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Sourceware 26831 0 P2 NEW aarch64: seccomp filters may prevent mprotect(PROT_EXEC|PROT_BTI) 2021-01-14 17:55:30 UTC

Description Jeremy Linton 2020-10-15 22:14:47 UTC
Description of problem: F33/aarch64 has BTI enabled for arm v8.5+ machines. glibc enables BTI validation on executable segments by calling mprotect with PROT_EXEC|PROC_BTI on executable marked as supporting BTI. 

Of course this is trapped by the secomp filter in systemd which is enabled on services with MemoryDenyWriteExecute.

So 50/50, this is a glibc+systemd interaction.

Version-Release number of selected component (if applicable): f33


How reproducible: 100 when running on an emulator that support BTI.

The code in question in systemd is seccomp-util.c 

r = add_seccomp_syscall_filter(seccomp, arch, SCMP_SYS(mprotect),
		       1,SCMP_A2(SCMP_CMP_MASKED_EQ, PROT_EXEC, PROT_EXEC));


and in glibc i'm carrying a patch like:

diff --git a/sysdeps/aarch64/dl-bti.c b/sysdeps/aarch64/dl-bti.c
index 196e462520..d580ac581c 100644
--- a/sysdeps/aarch64/dl-bti.c
+++ b/sysdeps/aarch64/dl-bti.c
@@ -40,12 +40,8 @@ enable_bti (struct link_map *map, const char *program)

        if (__mprotect (start, len, prot) < 0)
          {
-           if (program)
-             _dl_fatal_printf ("%s: mprotect failed to turn on BTI\n",
-                               map->l_name);
-           else
-             _dl_signal_error (errno, map->l_name, "dlopen",
-                               N_("mprotect failed to turn on BTI"));
+             _dl_printf ("%s: mprotect failed to turn on BTI %d\n",
+                         map->l_name, errno);
          }
       }
   return 0;



That patch keeps BTI enable failures from killing the application. So its a bit of a question of whether BTI or secomp provide more security here. But this patch leaves both enabled except when secomp filters mprotect, in which case BTI is being disabled.

Comment 1 Zbigniew Jędrzejewski-Szmek 2020-10-16 13:20:45 UTC
Yeah, that's unfortunate. I don't see any easy way out though:
- if we allow PROT_EXEC|PROC_BTI to pass through, the protection provided by MemoryDenyWriteExecute is gone.
- we could ignore MemoryDenyWriteExecute on aarch64 or maybe only on hardware that supports BTI, but that still drops that protection on those systems
- we could try to figure out if the mapping is already executable and allow PROT_EXEC|PROC_BTI in those cases. That would not be at all trivial, not easily done with seccomp.

Ideally we would have a way to enable both. Are the start+len somehow predictable? Or maybe we could allow one and just one call with PROT_EXEC|PROT_BTI?

Could you please open an issue upstream under https://github.com/systemd/systemd/issues?

Comment 2 Jeremy Linton 2020-10-16 16:05:45 UTC
https://github.com/systemd/systemd/issues/17368

Comment 4 Jeremy Linton 2020-10-29 18:55:32 UTC
I've opened a pull request, to carry the above patch until the glibc/kernel patches land. This will resolve boot failures in BTI environments.

Comment 5 Jeremy Linton 2020-10-29 18:56:07 UTC
Whops forgot the link: https://src.fedoraproject.org/rpms/glibc/pull-request/20

Comment 6 Jeremy Linton 2020-11-03 15:24:12 UTC
glibc posting here https://www.spinics.net/lists/arm-kernel/msg851408.html

Comment 7 Jeremy Linton 2020-11-03 15:52:02 UTC
I'm going to change the component too since this is mostly going to be a glibc/kernel fix.

https://sourceware.org/bugzilla/show_bug.cgi?id=26831

Comment 8 Carlos O'Donell 2020-11-10 14:32:21 UTC
This bug is going to be fixed in upstream glibc and we'll inherit the fix into Fedora Rawhide and any subsequent stable branch backports.

https://sourceware.org/pipermail/libc-alpha/2020-November/119305.html

Having this fixed upstream will fix all downstream distributions.

If you need anything further we should discuss this upstream.

Comment 9 Carlos O'Donell 2020-11-10 14:33:17 UTC
When this gets backported to release/2.32/master in upstream glibc we can then sync this to Fedora 33 for a fix in the distribution. You can file a bug for that if you want once the commits are there.


Note You need to log in before you can comment on or make changes to this bug.