Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 09 May 2020 08:57:41 +0200
From:      "Ronald Klop" <ronald-lists@klop.ws>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org, "Toomas Soome" <tsoome@freebsd.org>
Subject:   Re: svn commit: r360836 - head/stand/libsa/zfs
Message-ID:  <op.0kb8afh7kndu52@sjakie>
In-Reply-To: <202005090625.0496PLvc091232@repo.freebsd.org>
References:  <202005090625.0496PLvc091232@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Toomas,

Could this fix this issue  
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=144234 ?

Regards,
Ronald.


On Sat, 09 May 2020 08:25:21 +0200, Toomas Soome <tsoome@freebsd.org>  
wrote:

> Author: tsoome
> Date: Sat May  9 06:25:20 2020
> New Revision: 360836
> URL: https://svnweb.freebsd.org/changeset/base/360836
>
> Log:
>   loader: vdev_read() can corrupt memory
>  When reading less than sector size but from sector boundary,
>   the vdev_read() will read full sector into the provided buffer
>   and therefore corrupting memory past buffer end.
>  MFC after:	2 days
>
> Modified:
>   head/stand/libsa/zfs/zfs.c
>
> Modified: head/stand/libsa/zfs/zfs.c
> ==============================================================================
> --- head/stand/libsa/zfs/zfs.c	Sat May  9 05:04:02 2020	(r360835)
> +++ head/stand/libsa/zfs/zfs.c	Sat May  9 06:25:20 2020	(r360836)
> @@ -418,7 +418,7 @@ vdev_read(vdev_t *vdev, void *priv, off_t offset,  
> void
>  		full_sec_size -= secsz;
> 	/* Return of partial sector data requires a bounce buffer. */
> -	if ((head > 0) || do_tail_read) {
> +	if ((head > 0) || do_tail_read || bytes < secsz) {
>  		bouncebuf = malloc(secsz);
>  		if (bouncebuf == NULL) {
>  			printf("vdev_read: out of memory\n");
> @@ -442,14 +442,28 @@ vdev_read(vdev_t *vdev, void *priv, off_t offset,  
> void
>  		outbuf += min(secsz - head, bytes);
>  	}
> -	/* Full data return from read sectors */
> +	/*
> +	 * Full data return from read sectors.
> +	 * Note, there is still corner case where we read
> +	 * from sector boundary, but less than sector size, e.g. reading 512B
> +	 * from 4k sector.
> +	 */
>  	if (full_sec_size > 0) {
> -		res = read(fd, outbuf, full_sec_size);
> -		if (res != full_sec_size) {
> -			ret = EIO;
> -			goto error;
> +		if (bytes < full_sec_size) {
> +			res = read(fd, bouncebuf, secsz);
> +			if (res != secsz) {
> +				ret = EIO;
> +				goto error;
> +			}
> +			memcpy(outbuf, bouncebuf, bytes);
> +		} else {
> +			res = read(fd, outbuf, full_sec_size);
> +			if (res != full_sec_size) {
> +				ret = EIO;
> +				goto error;
> +			}
> +			outbuf += full_sec_size;
>  		}
> -		outbuf += full_sec_size;
>  	}
> 	/* Partial data return from last sector */
> _______________________________________________
> svn-src-all@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?op.0kb8afh7kndu52>