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>