]> Zhao Yanbai Git Server - minix.git/commitdiff
Security check on physical address to be < 16 MB (ISA DMA uses 24-bit
authorJorrit Herder <jnherder@minix3.org>
Fri, 5 Aug 2005 16:23:42 +0000 (16:23 +0000)
committerJorrit Herder <jnherder@minix3.org>
Fri, 5 Aug 2005 16:23:42 +0000 (16:23 +0000)
addressing, which can address 16 MB max).
Floppy driver now dynamically loaded.

drivers/floppy/Makefile
drivers/floppy/floppy.c
drivers/libdriver/driver.c
etc/rc
etc/usr/rc

index 55f0fdcc5e4ee4f91adfc5cc94b45cc28bbd3f4a..b9e59b97459d56df99c0aa28f340b74f867f3414 100644 (file)
@@ -29,8 +29,8 @@ $(LIBDRIVER):
        cd $d/libdriver && $(MAKE) 
 
 # install with other drivers
-install:       /usr/sbin/$(DRIVER)
-/usr/sbin/$(DRIVER):   $(DRIVER)
+install:       /sbin/$(DRIVER)
+/sbin/$(DRIVER):       $(DRIVER)
        install -o root -cs $? $@
 
 # clean up local files
index 0d775d8a63a7df03111473cbbcd8d21b0c06e413..6745258f7d4d12edf00d3b1c94ee0f4c694bb4dc 100644 (file)
 #define FDC_DATA       0x3F5   /* floppy disk controller data register */
 #define FDC_RATE       0x3F7   /* transfer rate register */
 #define DMA_ADDR       0x004   /* port for low 16 bits of DMA address */
-#define DMA_TOP        0x081   /* port for top 4 bits of 20-bit DMA addr */
+#define DMA_TOP        0x081   /* port for top 8 bits of 24-bit DMA addr */
 #define DMA_COUNT      0x005   /* port for DMA count (count =  bytes - 1) */
 #define DMA_FLIPFLOP   0x00C   /* DMA byte pointer flip-flop */
 #define DMA_MODE       0x00B   /* DMA mode port */
 #define DMA_INIT       0x00A   /* DMA init port */
-#define DMA_RESET_VAL   0x06
+#define DMA_RESET_VAL  0x006
+
+#define DMA_ADDR_MASK  0xFFFFFF        /* mask to verify DMA address is 24-bit */
 
 /* Status registers returned as result of operation. */
 #define ST0             0x00   /* status register 0 */
@@ -245,7 +247,7 @@ FORWARD _PROTOTYPE( char *f_name, (void) );
 FORWARD _PROTOTYPE( void f_cleanup, (void) );
 FORWARD _PROTOTYPE( int f_transfer, (int proc_nr, int opcode, off_t position,
                                        iovec_t *iov, unsigned nr_req) );
-FORWARD _PROTOTYPE( void dma_setup, (int opcode) );
+FORWARD _PROTOTYPE( int dma_setup, (int opcode) );
 FORWARD _PROTOTYPE( void start_motor, (void) );
 FORWARD _PROTOTYPE( int seek, (void) );
 FORWARD _PROTOTYPE( int fdc_transfer, (int opcode) );
@@ -571,7 +573,13 @@ unsigned nr_req;           /* length of request vector */
 
                /* Set up the DMA chip and perform the transfer. */
                if (r == OK) {
-                       dma_setup(opcode);
+                       if (dma_setup(opcode) != OK) {
+                               /* This can only fail for addresses above 16MB
+                                * that cannot be handled by the controller, 
+                                * because it uses 24-bit addressing.
+                                */
+                               return(EIO);
+                       }
                        r = fdc_transfer(opcode);
                }
 
@@ -627,7 +635,7 @@ unsigned nr_req;            /* length of request vector */
 /*===========================================================================*
  *                             dma_setup                                    *
  *===========================================================================*/
-PRIVATE void dma_setup(opcode)
+PRIVATE int dma_setup(opcode)
 int opcode;                    /* DEV_GATHER or DEV_SCATTER */
 {
 /* The IBM PC can perform DMA operations by using the DMA chip.  To use it,
@@ -636,10 +644,21 @@ int opcode;                       /* DEV_GATHER or DEV_SCATTER */
  * opcode.  This routine sets up the DMA chip.  Note that the chip is not
  * capable of doing a DMA across a 64K boundary (e.g., you can't read a
  * 512-byte block starting at physical address 65520).
+ *
+ * Warning! Also note that it's not possible to do DMA above 16 MB because 
+ * the ISA bus uses 24-bit addresses. Addresses above 16 MB therefore will 
+ * be interpreted modulo 16 MB, dangerously overwriting arbitrary memory. 
+ * A check here denies the I/O if the address is out of range. 
  */
   pvb_pair_t byte_out[9];
   int s;
 
+  /* First check the DMA memory address not to exceed maximum. */
+  if (tmp_phys != (tmp_phys & DMA_ADDR_MASK)) {
+       report("FLOPPY", "DMA denied because address out of range", NO_NUM);
+       return(EIO);
+  }
+
   /* Set up the DMA registers.  (The comment on the reset is a bit strong,
    * it probably only resets the floppy channel.)
    */
@@ -655,6 +674,7 @@ int opcode;                 /* DEV_GATHER or DEV_SCATTER */
 
   if ((s=sys_voutb(byte_out, 9)) != OK)
        panic("FLOPPY","Sys_voutb in dma_setup() failed", s);
+  return(OK);
 }
 
 
index a95f7014b5ecca4119fde4a25b58f31f9721bc7d..bc6e776d70012d7d52b61161fb786acc6da4a674 100644 (file)
@@ -41,6 +41,7 @@
 
 
 #if (CHIP == INTEL)
+
 #if USE_EXTRA_DMA_BUF && DMA_BUF_SIZE < 2048
 /* A bit extra scratch for the Adaptec driver. */
 #define BUF_EXTRA      (2048 - DMA_BUF_SIZE)
@@ -156,7 +157,7 @@ PRIVATE void init_buffer()
        tmp_buf += left;
        tmp_phys += left;
   }
-#endif /* CHIP != INTEL */
+#endif /* CHIP == INTEL */
 }
 
 
diff --git a/etc/rc b/etc/rc
index 4fa646b3a4fca533ea19b02c12ece6502539691e..96debe7c63f5385426e25f225aebc3a0d1d3dce6 100755 (executable)
--- a/etc/rc
+++ b/etc/rc
@@ -51,8 +51,10 @@ start)
     # National keyboard?
     test -f /etc/keymap && loadkeys /etc/keymap
 
-    # Start crucial system services
+    # Start crucial system services. The floppy driver *must* be loaded 
+    # first, as it needs memory below 16MB in order to do ISA DMA.
     echo -n "Starting services:"
+    up floppy "" /dev/fd0
     up is ""
     up cmos "" /dev/cmos
     echo .
index 13ab0bc9ce6a928d76f6f0031635ba90d7fa82a0..40f57f44daa757dea622f4eb7b39e10342ada9c0 100644 (file)
@@ -102,7 +102,6 @@ start)
     done
     up inet ""
     up printer "" /dev/lp
-#    up floppy "" /dev/fd0
     echo .
 
     # Network initialization.