Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Oct 2020 17:05:22 +0000 (UTC)
From:      Brooks Davis <brooks@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r366731 - head/sys/kern
Message-ID:  <202010151705.09FH5MW7085084@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: brooks
Date: Thu Oct 15 17:05:21 2020
New Revision: 366731
URL: https://svnweb.freebsd.org/changeset/base/366731

Log:
  physio: Don't store user addresses in bio_data
  
  Only assign the address from the iovec to bio_data if it is a kernel
  address.  This was the single place where bio_data stored (however
  briefly) a userspace pointer.
  
  Reviewed by:	imp, markj
  Obtained from:	CheriBSD
  MFC after:	1 week
  Sponsored by:	DARPA
  Differential Revision:	https://reviews.freebsd.org/D26783

Modified:
  head/sys/kern/kern_physio.c

Modified: head/sys/kern/kern_physio.c
==============================================================================
--- head/sys/kern/kern_physio.c	Thu Oct 15 15:36:08 2020	(r366730)
+++ head/sys/kern/kern_physio.c	Thu Oct 15 17:05:21 2020	(r366731)
@@ -45,7 +45,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
 	struct buf *pbuf;
 	struct bio *bp;
 	struct vm_page **pages;
-	caddr_t sa;
+	char *base, *sa;
 	u_int iolen, poff;
 	int error, i, npages, maxpages;
 	vm_prot_t prot;
@@ -140,7 +140,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
 				curthread->td_ru.ru_oublock++;
 			}
 			bp->bio_offset = uio->uio_offset;
-			bp->bio_data = uio->uio_iov[i].iov_base;
+			base = uio->uio_iov[i].iov_base;
 			bp->bio_length = uio->uio_iov[i].iov_len;
 			if (bp->bio_length > dev->si_iosize_max)
 				bp->bio_length = dev->si_iosize_max;
@@ -153,13 +153,13 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
 			 * larger than MAXPHYS - PAGE_SIZE must be
 			 * page aligned or it will be fragmented.
 			 */
-			poff = (vm_offset_t)bp->bio_data & PAGE_MASK;
+			poff = (vm_offset_t)base & PAGE_MASK;
 			if (pbuf && bp->bio_length + poff > pbuf->b_kvasize) {
 				if (dev->si_flags & SI_NOSPLIT) {
 					uprintf("%s: request ptr %p is not "
 					    "on a page boundary; cannot split "
 					    "request\n", devtoname(dev),
-					    bp->bio_data);
+					    base);
 					error = EFBIG;
 					goto doerror;
 				}
@@ -174,7 +174,7 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
 			if (pages) {
 				if ((npages = vm_fault_quick_hold_pages(
 				    &curproc->p_vmspace->vm_map,
-				    (vm_offset_t)bp->bio_data, bp->bio_length,
+				    (vm_offset_t)base, bp->bio_length,
 				    prot, pages, maxpages)) < 0) {
 					error = EFAULT;
 					goto doerror;
@@ -190,7 +190,8 @@ physio(struct cdev *dev, struct uio *uio, int ioflag)
 					bp->bio_data = unmapped_buf;
 					bp->bio_flags |= BIO_UNMAPPED;
 				}
-			}
+			} else
+				bp->bio_data = base;
 
 			csw->d_strategy(bp);
 			if (uio->uio_rw == UIO_READ)



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