svn commit: r360891 - stable/11/stand/libsa/zfs
Toomas Soome
tsoome at FreeBSD.org
Mon May 11 07:01:10 UTC 2020
Author: tsoome
Date: Mon May 11 07:01:10 2020
New Revision: 360891
URL: https://svnweb.freebsd.org/changeset/base/360891
Log:
MFC r360836:
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.
Modified:
stable/11/stand/libsa/zfs/zfs.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/stand/libsa/zfs/zfs.c
==============================================================================
--- stable/11/stand/libsa/zfs/zfs.c Mon May 11 06:59:01 2020 (r360890)
+++ stable/11/stand/libsa/zfs/zfs.c Mon May 11 07:01:10 2020 (r360891)
@@ -417,7 +417,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 = zfs_alloc(secsz);
if (bouncebuf == NULL) {
printf("vdev_read: out of memory\n");
@@ -441,14 +441,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 */
More information about the svn-src-stable
mailing list