tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: PaX MPROTECT gdb and software breakpoints
On May 22, 3:42pm, rhialto%falu.nl@localhost (Rhialto) wrote:
-- Subject: Re: PaX MPROTECT gdb and software breakpoints
Here's the sysctl way.
christos
Index: kern/kern_pax.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_pax.c,v
retrieving revision 1.49
diff -u -u -r1.49 kern_pax.c
--- kern/kern_pax.c 22 May 2016 14:26:09 -0000 1.49
+++ kern/kern_pax.c 22 May 2016 15:08:55 -0000
@@ -117,6 +117,7 @@
#ifdef PAX_MPROTECT
static int pax_mprotect_enabled = 1;
static int pax_mprotect_global = PAX_MPROTECT;
+static int pax_mprotect_ptrace = 0;
static bool pax_mprotect_elf_flags_active(uint32_t);
#endif /* PAX_MPROTECT */
#ifdef PAX_MPROTECT_DEBUG
@@ -205,6 +206,14 @@
"all processes."),
NULL, 0, &pax_mprotect_global, 0,
CTL_CREATE, CTL_EOL);
+ sysctl_createv(clog, 0, &rnode, NULL,
+ CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+ CTLTYPE_INT, "ptrace",
+ SYSCTL_DESCR("When enabled, allow ptrace(2) to "
+ "override protect permissions on traced "
+ "processes"),
+ NULL, 0, &pax_mprotect_ptrace, 0,
+ CTL_CREATE, CTL_EOL);
#ifdef PAX_MPROTECT_DEBUG
sysctl_createv(clog, 0, &rnode, NULL,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
@@ -432,6 +441,24 @@
*maxprot &= ~VM_PROT_WRITE;
}
}
+
+/*
+ * Bypass MPROTECT for traced processes
+ */
+int
+pax_mprotect_prot(struct lwp *l)
+{
+ uint32_t flags;
+
+ flags = l->l_proc->p_pax;
+ if (!pax_flags_active(flags, P_PAX_MPROTECT))
+ return 0;
+ if (!pax_mprotect_ptrace)
+ return 0;
+ return UVM_EXTRACT_PROT_ALL;
+}
+
+
#endif /* PAX_MPROTECT */
#ifdef PAX_ASLR
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.195
diff -u -u -r1.195 kern_proc.c
--- kern/kern_proc.c 4 Apr 2016 20:47:57 -0000 1.195
+++ kern/kern_proc.c 22 May 2016 15:08:55 -0000
@@ -2114,7 +2114,7 @@
auio.uio_resid = xlen;
auio.uio_rw = UIO_READ;
UIO_SETUP_SYSSPACE(&auio);
- error = uvm_io(&vmspace->vm_map, &auio);
+ error = uvm_io(&vmspace->vm_map, &auio, 0);
if (error)
goto done;
Index: kern/subr_copy.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_copy.c,v
retrieving revision 1.6
diff -u -u -r1.6 subr_copy.c
--- kern/subr_copy.c 21 Apr 2015 13:17:25 -0000 1.6
+++ kern/subr_copy.c 22 May 2016 15:08:55 -0000
@@ -223,7 +223,7 @@
uio.uio_resid = len;
uio.uio_rw = UIO_READ;
UIO_SETUP_SYSSPACE(&uio);
- error = uvm_io(&vm->vm_map, &uio);
+ error = uvm_io(&vm->vm_map, &uio, 0);
return (error);
}
@@ -256,7 +256,7 @@
uio.uio_resid = len;
uio.uio_rw = UIO_WRITE;
UIO_SETUP_SYSSPACE(&uio);
- error = uvm_io(&vm->vm_map, &uio);
+ error = uvm_io(&vm->vm_map, &uio, 0);
return (error);
}
Index: kern/sys_process.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_process.c,v
retrieving revision 1.168
diff -u -u -r1.168 sys_process.c
--- kern/sys_process.c 4 Apr 2016 20:47:57 -0000 1.168
+++ kern/sys_process.c 22 May 2016 15:08:55 -0000
@@ -122,12 +122,14 @@
#include "opt_ptrace.h"
#include "opt_ktrace.h"
+#include "opt_pax.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/errno.h>
#include <sys/exec.h>
+#include <sys/pax.h>
#include <sys/ptrace.h>
#include <sys/uio.h>
#include <sys/ras.h>
@@ -1118,7 +1120,7 @@
mutex_exit(&vm->vm_map.misc_lock);
if (error != 0)
return (error);
- error = uvm_io(&vm->vm_map, uio);
+ error = uvm_io(&vm->vm_map, uio, pax_mprotect_prot(l));
uvmspace_free(vm);
#ifdef PMAP_NEED_PROCWR
Index: sys/pax.h
===================================================================
RCS file: /cvsroot/src/sys/sys/pax.h,v
retrieving revision 1.21
diff -u -u -r1.21 pax.h
--- sys/pax.h 22 May 2016 14:26:10 -0000 1.21
+++ sys/pax.h 22 May 2016 15:08:55 -0000
@@ -67,6 +67,7 @@
struct lwp *, vm_prot_t *, vm_prot_t *);
#ifndef PAX_MPROTECT
# define PAX_MPROTECT_ADJUST(a, b, c)
+# define pax_mprotect_prot(l) 0
#else
# ifdef PAX_MPROTECT_DEBUG
# define PAX_MPROTECT_ADJUST(a, b, c) \
@@ -75,6 +76,7 @@
# define PAX_MPROTECT_ADJUST(a, b, c) \
pax_mprotect_adjust((a), (b), (c))
# endif
+extern int pax_mprotect_prot(struct lwp *);
#endif
int pax_segvguard(struct lwp *, struct vnode *, const char *, bool);
Index: uvm/uvm_extern.h
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.196
diff -u -u -r1.196 uvm_extern.h
--- uvm/uvm_extern.h 5 Feb 2016 04:18:55 -0000 1.196
+++ uvm/uvm_extern.h 22 May 2016 15:08:55 -0000
@@ -622,7 +622,7 @@
void uvm_init(void);
/* uvm_io.c */
-int uvm_io(struct vm_map *, struct uio *);
+int uvm_io(struct vm_map *, struct uio *, int);
/* uvm_km.c */
vaddr_t uvm_km_alloc(struct vm_map *, vsize_t, vsize_t,
Index: uvm/uvm_io.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_io.c,v
retrieving revision 1.27
diff -u -u -r1.27 uvm_io.c
--- uvm/uvm_io.c 27 Jan 2012 19:48:41 -0000 1.27
+++ uvm/uvm_io.c 22 May 2016 15:08:55 -0000
@@ -53,7 +53,7 @@
*/
int
-uvm_io(struct vm_map *map, struct uio *uio)
+uvm_io(struct vm_map *map, struct uio *uio, int flags)
{
vaddr_t baseva, endva, pageoffset, kva;
vsize_t chunksz, togo, sz;
@@ -86,6 +86,7 @@
chunksz = MIN(round_page(togo + pageoffset), trunc_page(MAXPHYS));
error = 0;
+ flags |= UVM_EXTRACT_QREF | UVM_EXTRACT_CONTIG | UVM_EXTRACT_FIXPROT;
/*
* step 1: main loop... while we've got data to move
*/
@@ -97,8 +98,7 @@
*/
error = uvm_map_extract(map, baseva, chunksz, kernel_map, &kva,
- UVM_EXTRACT_QREF | UVM_EXTRACT_CONTIG |
- UVM_EXTRACT_FIXPROT);
+ flags);
if (error) {
/* retry with a smaller chunk... */
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v
retrieving revision 1.336
diff -u -u -r1.336 uvm_map.c
--- uvm/uvm_map.c 5 Nov 2015 00:10:48 -0000 1.336
+++ uvm/uvm_map.c 22 May 2016 15:08:55 -0000
@@ -2546,6 +2546,7 @@
* UVM_EXTRACT_CONTIG: abort if unmapped area (advisory only)
* UVM_EXTRACT_QREF: for a temporary extraction do quick obj refs
* UVM_EXTRACT_FIXPROT: set prot to maxprot as we go
+ * UVM_EXTRACT_PROT_ALL: set prot to UVM_PROT_ALL as we go
* >>>NOTE: if you set REMOVE, you are not allowed to use CONTIG or QREF!<<<
* >>>NOTE: QREF's must be unmapped via the QREF path, thus should only
* be used from within the kernel in a kernel level map <<<
@@ -2704,9 +2705,14 @@
newentry->offset = 0;
}
newentry->etype = entry->etype;
- newentry->protection = (flags & UVM_EXTRACT_FIXPROT) ?
- entry->max_protection : entry->protection;
- newentry->max_protection = entry->max_protection;
+ if (flags & UVM_EXTRACT_PROT_ALL) {
+ newentry->protection = newentry->max_protection =
+ UVM_PROT_ALL;
+ } else {
+ newentry->protection = (flags & UVM_EXTRACT_FIXPROT) ?
+ entry->max_protection : entry->protection;
+ newentry->max_protection = entry->max_protection;
+ }
newentry->inheritance = entry->inheritance;
newentry->wired_count = 0;
newentry->aref.ar_amap = entry->aref.ar_amap;
Index: uvm/uvm_map.h
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_map.h,v
retrieving revision 1.72
diff -u -u -r1.72 uvm_map.h
--- uvm/uvm_map.h 29 Oct 2012 16:00:05 -0000 1.72
+++ uvm/uvm_map.h 22 May 2016 15:08:55 -0000
@@ -108,6 +108,7 @@
#define UVM_EXTRACT_QREF 0x04 /* use quick refs */
#define UVM_EXTRACT_FIXPROT 0x08 /* set prot to maxprot as we go */
#define UVM_EXTRACT_RESERVED 0x10 /* caller did uvm_map_reserve() */
+#define UVM_EXTRACT_PROT_ALL 0x20 /* set prot to UVM_PROT_ALL */
#endif /* _KERNEL */
Home |
Main Index |
Thread Index |
Old Index