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