Memory modified after free in "MAP ENTRY" zone (vm_map_entry_t->read_ahead)
Andriy Gapon
avg at FreeBSD.org
Fri Feb 19 08:40:10 UTC 2016
On 18/02/2016 17:13, Konstantin Belousov wrote:
> So this is arguably a fallout from r188331.
> The following is somewhat non-insistent attempt to fix the problem.
Kostik,
thank you very much, I am testing the patch.
> diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
> index a7e3d37..cddf1eb 100644
> --- a/sys/vm/vm_fault.c
> +++ b/sys/vm/vm_fault.c
> @@ -291,7 +291,8 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
> struct faultstate fs;
> struct vnode *vp;
> vm_page_t m;
> - int ahead, behind, cluster_offset, error, locked;
> + int ahead, behind, cluster_offset, error, locked, rv;
> + u_char behavior;
>
> hardfault = 0;
> growstack = TRUE;
> @@ -550,9 +551,18 @@ readrest:
> * zero-filled pages.
> */
> if (fs.object->type != OBJT_DEFAULT) {
> - int rv;
> - u_char behavior = vm_map_entry_behavior(fs.entry);
> -
> + if (!fs.lookup_still_valid) {
> + locked = vm_map_trylock_read(fs.map);
> + if (locked)
> + fs.lookup_still_valid = TRUE;
> + if (!locked || fs.map->timestamp !=
> + map_generation) {
> + release_page(&fs);
> + unlock_and_deallocate(&fs);
> + goto RetryFault;
> + }
> + }
> + behavior = vm_map_entry_behavior(fs.entry);
> era = fs.entry->read_ahead;
> if (behavior == MAP_ENTRY_BEHAV_RANDOM ||
> P_KILLED(curproc)) {
> @@ -603,6 +613,7 @@ readrest:
> }
> ahead = ulmin(ahead, atop(fs.entry->end - vaddr) - 1);
> if (era != nera)
> + /* XXX only read-lock on map */
> fs.entry->read_ahead = nera;
>
> /*
>
--
Andriy Gapon
More information about the freebsd-current
mailing list