Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Jul 2001 19:27:05 +0200 (CEST)
From:      Tor Egge <tegge@trondheim.fast.no>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/29194: read from raw device might corrupt nearby data
Message-ID:  <200107241727.f6OHR5f17119@not.trondheim.fast.no>

next in thread | raw e-mail | index | archive | help

>Number:         29194
>Category:       kern
>Synopsis:       read from raw device might corrupt nearby data
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 24 10:30:00 PDT 2001
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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