Subject: Re: PaX MPROTECT (Re: CVS commit: src)
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 05/17/2006 00:43:42
This is a multi-part message in MIME format.
--------------000803010308000209060707
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
YAMAMOTO Takashi wrote:
> - pax_mprotect_adjust seems no-op.
> - "*new_prot &= ~VM_PROT_EXECUTE;" in obj != NULL case of pax_mprotect
> is no-op because the condition isn't met if VM_PROT_EXECUTE is set.
> - mprotect(2) is not only user of uvm_map_protect.
> have you checked the rest of users?
> - uobj == NULL is not a good test for anonymous memory,
> if you want to count eg. sysv shared memory or COW'ed memory as anonymous.
> (i'm not sure why you want to check if anonymous or not here.)
> - the semantics of uvm_map_protect after your change is not clear to me.
> eg. consider doing mprotect(100, 100, WRITE|EXEC) and
> [100..150] is file-backed and [150..200] is anonymous memory.
> if i read your change correctly, both of WRITE and EXEC bits will be
> removed for the entire range. is it an intended behaviour?
> - i couldn't find any code to restrict mmap. does this make sense without it?
See if attached diff solves some of the above?
> have you had any public review of the patch?
Of an earlier version.. the screw-ups are all mine. :)
-e.
--
Elad Efrat
--------------000803010308000209060707
Content-Type: text/plain;
name="pax_mprotect.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="pax_mprotect.diff"
Index: sys/pax.h
===================================================================
RCS file: /cvsroot/src/sys/sys/pax.h,v
retrieving revision 1.1
diff -u -p -r1.1 pax.h
--- sys/pax.h 16 May 2006 00:08:25 -0000 1.1
+++ sys/pax.h 16 May 2006 21:42:53 -0000
@@ -33,7 +33,7 @@
#ifndef __SYS_PAX_H__
#define __SYS_PAX_H__
-void pax_mprotect(struct lwp *, struct uvm_object *, vm_prot_t *);
+void pax_mprotect(struct lwp *, void *, vm_prot_t *, vm_prot_t *);
void pax_mprotect_adjust(struct lwp *, int);
#endif /* !__SYS_PAX_H__ */
Index: kern/kern_pax.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_pax.c,v
retrieving revision 1.1
diff -u -p -r1.1 kern_pax.c
--- kern/kern_pax.c 16 May 2006 00:08:25 -0000 1.1
+++ kern/kern_pax.c 16 May 2006 21:42:53 -0000
@@ -84,8 +84,7 @@ SYSCTL_SETUP(sysctl_security_pax_setup,
void
pax_mprotect_adjust(struct lwp *l, int f)
{
- if (!pax_mprotect_enabled ||
- (f & (PF_PAXMPROTECT|PF_PAXNOMPROTECT)))
+ if (!pax_mprotect_enabled)
return;
if (f & PF_PAXMPROTECT)
@@ -95,22 +94,18 @@ pax_mprotect_adjust(struct lwp *l, int f
}
void
-pax_mprotect(struct lwp *l, struct uvm_object *obj, vm_prot_t *new_prot)
+pax_mprotect(struct lwp *l, void *handle, vm_prot_t *prot, vm_prot_t *maxprot)
{
if (!pax_mprotect_enabled ||
(pax_mprotect_global && (l->l_proc->p_flag & P_PAXNOMPROTECT)) ||
(!pax_mprotect_global && !(l->l_proc->p_flag & P_PAXMPROTECT)))
return;
- if (obj == NULL) {
- /* Anonymous mappings always get their execute bit stripped. */
- *new_prot &= ~VM_PROT_EXECUTE;
+ if ((*prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) != VM_PROT_EXECUTE) {
+ *prot &= ~VM_PROT_EXECUTE;
+ *maxprot &= ~VM_PROT_EXECUTE;
} else {
- /* File mappings. */
- if ((*new_prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) ==
- VM_PROT_WRITE)
- *new_prot &= ~VM_PROT_EXECUTE;
- else
- *new_prot &= ~VM_PROT_WRITE;
+ *prot &= ~VM_PROT_WRITE;
+ *maxprot &= ~VM_PROT_WRITE;
}
}
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_map.c,v
retrieving revision 1.224
diff -u -p -r1.224 uvm_map.c
--- uvm/uvm_map.c 16 May 2006 00:08:25 -0000 1.224
+++ uvm/uvm_map.c 16 May 2006 21:42:59 -0000
@@ -77,7 +77,6 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v
#include "opt_uvmhist.h"
#include "opt_uvm.h"
#include "opt_sysv.h"
-#include "opt_pax.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -101,10 +100,6 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v
#include <uvm/uvm_ddb.h>
#endif
-#ifdef PAX_MPROTECT
-#include <sys/pax.h>
-#endif /* PAX_MPROTECT */
-
#if defined(UVMMAP_NOCOUNTERS)
#define UVMMAP_EVCNT_DEFINE(name) /* nothing */
@@ -2834,10 +2829,6 @@ uvm_map_protect(struct vm_map *map, vadd
}
}
-#ifdef PAX_MPROTECT
- pax_mprotect(curlwp, current->object.uvm_obj, &new_prot);
-#endif /* PAX_MPROTECT */
-
current = current->next;
}
Index: uvm/uvm_mmap.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_mmap.c,v
retrieving revision 1.96
diff -u -p -r1.96 uvm_mmap.c
--- uvm/uvm_mmap.c 14 May 2006 21:38:17 -0000 1.96
+++ uvm/uvm_mmap.c 16 May 2006 21:43:00 -0000
@@ -54,6 +54,7 @@
__KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v 1.96 2006/05/14 21:38:17 elad Exp $");
#include "opt_compat_netbsd.h"
+#include "opt_pax.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,6 +68,10 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_mmap.c,v
#include <sys/vnode.h>
#include <sys/conf.h>
#include <sys/stat.h>
+
+#ifdef PAX_MPROTECT
+#include <sys/pax.h>
+#endif /* PAX_MPROTECT */
#include <miscfs/specfs/specdev.h>
@@ -500,6 +505,10 @@ sys_mmap(l, v, retval)
}
}
+#ifdef PAX_MPROTECT
+ pax_mprotect(l, handle, &prot, &maxprot);
+#endif /* PAX_MPROTECT */
+
/*
* now let kernel internal function uvm_mmap do the work.
*/
--------------000803010308000209060707--