add support for the linux PROT_GROWS{DOWN,UP} mprotect() flags.

fixes PR 30008.
This commit is contained in:
chs 2005-10-30 16:25:50 +00:00
parent df1287ee8b
commit d17f6e14bc
2 changed files with 41 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc.c,v 1.140 2005/09/10 19:20:50 jmmv Exp $ */
/* $NetBSD: linux_misc.c,v 1.141 2005/10/30 16:25:50 chs Exp $ */
/*-
* Copyright (c) 1995, 1998, 1999 The NetBSD Foundation, Inc.
@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.140 2005/09/10 19:20:50 jmmv Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc.c,v 1.141 2005/10/30 16:25:50 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -674,25 +674,33 @@ linux_sys_mprotect(l, v, retval)
syscallarg(unsigned long) len;
syscallarg(int) prot;
} */ *uap = v;
unsigned long end, start = (unsigned long)SCARG(uap, start), len;
int prot = SCARG(uap, prot);
struct vm_map_entry *entry;
struct vm_map *map = &l->l_proc->p_vmspace->vm_map;
struct vm_map *map;
struct proc *p;
vaddr_t end, start, len, stacklim;
int prot, grows;
start = (vaddr_t)SCARG(uap, start);
len = round_page(SCARG(uap, len));
prot = SCARG(uap, prot);
grows = prot & (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP);
prot &= ~grows;
end = start + len;
if (start & PAGE_MASK)
return EINVAL;
len = round_page(SCARG(uap, len));
end = start + len;
if (end < start)
return EINVAL;
else if (end == start)
if (end == start)
return 0;
if (SCARG(uap, prot) & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
return EINVAL;
if (grows == (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP))
return EINVAL;
p = l->l_proc;
map = &p->p_vmspace->vm_map;
vm_map_lock(map);
#ifdef notdef
VM_MAP_RANGE_CHECK(map, start, end);
@ -701,6 +709,25 @@ linux_sys_mprotect(l, v, retval)
vm_map_unlock(map);
return ENOMEM;
}
/*
* Approximate the behaviour of PROT_GROWS{DOWN,UP}.
*/
stacklim = (vaddr_t)p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur;
if (grows & LINUX_PROT_GROWSDOWN) {
if (USRSTACK - stacklim <= start && start < USRSTACK) {
start = USRSTACK - stacklim;
} else {
start = entry->start;
}
} else if (grows & LINUX_PROT_GROWSUP) {
if (USRSTACK <= end && end < USRSTACK + stacklim) {
end = USRSTACK + stacklim;
} else {
end = entry->end;
}
}
vm_map_unlock(map);
return uvm_map_protect(map, start, end, prot, FALSE);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_mmap.h,v 1.16 2005/05/03 16:26:29 manu Exp $ */
/* $NetBSD: linux_mmap.h,v 1.17 2005/10/30 16:25:50 chs Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -43,6 +43,8 @@
#define LINUX_PROT_READ 0x01
#define LINUX_PROT_WRITE 0x02
#define LINUX_PROT_EXEC 0x04
#define LINUX_PROT_GROWSDOWN 0x01000000
#define LINUX_PROT_GROWSUP 0x02000000
#define LINUX_MAP_SHARED 0x0001
#define LINUX_MAP_PRIVATE 0x0002