Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Feb 2016 10:38:46 +0200
From:      Andriy Gapon <avg@FreeBSD.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        alc@FreeBSD.org, FreeBSD Current <freebsd-current@FreeBSD.org>
Subject:   Re: Memory modified after free in "MAP ENTRY" zone (vm_map_entry_t->read_ahead)
Message-ID:  <56C6D496.1060509@FreeBSD.org>
In-Reply-To: <20160218151321.GR91220@kib.kiev.ua>
References:  <56BBAB6E.5050601@FreeBSD.org> <56C08AAA.5050206@FreeBSD.org> <CAJUyCcNy19rArmgjzpPZvsDE7Ln4OoMWU%2B75Q%2BTHdp0T7%2BDxPg@mail.gmail.com> <56C1953F.60604@FreeBSD.org> <20160218151321.GR91220@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?56C6D496.1060509>