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