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;