Re: Memory modified after free in "MAP ENTRY" zone (vm_map_entry_t->read_ahead)

From: Andriy Gapon <avg_at_FreeBSD.org>
Date: Fri, 19 Feb 2016 10:38:46 +0200
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
> _at__at_ -291,7 +291,8 _at__at_ 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;
> _at__at_ -550,9 +551,18 _at__at_ 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)) {
> _at__at_ -603,6 +613,7 _at__at_ 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
Received on Fri Feb 19 2016 - 07:40:10 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:02 UTC