contigmalloc & access protection failure
Ray Kinsella
raykinsella78 at gmail.com
Sun May 10 12:53:53 UTC 2009
Hi all,
I am trying to create a kernel panic with a memory access volition,
the memory I am allocating is physically contiguous and is 2 pages in size,
I then try to use vm_map_protect to set the access flags of the 2nd
page to disables writes,
vm_map_protect returns successful but when I write to the page no
access volition occurs, what am I missing?
My attempt in source code to create the volition is below.
Also a question about the FreeBSD memory manager,
I am a bit confused, I read the source code of the vm_map_protect
function and I see it sets the protection on a vm_map_entry_t,
my expectation was protection would be set on vm_page_t, my
understanding was this:-
each vm_map_t contains 1 or more vm_map_entry_t
each vm_map_entry_t contains 1 vm_object_t
each vm_object_t contains 1 or more vm_page_t
so does this mean that because protection is getting set at vm_map_entry,
am I actually protecting more than one page of memory?
Thanks
Ray Kinsella
--------------------------------------------- cut here
---------------------------------------------
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
vm_offset_t palloc_wr;
vm_offset_t palloc_r;
void _alloc(void);
void _free(void);
void _alloc(void)
{
uint32_t retval = 0;
palloc_wr = (vm_offset_t) contigmalloc(2 * PAGE_SIZE,
M_DEVBUF, 0, 0, (1L << 31),
4096, 1024 * 1024);
printf("contigmalloc : 0x%.08x\n", palloc_wr);
palloc_r = palloc_wr + PAGE_SIZE;
//kernel_map
retval = vm_map_protect(&curthread->td_proc->p_vmspace->vm_map
, palloc_r, palloc_r + PAGE_SIZE,
VM_PROT_ALL, 0);
printf("vm_map_protect : %d\n", retval);
memset((void *)palloc_r,0xFF, PAGE_SIZE);
}
void _free(void)
{
contigfree((void *) palloc_wr, 2 * PAGE_SIZE, M_DEVBUF);
}
/* The function called at load/unload. */
static int event_handler(struct module *module, int event, void *arg) {
int e = 0; /* Error, 0 for normal return status */
switch (event) {
case MOD_LOAD:
_alloc();
break;
case MOD_UNLOAD:
_free();
break;
default:
e = EOPNOTSUPP; /* Error, Operation Not Supported */
break;
}
return(e);
}
/* The second argument of DECLARE_MODULE. */
static moduledata_t mod_conf = {
"mod", /* module name */
event_handler, /* event handler */
NULL /* extra data */
};
DECLARE_MODULE(mod, mod_conf, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
More information about the freebsd-hackers
mailing list