Hi,
I've been playing with memguard(9) and so far it works well until it
starts to run out of memory. For those who don't know, memguard is a
replacement debugging malloc for the kernel, which is designed to
catch use after free errors. It achieves this by setting any free'd
pages to read-only, therefore any writes to the page should generate a
page fault, and a backtrace allowing you to figure out where your code
is using freed memory. To stop memguard using all your system's RAM
and setting every page to read-only, it begins to recycle previously
freed pages. To do this it must first make the page read-write, and
then return it from malloc.

The problem I am facing is when memguard, unguards a page (ie changes
the page to read-write) it does not actually do this, and the page
remains read-only. I have tracked the problem down but I don't know
how to fix it.

memguard_guard calls vm_map_protect with a read-only flag.
vm_map_protect updates the vm_map_entry, and then calls pmap_protect
to set the actual pte.
pmap_protect successfully sets the pte to read-only and everything
works as it should.

However, memguard_unguard doesn't work correctly. It first calls
vm_map_protect with a read-write flag.
vm_map_protect correctly updates the vm_map_entry, and then calls
pmap_protect to set the actual pte.
pmap_protect is lazy and notices that we are reducing the protection
on the page and therefore does nothing. It assumes that later that a
page fault will occur, call vm_fault, and then fix up the pte then.

The problem I seem to be having is that vm_fault is not called,
because when the page fault occurs, calltrap then trap gets called,
but it falls into trap_fatal because a non-sleepable lock is held.

So my question is, can I call a function which sets the pte in a
non-lazy way? I considered rewriting pmap_protect to do this, but I
thought it be best to do it another way. Another idea I had was to
call vm_fault myself straight after vm_map_protect, but I was unsure
if that was allowed. Also, some googling found the function
pmap_page_protect claims to do what I want, but has long been missing
from FreeBSD.

In case it matters, I'm using FreeBSD 7.2, on a amd64 machine. I've
looked at HEAD and the relevant code looks the same, so I suspect I
will still have problems with that.

thanks for any help
Andrew
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to