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