Page MenuHomeFreeBSD

D36595.diff
No OneTemporary

D36595.diff

diff --git a/share/man/man3/siginfo.3 b/share/man/man3/siginfo.3
--- a/share/man/man3/siginfo.3
+++ b/share/man/man3/siginfo.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 17, 2021
+.Dd September 16, 2022
.Dt SIGINFO 3
.Os
.Sh NAME
@@ -162,6 +162,8 @@
DTrace induced trap
.It Ta Dv TRAP_CAP Ta
capabilities protective trap
+.It Ta Dv TRAP_WXORX Ta
+W^X violation trap
.It Dv SIGCHLD Ta Dv CLD_EXITED Ta
child has exited
.It Ta Dv CLD_KILLED Ta
diff --git a/share/man/man7/security.7 b/share/man/man7/security.7
--- a/share/man/man7/security.7
+++ b/share/man/man7/security.7
@@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 14, 2022
+.Dd September 23, 2022
.Dt SECURITY 7
.Os
.Sh NAME
@@ -938,6 +938,59 @@
.Pa authorized_keys
file to make the key only usable to entities logging in from specific
machines.
+.Sh EXECUTABLE MEMORY PROTECTION
+Some hardware allows you to control which memory regions are allowed to contain
+executable instructions.
+The hardware will block attempts to execute code from memory which is not
+configured to allow executable instructions.
+.Pp
+One security measure you can use to block certain kinds of attacks is to
+ensure that the same memory region is not writable and executable at the same
+time.
+This security measure (sometimes called Write XOR eXecute, or W^X) attempts to
+limit an attacker's ability to overwrite executable code.
+.Fx
+provides configuration controls to enable this protection for user-space code.
+.Pp
+There are two sets of controls.
+One set of controls chooses the user-space processes for which
+.Fx
+should try to enforce the W^X restriction.
+The second set of controls specifies how
+.Fx
+should respond when a user-space program violates the W^X restriction.
+.Pp
+The set of controls which chooses the user-space processes for which
+.Fx
+should try to enforce the W^X restriction includes:
+.Bl -bullet
+.It
+The
+.Va kern.elf32.allow_wx
+and/or
+.Va kern.elf64.allow_wx
+sysctls and/or tunables. (Described below.)
+.It
+The
+.Va wxmap
+mode argument to the
+.Xr proccontrol 1
+command.
+.El
+.Pp
+The set of controls which specifies how
+.Fx
+should respond when a user-space program violates the W^X restriction includes:
+.Bl -bullet
+.It
+The
+.Va vm.enforce_wxorx
+sysctl/tunable. (Described below.)
+.It
+The
+.Va vm.log_wxorx
+sysctl/tunable. (Described below.)
+.El
.Sh KNOBS AND TWEAKS
.Fx
provides several knobs and tweak handles that make some introspection
@@ -1082,9 +1135,48 @@
.It Dv kern.elf32.allow_wx
Enables mapping of simultaneously writable and executable pages for
32-bit processes.
+In general, it is considered less secure to allow executable pages to
+be simultaneously writable.
+Not all systems are capable of enforcing execution permissions.
.It Dv kern.elf64.allow_wx
Enables mapping of simultaneously writable and executable pages for
64-bit processes.
+In general, it is considered less secure to allow executable pages to
+be simultaneously writable.
+Not all systems are capable of enforcing execution permissions.
+.It Dv vm.enforce_wxorx
+Controls how the system enforces protections against simultaneously writable
+and executable pages for user processes where such enforcement has been
+requested (for example, through the
+.Va kern.elf32.allow_wx
+or
+.Va kern.elf64.allow_wx
+sysctls and/or tunables).
+.Pp
+Recognized values are:
+.Bl -tag -width flag
+.It Ic 0
+Do not enforce W^X permissions.
+This is the default initial value.
+.It Ic 1
+Block page mappings which are simultaneously writable and executable.
+.It Ic 2
+Block page mappings which are simultaneously writable and executable and send a
+.Dv SIGTRAP
+signal with code
+.Dv TRAP_WXORX
+to any process which attempts to create such a mapping.
+This may be useful for debugging code paths which request these memory
+mappings.
+.El
+.Pp
+Not all systems are capable of enforcing execution permissions.
+.It Dv vm.log_wxorx
+Controls whether the system logs attempts to map memory pages which are
+simultaneously writable and executable for user processes where such
+enforcement has been requested.
+This can be enabled separately from enforcement to allow a system to log
+requests which would have been denied if enforcement was enabled.
.El
.Sh SEE ALSO
.Xr chflags 1 ,
diff --git a/sys/compat/linux/linux_signal.c b/sys/compat/linux/linux_signal.c
--- a/sys/compat/linux/linux_signal.c
+++ b/sys/compat/linux/linux_signal.c
@@ -647,6 +647,7 @@
case TRAP_DTRACE:
return (LINUX_TRAP_TRACE);
case TRAP_CAP:
+ case TRAP_WXORX:
return (LINUX_TRAP_UNK);
default:
return (si_code);
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -744,6 +744,13 @@
/* Loadable segment */
prot = __elfN(trans_prot)(phdr[i].p_flags);
+ if ((imgp->map_flags & MAP_WXORX) == MAP_WXORX &&
+ (prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) ==
+ (VM_PROT_WRITE | VM_PROT_EXECUTE)) {
+ uprintf("Refusing to run ELF binary with WX memory"
+ " mapping when WX mappings disallowed\n");
+ return (ENOEXEC);
+ }
error = __elfN(load_section)(imgp, phdr[i].p_offset,
(caddr_t)(uintptr_t)phdr[i].p_vaddr + rbase,
phdr[i].p_memsz, phdr[i].p_filesz, prot);
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -346,6 +346,7 @@
#define TRAP_TRACE 2 /* Process trace trap. */
#define TRAP_DTRACE 3 /* DTrace induced trap. */
#define TRAP_CAP 4 /* Capabilities protective trap. */
+#define TRAP_WXORX 5 /* W^X violation trap. */
/* codes for SIGCHLD */
#define CLD_EXITED 1 /* Child has exited */
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -82,7 +82,9 @@
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
#include <sys/file.h>
+#include <sys/signalvar.h>
#include <sys/sysctl.h>
+#include <sys/syslog.h>
#include <sys/sysent.h>
#include <sys/shm.h>
@@ -1600,6 +1602,62 @@
return (FALSE);
}
+static int enforce_wxorx = 1;
+SYSCTL_INT(_vm, OID_AUTO, enforce_wxorx, CTLFLAG_RWTUN, &enforce_wxorx, 0,
+ "Enforce W^X: 0 = no, 1 = deny mapping, 2 = deny mapping and send trap "
+ "to process");
+
+static bool log_wxorx = false;
+SYSCTL_BOOL(_vm, OID_AUTO, log_wxorx, CTLFLAG_RWTUN, &log_wxorx, 0,
+ "Log W^X violations");
+
+/*
+ * handle_wxorx_exception:
+ *
+ * Handle W^X errors according to the sysctl setting.
+ *
+ * If the calling function should block the mapping, return true.
+ * Otherwise, return false.
+ */
+static bool
+handle_wxorx_exception(void)
+{
+ ksiginfo_t ksi;
+ const char *action = NULL;
+ struct thread *td;
+ bool rv;
+
+ switch (enforce_wxorx) {
+ case 2:
+ td = curthread;
+ if ((td->td_proc->p_flag & P_SYSTEM) == 0 &&
+ td->td_proc->p_state != PRS_NEW &&
+ (td->td_pflags & TDP_KTHREAD) == 0) {
+ ksiginfo_init_trap(&ksi);
+ ksi.ksi_signo = SIGTRAP;
+ ksi.ksi_code = TRAP_WXORX;
+ ksi.ksi_errno = EINVAL;
+ trapsignal(td, &ksi);
+ action = "sent trap to process";
+ }
+ /* FALLTHROUGH */
+ default:
+ case 1:
+ rv = true;
+ if (action == NULL)
+ action = "blocked";
+ break;
+ case 0:
+ rv = false;
+ action = "allowed";
+ break;
+ }
+ if (log_wxorx)
+ log(LOG_WARNING, "Detected WX mapping from pid %u (%s): %s\n",
+ curproc->p_pid, curproc->p_comm, action);
+ return (rv);
+}
+
/*
* vm_map_insert:
*
@@ -1641,7 +1699,8 @@
return (KERN_INVALID_ADDRESS);
if ((map->flags & MAP_WXORX) != 0 && (prot & (VM_PROT_WRITE |
- VM_PROT_EXECUTE)) == (VM_PROT_WRITE | VM_PROT_EXECUTE))
+ VM_PROT_EXECUTE)) == (VM_PROT_WRITE | VM_PROT_EXECUTE) &&
+ handle_wxorx_exception())
return (KERN_PROTECTION_FAILURE);
/*
@@ -2728,7 +2787,7 @@
if ((map->flags & MAP_WXORX) != 0 &&
(flags & VM_MAP_PROTECT_SET_PROT) != 0 &&
(new_prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE |
- VM_PROT_EXECUTE)) {
+ VM_PROT_EXECUTE) && handle_wxorx_exception()) {
vm_map_unlock(map);
return (KERN_PROTECTION_FAILURE);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 4, 4:35 PM (11 h, 55 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29250111
Default Alt Text
D36595.diff (7 KB)

Event Timeline