svn commit: r360836 - head/stand/libsa/zfs

Ronald Klop ronald-lists at klop.ws
Sat May 9 06:57:48 UTC 2020


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 at 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 at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/svn-src-all
> To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"


More information about the svn-src-head mailing list