Bug 1888842

Summary: MemoryDenyWriteExecute causes BTI enabled services to abort.
Product: [Fedora] Fedora Reporter: Jeremy Linton <jeremy.linton>
Component: glibcAssignee: Carlos O'Donell <codonell>
Status: CLOSED UPSTREAM QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 33CC: aoliva, ashankar, codonell, dj, fedoraproject, filbranden, flepied, fweimer, law, lnykryn, mfabian, msekleta, pbrobinson, pfrankli, rth, sipoyare, ssahani, s, systemd-maint, yuwatana, zbyszek, z
Target Milestone: ---   
Target Release: ---   
Hardware: aarch64   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-11-10 14:32:21 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 245418    

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.