NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/43443: fwmem devices erroneously do writes instead of reads



>Number:         43443
>Category:       kern
>Synopsis:       fwmem devices erroneously do writes instead of reads
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 09 21:40:01 +0000 2010
>Originator:     Jordan Gordeev
>Release:        NetBSD 5.0.2
>Organization:
>Environment:
>Description:
When you try to read the memory of a remote machine through a fwmem device, a 
write is actually executed.
When reading from or writing to fwmem, physio() gets called with fw_strategy() 
as the strategy routine. fw_strategy() calls fwmem_strategy(). The test in 
fwmem_strategy() that differentiates between read and write always detects 
write.
Of course, doing writes instead of reads can have undesirable consequences like 
kernel memory corruption or machine reboots.

>How-To-Repeat:
fwctl -m <EUI64 of remote machine>
sysctl -w hw.fwmem.fwmem_debug=1
dd if=/dev/fwmem0.0 <other arguments here>
Observe in console output that the write functions fwmem_write_quad() and 
fwmem_write_block() get called, instead of the read functions fwmem_read_quad() 
and fwmem_read_block().

>Fix:
I propose the following patch. It changes the invocations of physio() so that 
they are in line with countless other examples in the NetBSD source tree.

Index: sys/dev/ieee1394/fwdev.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ieee1394/fwdev.c,v
retrieving revision 1.22
diff -u -r1.22 fwdev.c
--- sys/dev/ieee1394/fwdev.c    23 May 2010 18:56:58 -0000      1.22
+++ sys/dev/ieee1394/fwdev.c    9 Jun 2010 21:29:18 -0000
@@ -221,7 +221,7 @@
                return ENXIO;
 
        if (DEV_FWMEM(dev))
-               return physio(fw_strategy, NULL, dev, ioflag, minphys, uio);
+               return physio(fw_strategy, NULL, dev, B_READ, minphys, uio);
 
        d = (struct fw_drv1 *)sc->si_drv1;
        fc = d->fc;
@@ -298,7 +298,7 @@
                return ENXIO;
 
        if (DEV_FWMEM(dev))
-               return physio(fw_strategy, NULL, dev, ioflag, minphys, uio);
+               return physio(fw_strategy, NULL, dev, B_WRITE, minphys, uio);
 
        d = (struct fw_drv1 *)sc->si_drv1;
        fc = d->fc;



Home | Main Index | Thread Index | Old Index