From tegge@trondheim.fast.no  Tue Jul 24 10:27:07 2001
Return-Path: <tegge@trondheim.fast.no>
Received: from innenfor.trondheim.fast.no (ext-gw.trd.fast.no [213.188.8.2])
	by hub.freebsd.org (Postfix) with ESMTP id F3C6637B403
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 24 Jul 2001 10:27:06 -0700 (PDT)
	(envelope-from tegge@trondheim.fast.no)
Received: from not.trondheim.fast.no (not.trondheim.fast.no [192.168.8.12])
	by innenfor.trondheim.fast.no (8.9.3/8.9.3) with ESMTP id TAA70589
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 24 Jul 2001 19:27:05 +0200 (CEST)
	(envelope-from tegge@not.trondheim.fast.no)
Received: (from tegge@localhost)
	by not.trondheim.fast.no (8.11.4/8.8.8) id f6OHR5f17119;
	Tue, 24 Jul 2001 19:27:05 +0200 (CEST)
	(envelope-from tegge@not.trondheim.fast.no)
Message-Id: <200107241727.f6OHR5f17119@not.trondheim.fast.no>
Date: Tue, 24 Jul 2001 19:27:05 +0200 (CEST)
From: Tor Egge <tegge@trondheim.fast.no>
Reply-To: Tor Egge <tegge@trondheim.fast.no>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: read from raw device might corrupt nearby data
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         29194
>Category:       kern
>Synopsis:       read from raw device might corrupt nearby data
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    mjacob
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 24 10:30:00 PDT 2001
>Closed-Date:    Tue Oct 2 11:39:08 PDT 2001
>Last-Modified:  Tue Oct 02 11:39:40 PDT 2001
>Originator:     Tor Egge
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
Fast Search & Transfer ASA
>Environment:
System: FreeBSD not.trondheim.fast.no 5.0-CURRENT FreeBSD 5.0-CURRENT #4: Sun Jul 22 18:11:27 CEST 2001 root@not.trondheim.fast.no:/usr/src/sys/i386/compile/NOT_SMP i386



>Description:

When reading from a raw device, the userspace buffer is mapped into kernel
virtal address space.  To ensure that the pages are writable, a byte is read
from each relevant page and written back in vm_fault_quick to force a
copy-on-write if needed.  Unless the userspace buffer is page aligned, the
first writeback is outside the userspace buffer and might cause modification to
that byte by another CPU or DMA to be lost.

>How-To-Repeat:

Perform multiple simultaneous small (2 KB) read operations from raw device to
memory in the same address space where pairs of userspace buffers share a page.

>Fix:

Don't write to 'unrelated' memory to force a copy-on-write.

Use the buffer start address instead of the page start address as the first
argument to vm_fault_quick if the page start address is below the buffer start
address.

Index: sys/alpha/alpha/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/vm_machdep.c,v
retrieving revision 1.56
diff -u -r1.56 vm_machdep.c
--- sys/alpha/alpha/vm_machdep.c	2001/07/14 21:37:57	1.56
+++ sys/alpha/alpha/vm_machdep.c	2001/07/24 16:45:13
@@ -344,7 +344,7 @@
 		 * Do the vm_fault if needed; do the copy-on-write thing
 		 * when reading stuff off device into memory.
 		 */
-		vm_fault_quick(addr,
+		vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
 			(bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
 		pa = trunc_page(pmap_kextract((vm_offset_t) addr));
 		if (pa == 0)
Index: sys/i386/i386/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/vm_machdep.c,v
retrieving revision 1.167
diff -u -r1.167 vm_machdep.c
--- sys/i386/i386/vm_machdep.c	2001/07/12 06:32:50	1.167
+++ sys/i386/i386/vm_machdep.c	2001/07/24 16:45:13
@@ -389,7 +389,7 @@
 		 * Do the vm_fault if needed; do the copy-on-write thing
 		 * when reading stuff off device into memory.
 		 */
-		vm_fault_quick(addr,
+		vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
 			(bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
 		pa = trunc_page(pmap_kextract((vm_offset_t) addr));
 		if (pa == 0)
Index: sys/ia64/ia64/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/ia64/ia64/vm_machdep.c,v
retrieving revision 1.23
diff -u -r1.23 vm_machdep.c
--- sys/ia64/ia64/vm_machdep.c	2001/07/05 01:32:41	1.23
+++ sys/ia64/ia64/vm_machdep.c	2001/07/24 16:45:13
@@ -380,7 +380,7 @@
 		 * Do the vm_fault if needed; do the copy-on-write thing
 		 * when reading stuff off device into memory.
 		 */
-		vm_fault_quick(addr,
+		vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
 			(bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
 		pa = trunc_page(pmap_kextract((vm_offset_t) addr));
 		if (pa == 0)
Index: sys/powerpc/powerpc/vm_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/powerpc/powerpc/vm_machdep.c,v
retrieving revision 1.56
diff -u -r1.56 vm_machdep.c
--- sys/powerpc/powerpc/vm_machdep.c	2001/07/05 01:32:42	1.56
+++ sys/powerpc/powerpc/vm_machdep.c	2001/07/24 16:45:13
@@ -252,7 +252,7 @@
 		 * Do the vm_fault if needed; do the copy-on-write thing
 		 * when reading stuff off device into memory.
 		 */
-		vm_fault_quick(addr,
+		vm_fault_quick((addr >= bp->b_data) ? addr : bp->b_data,
 			(bp->b_iocmd == BIO_READ)?(VM_PROT_READ|VM_PROT_WRITE):VM_PROT_READ);
 		pa = trunc_page(pmap_kextract((vm_offset_t) addr));
 		if (pa == 0)


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->mjacob 
Responsible-Changed-By: mjacob 
Responsible-Changed-When: Mon Oct 1 22:11:58 PDT 2001 
Responsible-Changed-Why:  
Huh- we missed picking up on this and this looks good to me- but I'll 
ask audit@ to check on it. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=29194 
State-Changed-From-To: open->closed 
State-Changed-By: mjacob 
State-Changed-When: Tue Oct 2 11:39:08 PDT 2001 
State-Changed-Why:  
Patch applied to -current and MFC scheduled for 2 weeks, thank you. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=29194 
>Unformatted:
