Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Dec 2020 21:14:46 GMT
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 26b23f07fb98 - main - sendfile: Ensure that sfio->npages is initialized
Message-ID:  <202012262114.0BQLEkgf027510@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=26b23f07fb981662debd69b9969f78864c262466

commit 26b23f07fb981662debd69b9969f78864c262466
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2020-12-26 21:07:40 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2020-12-26 21:07:40 +0000

    sendfile: Ensure that sfio->npages is initialized
    
    We initialize sfio->npages only when some I/O is required to satisfy the
    request.  However, sendfile_iodone() contains an INVARIANTS-only check
    that references sfio->npages, and this check is executed even if no I/O
    is performed, so the check may use an uninitialized value.
    
    Fix the problem by initializing sfio->npages earlier.  Note that
    sendfile_swapin() always initializes the page array.  In some rare cases
    we need to trim the page array so ensure that sfio->npages gets updated
    accordingly.
    
    Reported by:            syzkaller (with KASAN)
    Reviewed by:            kib
    Sponsored by:           The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D27726
---
 sys/kern/kern_sendfile.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
index e0b9b0e261d4..18c9ade721a9 100644
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -413,12 +413,13 @@ out_with_ref:
  */
 static int
 sendfile_swapin(vm_object_t obj, struct sf_io *sfio, int *nios, off_t off,
-    off_t len, int npages, int rhpages, int flags)
+    off_t len, int rhpages, int flags)
 {
 	vm_page_t *pa;
-	int a, count, count1, grabbed, i, j, rv;
+	int a, count, count1, grabbed, i, j, npages, rv;
 
 	pa = sfio->pa;
+	npages = sfio->npages;
 	*nios = 0;
 	flags = (flags & SF_NODISKIO) ? VM_ALLOC_NOWAIT : 0;
 	sfio->pindex0 = OFF_TO_IDX(off);
@@ -905,6 +906,7 @@ retry_space:
 		sfio->obj = obj;
 		sfio->error = 0;
 		sfio->m = NULL;
+		sfio->npages = npages;
 #ifdef KERN_TLS
 		/*
 		 * This doesn't use ktls_hold() because sfio->m will
@@ -914,8 +916,8 @@ retry_space:
 		sfio->tls = tls;
 #endif
 		vm_object_pip_add(obj, 1);
-		error = sendfile_swapin(obj, sfio, &nios, off, space, npages,
-		    rhpages, flags);
+		error = sendfile_swapin(obj, sfio, &nios, off, space, rhpages,
+		    flags);
 		if (error != 0) {
 			if (vp != NULL)
 				VOP_UNLOCK(vp);
@@ -963,7 +965,7 @@ retry_space:
 			if (pa[i] == NULL) {
 				SFSTAT_INC(sf_busy);
 				fixspace(npages, i, off, &space);
-				npages = i;
+				sfio->npages = i;
 				softerr = EBUSY;
 				break;
 			}
@@ -1042,12 +1044,14 @@ retry_space:
 			if (sf == NULL) {
 				SFSTAT_INC(sf_allocfail);
 				sendfile_iowait(sfio, "sfnosf");
-				for (int j = i; j < npages; j++)
+				for (int j = i; j < npages; j++) {
 					vm_page_unwire(pa[j], PQ_INACTIVE);
+					pa[j] = NULL;
+				}
 				if (m == NULL)
 					softerr = ENOBUFS;
 				fixspace(npages, i, off, &space);
-				npages = i;
+				sfio->npages = i;
 				break;
 			}
 
@@ -1152,7 +1156,6 @@ prepend_header:
 		} else {
 			sfio->so = so;
 			sfio->m = m0;
-			sfio->npages = npages;
 			soref(so);
 			error = (*so->so_proto->pr_usrreqs->pru_send)
 			    (so, PRUS_NOTREADY, m, NULL, NULL, td);



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