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;