Synopsis: Problem with mmap(2) and many drivers.
NetBSD versions: 1.3 and 1.3.1, 1.3.2.
Thanks to: Chris Demetriou, Ted Lemon and Matthew Green.
Reported in NetBSD Advisory: NetBSD-SA1998-005
Notes: cd to src/sys and run `patch -p < thisfile' to apply.


Index: arch/alpha/pci/tga.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/pci/Attic/tga.c,v
retrieving revision 1.21
diff -c -r1.21 tga.c
*** tga.c	1997/09/25 01:32:04	1.21
--- tga.c	1998/11/19 14:38:15
***************
*** 401,407 ****
  {
  	struct tga_softc *sc = v;
  
! 	if (offset > sc->sc_dc->dc_tgaconf->tgac_cspace_size)
  		return -1;
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
--- 401,407 ----
  {
  	struct tga_softc *sc = v;
  
! 	if (offset >= sc->sc_dc->dc_tgaconf->tgac_cspace_size || offset < 0)
  		return -1;
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
Index: arch/alpha/tc/cfb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/tc/cfb.c,v
retrieving revision 1.13
diff -c -r1.13 cfb.c
*** cfb.c	1997/09/25 01:32:09	1.13
--- cfb.c	1998/11/19 14:38:16
***************
*** 298,305 ****
  {
  	struct cfb_softc *sc = v;
  
! 	if (offset > CFB_SIZE)
! 		return -1;
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
  
--- 298,305 ----
  {
  	struct cfb_softc *sc = v;
  
! 	if (offset >= CFB_SIZE || offset < 0)
! 		return (-1);
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
  
Index: arch/alpha/tc/sfb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/tc/sfb.c,v
retrieving revision 1.13
diff -c -r1.13 sfb.c
*** sfb.c	1997/09/25 01:32:12	1.13
--- sfb.c	1998/11/19 14:38:16
***************
*** 343,350 ****
  {
  	struct sfb_softc *sc = v;
  
! 	if (offset > SFB_SIZE)
! 		return -1;
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
  
--- 343,350 ----
  {
  	struct sfb_softc *sc = v;
  
! 	if (offset >= SFB_SIZE || offset < 0)
! 		return (-1);
  	return alpha_btop(sc->sc_dc->dc_paddr + offset);
  }
  
Index: arch/alpha/wscons/wscons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/wscons/wscons.c,v
retrieving revision 1.15
diff -c -r1.15 wscons.c
*** wscons.c	1997/09/02 13:20:58	1.15
--- wscons.c	1998/11/19 14:38:17
***************
*** 378,384 ****
  {
  	struct wscons_softc *sc = wscons_cd.cd_devs[WSCUNIT(dev)];
  
! 	if (sc->sc_ioctl != NULL)
  		return (*sc->sc_mmap)(sc->sc_dev.dv_parent, offset, prot);
  	else
  		return -1;
--- 378,384 ----
  {
  	struct wscons_softc *sc = wscons_cd.cd_devs[WSCUNIT(dev)];
  
! 	if (sc->sc_ioctl != NULL && offset >= 0)
  		return (*sc->sc_mmap)(sc->sc_dev.dv_parent, offset, prot);
  	else
  		return -1;
Index: arch/amiga/amiga/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/amiga/mem.c,v
retrieving revision 1.18
diff -c -r1.18 mem.c
*** mem.c	1997/02/02 07:17:14	1.18
--- mem.c	1998/11/19 14:38:17
***************
*** 234,238 ****
  	int off, prot;
  {
  
! 	return (EOPNOTSUPP);
  }
--- 234,238 ----
  	int off, prot;
  {
  
! 	return (-1);
  }
Index: arch/arm32/arm32/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/arm32/mem.c,v
retrieving revision 1.3
diff -c -r1.3 mem.c
*** mem.c	1997/07/31 23:02:24	1.3
--- mem.c	1998/11/19 14:38:19
***************
*** 199,205 ****
  
  	/* minor device 0 is physical memory */
  
! 	if (off > ctob(physmem) &&
  	    suser(p->p_ucred, &p->p_acflag) != 0)
  		return -1;
  	return arm_byte_to_page(off);
--- 199,205 ----
  
  	/* minor device 0 is physical memory */
  
! 	if ((unsigned)off >= ctob(physmem) &&
  	    suser(p->p_ucred, &p->p_acflag) != 0)
  		return -1;
  	return arm_byte_to_page(off);
Index: arch/arm32/vidc/console/vidcconsole.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm32/vidc/console/vidcconsole.c,v
retrieving revision 1.15
diff -c -r1.15 vidcconsole.c
*** vidcconsole.c	1997/10/14 11:49:19	1.15
--- vidcconsole.c	1998/11/19 14:38:30
***************
*** 807,813 ****
  	int offset;
  	int nprot;
  {
! 	if (offset > videomemory.vidm_size)
  		return (-1);
  	return(arm_byte_to_page(((videomemory.vidm_pbase) + (offset))));
  }
--- 807,813 ----
  	int offset;
  	int nprot;
  {
! 	if ((u_int)offset >= videomemory.vidm_size)
  		return (-1);
  	return(arm_byte_to_page(((videomemory.vidm_pbase) + (offset))));
  }
Index: arch/atari/atari/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/atari/mem.c,v
retrieving revision 1.9
diff -c -r1.9 mem.c
*** mem.c	1997/04/25 19:07:45	1.9
--- mem.c	1998/11/19 14:38:30
***************
*** 205,209 ****
  	int off, prot;
  {
  
! 	return (EOPNOTSUPP);
  }
--- 205,209 ----
  	int off, prot;
  {
  
! 	return (-1);
  }
Index: arch/bebox/bebox/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/bebox/bebox/Attic/mem.c,v
retrieving revision 1.1
diff -c -r1.1 mem.c
*** mem.c	1997/10/14 06:47:47	1.1
--- mem.c	1998/11/19 14:38:31
***************
*** 150,154 ****
          dev_t dev;
          int off, prot;
  {
! 	return EOPNOTSUPP;
  }
--- 150,154 ----
          dev_t dev;
          int off, prot;
  {
! 	return -1;
  }
Index: arch/bebox/isa/pccons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/bebox/isa/pccons.c,v
retrieving revision 1.1.2.1
diff -c -r1.1.2.1 pccons.c
*** pccons.c	1997/11/28 19:48:20	1.1.2.1
--- pccons.c	1998/11/19 14:38:36
***************
*** 1680,1686 ****
  	int nprot;
  {
  
! 	if (offset > 0x20000)
  		return -1;
  #if 0
  	return i386_btop(0xa0000 + offset);
--- 1680,1686 ----
  	int nprot;
  {
  
! 	if ((u_int)offset > 0x20000)
  		return -1;
  #if 0
  	return i386_btop(0xa0000 + offset);
Index: arch/hp300/hp300/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/hp300/mem.c,v
retrieving revision 1.17
diff -c -r1.17 mem.c
*** mem.c	1997/06/10 18:51:31	1.17
--- mem.c	1998/11/19 14:38:37
***************
*** 226,232 ****
  	/*
  	 * Allow access only in RAM.
  	 */
! 	if ((unsigned)off < lowram || (unsigned)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop(off));
  }
--- 226,232 ----
  	/*
  	 * Allow access only in RAM.
  	 */
! 	if ((u_int)off < lowram || (u_int)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop((u_int)off));
  }
Index: arch/i386/i386/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/mem.c,v
retrieving revision 1.32
diff -c -r1.32 mem.c
*** mem.c	1997/03/24 21:16:59	1.32
--- mem.c	1998/11/19 14:38:39
***************
*** 198,207 ****
  	switch (minor(dev)) {
  /* minor device 0 is physical memory */
  	case 0:
! 		if (off > ctob(physmem) &&
  		    suser(p->p_ucred, &p->p_acflag) != 0)
  			return -1;
! 		return i386_btop(off);
  
  /* minor device 1 is kernel memory */
  	case 1:
--- 198,207 ----
  	switch (minor(dev)) {
  /* minor device 0 is physical memory */
  	case 0:
! 		if ((u_int)off > ctob(physmem) &&
  		    suser(p->p_ucred, &p->p_acflag) != 0)
  			return -1;
! 		return i386_btop((u_int)off);
  
  /* minor device 1 is kernel memory */
  	case 1:
Index: arch/i386/isa/pccons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/isa/pccons.c,v
retrieving revision 1.113.2.3
diff -c -r1.113.2.3 pccons.c
*** pccons.c	1998/01/29 10:07:25	1.113.2.3
--- pccons.c	1998/11/19 14:38:42
***************
*** 2323,2329 ****
  	int nprot;
  {
  
! 	if (offset > 0x20000)
  		return (-1);
  	return (i386_btop(0xa0000 + offset));
  }
--- 2323,2329 ----
  	int nprot;
  {
  
! 	if ((u_int)offset > 0x20000)
  		return (-1);
  	return (i386_btop(0xa0000 + offset));
  }
Index: arch/i386/isa/pcvt/pcvt_drv.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/isa/pcvt/pcvt_drv.c,v
retrieving revision 1.40.4.1
diff -c -r1.40.4.1 pcvt_drv.c
*** pcvt_drv.c	1997/12/07 06:22:24	1.40.4.1
--- pcvt_drv.c	1998/11/19 14:38:44
***************
*** 771,777 ****
  int
  pcmmap(Dev_t dev, int offset, int nprot)
  {
! 	if (offset > 0x20000)
  		return -1;
  	return i386_btop((0xa0000 + offset));
  }
--- 771,777 ----
  int
  pcmmap(Dev_t dev, int offset, int nprot)
  {
! 	if ((u_int)offset >= 0x20000)
  		return -1;
  	return i386_btop((0xa0000 + offset));
  }
Index: arch/mac68k/dev/asc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/Attic/asc.c,v
retrieving revision 1.24
diff -c -r1.24 asc.c
*** asc.c	1997/10/10 05:54:54	1.24
--- asc.c	1998/11/19 14:38:45
***************
*** 276,282 ****
  	vm_offset_t pa;
  
  	sc = asc_cd.cd_devs[unit];
! 	if (off < MAC68K_ASC_LEN) {
  		pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_handle);
  		return m68k_btop(pa + off);
  	}
--- 276,282 ----
  	vm_offset_t pa;
  
  	sc = asc_cd.cd_devs[unit];
! 	if ((u_int)off < MAC68K_ASC_LEN) {
  		pa = pmap_extract(pmap_kernel(), (vm_offset_t)sc->sc_handle);
  		return m68k_btop(pa + off);
  	}
Index: arch/mac68k/dev/grf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/grf.c,v
retrieving revision 1.45.4.1
diff -c -r1.45.4.1 grf.c
*** grf.c	1998/01/29 12:18:02	1.45.4.1
--- grf.c	1998/11/19 14:38:45
***************
*** 290,296 ****
  		printf("grfmmap(%x): off %x, prot %x\n", dev, off, prot);
  #endif
  
! 	if (off < m68k_round_page(gm->fbsize + gm->fboff))
  		addr = m68k_btop((*gp->sc_phys)(gp) + off);
  	else
  		addr = (-1);	/* XXX bogus */
--- 290,296 ----
  		printf("grfmmap(%x): off %x, prot %x\n", dev, off, prot);
  #endif
  
! 	if (off >= 0 && off < m68k_round_page(gm->fbsize + gm->fboff))
  		addr = m68k_btop((*gp->sc_phys)(gp) + off);
  	else
  		addr = (-1);	/* XXX bogus */
Index: arch/mips/mips/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mem.c,v
retrieving revision 1.11
diff -c -r1.11 mem.c
*** mem.c	1997/09/24 02:20:56	1.11
--- mem.c	1998/11/19 14:38:46
***************
*** 170,174 ****
  	int off, prot;
  {
  
! 	return (EOPNOTSUPP);
  }
--- 170,174 ----
  	int off, prot;
  {
  
! 	return (-1);
  }
Index: arch/mvme68k/mvme68k/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/mvme68k/mem.c,v
retrieving revision 1.2
diff -c -r1.2 mem.c
*** mem.c	1997/02/02 08:27:15	1.2
--- mem.c	1998/11/19 14:38:47
***************
*** 216,222 ****
  	 * XXX could be extended to allow access to IO space but must
  	 * be very careful.
  	 */
! 	if ((unsigned)off < lowram || (unsigned)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop(off));
  }
--- 216,222 ----
  	 * XXX could be extended to allow access to IO space but must
  	 * be very careful.
  	 */
! 	if ((u_int)off < lowram || (u_int)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop((u_int)off));
  }
Index: arch/pc532/pc532/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pc532/pc532/mem.c,v
retrieving revision 1.15
diff -c -r1.15 mem.c
*** mem.c	1997/04/01 16:32:52	1.15
--- mem.c	1998/11/19 14:38:50
***************
*** 176,180 ****
  	dev_t dev;
  	int off, prot;
  {
! 	return (EOPNOTSUPP);
  }
--- 176,180 ----
  	dev_t dev;
  	int off, prot;
  {
! 	return (-1);
  }
Index: arch/pmax/dev/fb_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/dev/fb_usrreq.c,v
retrieving revision 1.10
diff -c -r1.10 fb_usrreq.c
*** fb_usrreq.c	1997/06/22 07:42:30	1.10
--- fb_usrreq.c	1998/11/19 14:38:51
***************
*** 242,247 ****
--- 242,250 ----
  	int len;
  	register struct fbinfo *fi;
  
+ 	if (off < 0)
+ 		return (-1);
+ 
  	if (minor(dev) >= fbcd.cd_ndevs ||
  	    (fi = fbcd.cd_devs[minor(dev)]) == NULL)
  	    return(-1);
Index: arch/pmax/dev/rcons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/dev/rcons.c,v
retrieving revision 1.14
diff -c -r1.14 rcons.c
*** rcons.c	1996/10/13 13:14:00	1.14
--- rcons.c	1998/11/19 14:38:52
***************
*** 373,379 ****
  	 int off;
  	 int prot;
  {
! 	return 0;
  }
  
  void
--- 373,380 ----
  	 int off;
  	 int prot;
  {
! 
! 	return -1;
  }
  
  void
Index: arch/powerpc/powerpc/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/mem.c,v
retrieving revision 1.1
diff -c -r1.1 mem.c
*** mem.c	1996/09/30 16:34:50	1.1
--- mem.c	1998/11/19 14:38:52
***************
*** 150,154 ****
          dev_t dev;
          int off, prot;
  {
! 	return EOPNOTSUPP;
  }
--- 150,154 ----
          dev_t dev;
          int off, prot;
  {
! 	return -1;
  }
Index: arch/sparc/dev/cgeight.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/cgeight.c,v
retrieving revision 1.14
diff -c -r1.14 cgeight.c
*** cgeight.c	1997/10/05 18:24:32	1.14
--- cgeight.c	1998/11/19 14:38:53
***************
*** 449,455 ****
  	if (off & PGOFSET)
  		panic("cgeightmap");
  
! 	if ((u_int)off >= NOOVERLAY) {
  		off -= NOOVERLAY;
  
  		/*
--- 449,457 ----
  	if (off & PGOFSET)
  		panic("cgeightmap");
  
! 	if (off < 0)
! 		return (-1);
! 	else if ((u_int)off >= NOOVERLAY) {
  		off -= NOOVERLAY;
  
  		/*
***************
*** 457,463 ****
  		 * there really is. We compensate by double-mapping the
  		 * first page for as many other pages as it wants
  		 */
! 		while (off >= COLOR_SIZE)
  			off -= COLOR_SIZE;	/* XXX thorpej ??? */
  
  		poff = off + PFOUR_COLOR_OFF_COLOR;
--- 459,465 ----
  		 * there really is. We compensate by double-mapping the
  		 * first page for as many other pages as it wants
  		 */
! 		while ((u_int)off >= COLOR_SIZE)
  			off -= COLOR_SIZE;	/* XXX thorpej ??? */
  
  		poff = off + PFOUR_COLOR_OFF_COLOR;
Index: arch/sparc/dev/cgfour.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/cgfour.c,v
retrieving revision 1.14
diff -c -r1.14 cgfour.c
*** cgfour.c	1997/10/05 18:24:33	1.14
--- cgfour.c	1998/11/19 14:38:54
***************
*** 447,453 ****
  	if (off & PGOFSET)
  		panic("cgfourmap");
  
! 	if ((u_int)off >= NOOVERLAY) {
  		off -= NOOVERLAY;
  
  		/*
--- 447,455 ----
  	if (off & PGOFSET)
  		panic("cgfourmap");
  
! 	if (off < 0)
! 		return (-1);
! 	else if ((u_int)off >= NOOVERLAY) {
  		off -= NOOVERLAY;
  
  		/*
***************
*** 455,461 ****
  		 * there really is. We compensate by double-mapping the
  		 * first page for as many other pages as it wants
  		 */
! 		while (off >= COLOR_SIZE)
  			off -= COLOR_SIZE;	/* XXX thorpej ??? */
  
  		poff = off + PFOUR_COLOR_OFF_COLOR;
--- 457,463 ----
  		 * there really is. We compensate by double-mapping the
  		 * first page for as many other pages as it wants
  		 */
! 		while ((u_int)off >= COLOR_SIZE)
  			off -= COLOR_SIZE;	/* XXX thorpej ??? */
  
  		poff = off + PFOUR_COLOR_OFF_COLOR;
Index: arch/sparc/dev/cgfourteen.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/cgfourteen.c,v
retrieving revision 1.7
diff -c -r1.7 cgfourteen.c
*** cgfourteen.c	1997/05/24 20:16:08	1.7
--- cgfourteen.c	1998/11/19 14:38:56
***************
*** 576,581 ****
--- 576,584 ----
  	if (off & PGOFSET)
  		panic("cgfourteenmmap");
  
+ 	if (off < 0)
+ 		return (-1);
+ 
  #if defined(DEBUG) && defined(CG14_MAP_REGS) /* XXX: security hole */
  	/*
  	 * Map the control registers into user space. Should only be 
Index: arch/sparc/dev/cgthree.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/cgthree.c,v
retrieving revision 1.33
diff -c -r1.33 cgthree.c
*** cgthree.c	1997/05/24 20:16:11	1.33
--- cgthree.c	1998/11/19 14:38:57
***************
*** 437,442 ****
--- 437,444 ----
  
  	if (off & PGOFSET)
  		panic("cgthreemmap");
+ 	if (off < 0)
+ 		return (-1);
  	if ((u_int)off >= NOOVERLAY)
  		off -= NOOVERLAY;
  	else if ((u_int)off >= START)
Index: arch/sun3/sun3/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/sun3/mem.c,v
retrieving revision 1.26
diff -c -r1.26 mem.c
*** mem.c	1997/04/28 23:21:01	1.26
--- mem.c	1998/11/19 14:39:01
***************
*** 247,253 ****
  	dev_t dev;
  	int off, prot;
  {
! 	register int v = off;
  
  	/*
  	 * Check address validity.
--- 247,253 ----
  	dev_t dev;
  	int off, prot;
  {
! 	register u_int v = off;
  
  	/*
  	 * Check address validity.
Index: arch/sun3x/sun3x/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3x/sun3x/Attic/mem.c,v
retrieving revision 1.7
diff -c -r1.7 mem.c
*** mem.c	1997/04/25 18:46:10	1.7
--- mem.c	1998/11/19 14:39:01
***************
*** 236,242 ****
  	dev_t dev;
  	int off, prot;
  {
! 	register int v = off;
  
  	/*
  	 * Check address validity.
--- 236,242 ----
  	dev_t dev;
  	int off, prot;
  {
! 	register u_int v = off;
  
  	/*
  	 * Check address validity.
Index: arch/vax/vax/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vax/mem.c,v
retrieving revision 1.9
diff -c -r1.9 mem.c
*** mem.c	1996/04/08 18:32:48	1.9
--- mem.c	1998/11/19 14:39:02
***************
*** 194,198 ****
  	int off, prot;
  {
  
! 	return (EOPNOTSUPP);
  }
--- 194,198 ----
  	int off, prot;
  {
  
! 	return (-1);
  }
Index: arch/x68k/x68k/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/mem.c,v
retrieving revision 1.8
diff -c -r1.8 mem.c
*** mem.c	1997/10/10 17:43:16	1.8
--- mem.c	1998/11/19 14:39:03
***************
*** 224,230 ****
  	 * XXX could be extended to allow access to IO space but must
  	 * be very careful.
  	 */
! 	if ((unsigned)off < lowram || (unsigned)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop(off));
  }
--- 224,230 ----
  	 * XXX could be extended to allow access to IO space but must
  	 * be very careful.
  	 */
! 	if ((u_int)off < lowram || (u_int)off >= 0xFFFFFFFC)
  		return (-1);
! 	return (m68k_btop((u_int)off));
  }
Index: dev/audio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audio.c,v
retrieving revision 1.77.2.1
diff -c -r1.77.2.1 audio.c
*** audio.c	1997/11/05 02:46:55	1.77.2.1
--- audio.c	1998/11/19 14:39:08
***************
*** 1648,1654 ****
  	cb = &sc->sc_pr;
  #endif
  
! 	if (off >= cb->bufsize)
  		return -1;
  	if (!cb->mmapped) {
  		cb->mmapped = 1;
--- 1648,1654 ----
  	cb = &sc->sc_pr;
  #endif
  
! 	if ((u_int)off >= cb->bufsize)
  		return -1;
  	if (!cb->mmapped) {
  		cb->mmapped = 1;
Index: dev/isa/isadma.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/isadma.c,v
retrieving revision 1.32
diff -c -r1.32 isadma.c
*** isadma.c	1997/09/05 01:48:33	1.32
--- isadma.c	1998/11/19 14:39:15
***************
*** 579,584 ****
--- 579,587 ----
  		panic("isa_dmamem_mmap");
  	}
  
+ 	if (off < 0)
+ 		return (-1);
+ 
  	seg.ds_addr = addr;
  	seg.ds_len = size;