<listitem><para>Takes a boolean argument. If set, attempts to create memory mappings that are writable and
executable at the same time, or to change existing memory mappings to become executable, or mapping shared
- memory segments as executable, are prohibited. Specifically, a system call filter is added that rejects
- <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls with both
- <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
+ memory segments as executable, are prohibited. Specifically, a system call filter is added (or
+ preferably, an equivalent kernel check is enabled with
+ <citerefentry><refentrytitle>prctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>) that
+ rejects <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+ system calls with both <constant>PROT_EXEC</constant> and <constant>PROT_WRITE</constant> set,
<citerefentry><refentrytitle>mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> or
<citerefentry><refentrytitle>pkey_mprotect</refentrytitle><manvolnum>2</manvolnum></citerefentry> system calls
with <constant>PROT_EXEC</constant> set and
#define PR_CAP_AMBIENT_LOWER 3
#define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif
+
+/* b507808ebce23561d4ff8c2aa1fb949fe402bc61 (6.3) */
+#ifndef PR_SET_MDWE
+#define PR_SET_MDWE 65
+#endif
+#ifndef PR_MDWE_REFUSE_EXEC_GAIN
+#define PR_MDWE_REFUSE_EXEC_GAIN 1
+#endif
#include "memory-util.h"
#include "missing_fs.h"
#include "missing_ioprio.h"
+#include "missing_prctl.h"
#include "mkdir-label.h"
#include "mount-util.h"
#include "mountpoint-util.h"
}
static int apply_memory_deny_write_execute(const Unit* u, const ExecContext *c) {
+ int r;
+
assert(u);
assert(c);
if (!c->memory_deny_write_execute)
return 0;
+ /* use prctl() if kernel supports it (6.3) */
+ r = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0, 0, 0);
+ if (r == 0) {
+ log_unit_debug(u, "Enabled MemoryDenyWriteExecute= with PR_SET_MDWE");
+ return 0;
+ }
+ if (r < 0 && errno != EINVAL)
+ return log_unit_debug_errno(u, errno, "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m");
+ /* else use seccomp */
+ log_unit_debug(u, "Kernel doesn't support PR_SET_MDWE: falling back to seccomp");
+
if (skip_seccomp_unavailable(u, "MemoryDenyWriteExecute="))
return 0;