Synopsis: Insufficient checking of lengths passed from userland to kernel NetBSD versions: 1.5, 1.5.1 Thanks to: Jaromir Dolecek Reported in NetBSD Security Advisory: NetBSD-SA2001-015 Index: arch/amiga/dev/grf_cl.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/amiga/dev/grf_cl.c,v retrieving revision 1.25 retrieving revision 1.25.12.1 diff -u -p -r1.25 -r1.25.12.1 --- grf_cl.c 1999/06/29 19:51:28 1.25 +++ grf_cl.c 2001/08/16 16:52:36 1.25.12.1 @@ -905,7 +905,7 @@ cl_setspriteinfo(gp, data) if (data->set & GRFSPRSET_SHAPE) { - short dsx, dsy, i; + unsigned short dsx, dsy, i; unsigned long *di, *dm, *si, *sm; unsigned long ssi[128], ssm[128]; struct grf_position gpos; Index: arch/amiga/dev/grfioctl.h =================================================================== RCS file: /cvsroot/syssrc/sys/arch/amiga/dev/grfioctl.h,v retrieving revision 1.13 retrieving revision 1.13.30.1 diff -u -p -r1.13 -r1.13.30.1 --- grfioctl.h 1997/07/29 17:54:11 1.13 +++ grfioctl.h 2001/08/16 16:52:37 1.13.30.1 @@ -147,8 +147,8 @@ struct grfvideo_mode { * Maxium value of "index" can be deduced from grfinfo->gd_colors. */ struct grf_colormap { - int index; /* start at red[index],green[index],blue[index] */ - int count; /* till < red[index+count],... */ + unsigned int index; /* start at red[index],green[index],blue[index] */ + unsigned int count; /* till < red[index+count],... */ u_char *red; u_char *green; u_char *blue; Index: arch/hpcmips/dev/plumvideo.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/hpcmips/dev/plumvideo.c,v retrieving revision 1.11.4.1 retrieving revision 1.11.4.2 diff -u -p -r1.11.4.1 -r1.11.4.2 --- plumvideo.c 2000/06/30 16:27:24 1.11.4.1 +++ plumvideo.c 2001/08/16 16:52:37 1.11.4.2 @@ -429,7 +429,8 @@ plumvideo_ioctl(v, cmd, data, flag, p) struct wsdisplay_cmap *cmap; u_int8_t *r, *g, *b; u_int32_t *rgb; - int idx, cnt, error; + int idx, error; + size_t cnt; switch (cmd) { case WSDISPLAYIO_GETCMAP: Index: arch/macppc/dev/ofb.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/macppc/dev/ofb.c,v retrieving revision 1.13.2.2 retrieving revision 1.13.2.3 diff -u -p -r1.13.2.2 -r1.13.2.3 --- ofb.c 2000/11/01 16:24:01 1.13.2.2 +++ ofb.c 2001/08/16 16:52:37 1.13.2.3 @@ -515,8 +515,8 @@ ofb_putcmap(sc, cm) struct wsdisplay_cmap *cm; { struct ofb_devconfig *dc = sc->sc_dc; - int index = cm->index; - int count = cm->count; + u_int index = cm->index; + u_int count = cm->count; int i; u_char *r, *g, *b; Index: arch/sparc/dev/cgtwo.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/sparc/dev/cgtwo.c,v retrieving revision 1.31.4.1 retrieving revision 1.31.4.2 diff -u -p -r1.31.4.1 -r1.31.4.2 --- cgtwo.c 2000/06/30 16:27:38 1.31.4.1 +++ cgtwo.c 2001/08/16 16:52:37 1.31.4.2 @@ -365,7 +365,8 @@ cgtwoputcmap(sc, cmap) register struct fbcmap *cmap; { u_char red[CG2_CMSIZE], green[CG2_CMSIZE], blue[CG2_CMSIZE]; - int error, start, count, ecount; + int error; + u_int start, count, ecount; register u_int i; register volatile u_short *p; Index: arch/sun3/dev/cg2.c =================================================================== RCS file: /cvsroot/syssrc/sys/arch/sun3/dev/cg2.c,v retrieving revision 1.11.26.1 retrieving revision 1.11.26.2 diff -u -p -r1.11.26.1 -r1.11.26.2 --- cg2.c 2000/06/30 16:27:42 1.11.26.1 +++ cg2.c 2001/08/16 16:52:38 1.11.26.2 @@ -352,7 +352,8 @@ static int cg2putcmap(fb, data) struct fbcmap *cmap = data; struct cg2_softc *sc = fb->fb_private; u_char red[CMSIZE], green[CMSIZE], blue[CMSIZE]; - int error, start, count, ecount; + int error; + u_int start, count, ecount; register u_int i; register u_short *p; Index: arch/sparc/include/fbio.h =================================================================== RCS file: /cvsroot/syssrc/sys/arch/sparc/include/Attic/fbio.h,v retrieving revision 1.6 retrieving revision 1.6.12.1 diff -u -p -r1.6 -r1.6.12.1 --- fbio.h 1999/08/01 00:23:49 1.6 +++ fbio.h 2001/08/16 16:52:38 1.6.12.1 @@ -107,8 +107,8 @@ struct fbinfo { * Color map I/O. */ struct fbcmap { - int index; /* first element (0 origin) */ - int count; /* number of elements */ + u_int index; /* first element (0 origin) */ + u_int count; /* number of elements */ u_char *red; /* red color map elements */ u_char *green; /* green color map elements */ u_char *blue; /* blue color map elements */ Index: arch/sparc64/include/fbio.h =================================================================== RCS file: /cvsroot/syssrc/sys/arch/sparc64/include/fbio.h,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.24.1 diff -u -p -r1.1.1.1 -r1.1.1.1.24.1 --- fbio.h 1998/06/20 04:58:51 1.1.1.1 +++ fbio.h 2001/08/16 16:52:38 1.1.1.1.24.1 @@ -106,8 +106,8 @@ struct fbinfo { * Color map I/O. */ struct fbcmap { - int index; /* first element (0 origin) */ - int count; /* number of elements */ + u_int index; /* first element (0 origin) */ + u_int count; /* number of elements */ u_char *red; /* red color map elements */ u_char *green; /* green color map elements */ u_char *blue; /* blue color map elements */ Index: arch/sun3/include/fbio.h =================================================================== RCS file: /cvsroot/syssrc/sys/arch/sun3/include/fbio.h,v retrieving revision 1.3 retrieving revision 1.3.46.1 diff -u -p -r1.3 -r1.3.46.1 --- fbio.h 1994/11/21 21:33:40 1.3 +++ fbio.h 2001/08/16 16:52:38 1.3.46.1 @@ -104,8 +104,8 @@ struct fbinfo { * Color map I/O. */ struct fbcmap { - int index; /* first element (0 origin) */ - int count; /* number of elements */ + u_int index; /* first element (0 origin) */ + u_int count; /* number of elements */ u_char *red; /* red color map elements */ u_char *green; /* green color map elements */ u_char *blue; /* blue color map elements */ Index: dev/pci/tga.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/pci/tga.c,v retrieving revision 1.25.2.3 retrieving revision 1.25.2.4 diff -u -p -r1.25.2.3 -r1.25.2.4 --- tga.c 2001/06/25 16:27:54 1.25.2.3 +++ tga.c 2001/08/16 16:52:39 1.25.2.4 @@ -771,7 +771,8 @@ tga_builtin_set_cursor(dc, cursorp) { struct ramdac_funcs *dcrf = dc->dc_ramdac_funcs; struct ramdac_cookie *dcrc = dc->dc_ramdac_cookie; - int count, error, v; + u_int count, v; + int error; v = cursorp->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/cfb.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/cfb.c,v retrieving revision 1.20.4.1 retrieving revision 1.20.4.2 diff -u -p -r1.20.4.1 -r1.20.4.2 --- cfb.c 2000/06/30 16:27:52 1.20.4.1 +++ cfb.c 2001/08/16 16:52:39 1.20.4.2 @@ -714,7 +714,7 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, index, count, icount; + u_int v, index, count, icount; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/mfb.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/mfb.c,v retrieving revision 1.22.4.1 retrieving revision 1.22.4.2 diff -u -p -r1.22.4.1 -r1.22.4.2 --- mfb.c 2000/06/30 16:27:52 1.22.4.1 +++ mfb.c 2001/08/16 16:52:40 1.22.4.2 @@ -32,7 +32,7 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: SA2001-015-kernlen-1.5.patch,v 1.1 2001/08/23 21:02:14 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: SA2001-015-kernlen-1.5.patch,v 1.1 2001/08/23 21:02:14 jdolecek Exp $"); #include #include @@ -615,7 +615,7 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, count, index; + u_int v, count, index; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/sfb.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/sfb.c,v retrieving revision 1.35.4.1 retrieving revision 1.35.4.2 diff -u -p -r1.35.4.1 -r1.35.4.2 --- sfb.c 2000/06/30 16:27:52 1.35.4.1 +++ sfb.c 2001/08/16 16:52:40 1.35.4.2 @@ -32,7 +32,7 @@ #include /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: SA2001-015-kernlen-1.5.patch,v 1.1 2001/08/23 21:02:14 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: SA2001-015-kernlen-1.5.patch,v 1.1 2001/08/23 21:02:14 jdolecek Exp $"); #include #include @@ -752,7 +752,7 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, index, count, icount; + u_int v, index, count, icount; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/sfbplus.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/sfbplus.c,v retrieving revision 1.3.6.1 retrieving revision 1.3.6.2 diff -u -p -r1.3.6.1 -r1.3.6.2 --- sfbplus.c 2000/06/30 16:27:52 1.3.6.1 +++ sfbplus.c 2001/08/16 16:52:40 1.3.6.2 @@ -774,7 +774,8 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, index, count, icount, x, y; + u_int v, index, count, icount; + int x, y; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/tfb.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/tfb.c,v retrieving revision 1.24.4.1 retrieving revision 1.24.4.2 diff -u -p -r1.24.4.1 -r1.24.4.2 --- tfb.c 2000/06/30 16:27:52 1.24.4.1 +++ tfb.c 2001/08/16 16:52:40 1.24.4.2 @@ -786,7 +786,7 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, index, count, icount; + u_int v, index, count, icount; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: dev/tc/xcfb.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/tc/xcfb.c,v retrieving revision 1.17.4.1 retrieving revision 1.17.4.2 diff -u -p -r1.17.4.1 -r1.17.4.2 --- xcfb.c 2000/06/30 16:27:52 1.17.4.1 +++ xcfb.c 2001/08/16 16:52:40 1.17.4.2 @@ -598,7 +598,7 @@ set_cursor(sc, p) struct wsdisplay_cursor *p; { #define cc (&sc->sc_cursor) - int v, index, count; + u_int v, index, count; v = p->which; if (v & WSDISPLAY_CURSOR_DOCMAP) { Index: net/if_ppp.c =================================================================== RCS file: /cvsroot/syssrc/sys/net/if_ppp.c,v retrieving revision 1.58 retrieving revision 1.58.4.1 diff -u -p -r1.58 -r1.58.4.1 --- if_ppp.c 2000/03/30 09:45:36 1.58 +++ if_ppp.c 2001/08/16 16:52:39 1.58.4.1 @@ -350,7 +350,8 @@ pppioctl(sc, cmd, data, flag, p) int flag; struct proc *p; { - int s, error, flags, mru, nb, npx; + int s, error, flags, mru, npx; + u_int nb; struct ppp_option_data *odp; struct compressor **cp; struct npioctl *npi; Index: coda/coda_venus.c =================================================================== RCS file: /cvsroot/syssrc/sys/coda/coda_venus.c,v retrieving revision 1.7 retrieving revision 1.7.20.1 diff -u -p -r1.7 -r1.7.20.1 --- coda_venus.c 1998/11/18 03:09:20 1.7 +++ coda_venus.c 2001/08/16 15:22:33 1.7.20.1 @@ -265,6 +265,9 @@ venus_ioctl(void *mdp, ViceFid *fid, inp->cmd = (com & ~(IOCPARM_MASK << 16)); tmp = ((com >> 16) & IOCPARM_MASK) - sizeof (char *) - sizeof (int); inp->cmd |= (tmp & IOCPARM_MASK) << 16; + + if (iap->vi.in_size < 0 || iap->vi.in_size > VC_MAXMSGSIZE) + return (EINVAL); inp->rwflag = flag; inp->len = iap->vi.in_size; Index: dev/wscons/wsdisplay.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/wscons/wsdisplay.c,v retrieving revision 1.37.4.2 retrieving revision 1.37.4.3 diff -u -p -r1.37.4.2 -r1.37.4.3 --- wsdisplay.c 2000/12/13 22:10:23 1.37.4.2 +++ wsdisplay.c 2001/08/16 16:19:12 1.37.4.3 @@ -1019,6 +1019,7 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, int error; char *type, typebuf[16], *emul, emulbuf[16]; void *buf; + u_int fontsz; #if defined(COMPAT_14) && NWSKBD > 0 struct wsmux_device wsmuxdata; #endif @@ -1061,10 +1062,12 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, d->name = typebuf; } else d->name = "loaded"; /* ??? */ - buf = malloc(d->fontheight * d->stride * d->numchars, - M_DEVBUF, M_WAITOK); - error = copyin(d->data, buf, - d->fontheight * d->stride * d->numchars); + fontsz = d->fontheight * d->stride * d->numchars; + if (fontsz > WSDISPLAY_MAXFONTSZ) + return (EINVAL); + + buf = malloc(fontsz, M_DEVBUF, M_WAITOK); + error = copyin(d->data, buf, fontsz); if (error) { free(buf, M_DEVBUF); return (error); Index: dev/wscons/wskbd.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/wscons/wskbd.c,v retrieving revision 1.38 retrieving revision 1.38.4.1 diff -u -p -r1.38 -r1.38.4.1 --- wskbd.c 2000/03/23 07:01:47 1.38 +++ wskbd.c 2001/08/16 16:19:12 1.38.4.1 @@ -964,6 +964,9 @@ getkeyrepeat: if ((flag & FWRITE) == 0) return (EACCES); umdp = (struct wskbd_map_data *)data; + if (umdp->maplen > WSKBDIO_MAXMAPLEN) + return (EINVAL); + len = umdp->maplen*sizeof(struct wscons_keymap); buf = malloc(len, M_TEMP, M_WAITOK); error = copyin(umdp->map, buf, len); Index: dev/wscons/wsconsio.h =================================================================== RCS file: /cvsroot/syssrc/sys/dev/wscons/wsconsio.h,v retrieving revision 1.31.2.1 retrieving revision 1.31.2.2 diff -u -p -r1.31.2.1 -r1.31.2.2 --- wsconsio.h 2000/07/07 09:49:17 1.31.2.1 +++ wsconsio.h 2001/08/16 16:19:13 1.31.2.2 @@ -135,6 +135,7 @@ struct wskbd_keyrepeat_data { /* Manipulate keysym groups. */ struct wskbd_map_data { u_int maplen; /* number of entries in map */ +#define WSKBDIO_MAXMAPLEN 65536 struct wscons_keymap *map; /* map to get or set */ }; #define WSKBDIO_GETMAP _IOWR('W', 13, struct wskbd_map_data) @@ -302,7 +303,8 @@ struct wsdisplay_font { #define WSDISPLAY_FONTENC_ISO 0 #define WSDISPLAY_FONTENC_IBM 1 #define WSDISPLAY_FONTENC_PCVT 2 - int fontwidth, fontheight, stride; + u_int fontwidth, fontheight, stride; +#define WSDISPLAY_MAXFONTSZ (512*1024) int bitorder, byteorder; #define WSDISPLAY_FONTORDER_KNOWN 0 /* i.e, no need to convert */ #define WSDISPLAY_FONTORDER_L2R 1 Index: dev/ccd.c =================================================================== RCS file: /cvsroot/syssrc/sys/dev/ccd.c,v retrieving revision 1.69.4.1 retrieving revision 1.69.4.2 diff -u -p -r1.69.4.1 -r1.69.4.2 --- ccd.c 2001/05/01 12:27:03 1.69.4.1 +++ ccd.c 2001/08/16 16:10:53 1.69.4.2 @@ -1017,6 +1017,11 @@ ccdioctl(dev, cmd, data, flag, p) goto out; } + if (ccio->ccio_ndisks > CCD_MAXNDISKS) { + error = EINVAL; + goto out; + } + /* Fill in some important bits. */ cs->sc_ileave = ccio->ccio_ileave; cs->sc_nccdisks = ccio->ccio_ndisks; Index: dev/ccdvar.h =================================================================== RCS file: /cvsroot/syssrc/sys/dev/ccdvar.h,v retrieving revision 1.19 retrieving revision 1.19.12.1 diff -u -p -r1.19 -r1.19.12.1 --- ccdvar.h 1999/08/11 02:44:35 1.19 +++ ccdvar.h 2001/08/16 16:10:53 1.19.12.1 @@ -95,7 +95,7 @@ */ struct ccd_ioctl { char **ccio_disks; /* pointer to component paths */ - int ccio_ndisks; /* number of disks to concatenate */ + u_int ccio_ndisks; /* number of disks to concatenate */ int ccio_ileave; /* interleave (DEV_BSIZE blocks) */ int ccio_flags; /* see sc_flags below */ int ccio_unit; /* unit number: use varies */ @@ -166,7 +166,8 @@ struct ccd_softc { int sc_flags; /* flags */ size_t sc_size; /* size of ccd */ int sc_ileave; /* interleave */ - int sc_nccdisks; /* number of components */ + u_int sc_nccdisks; /* number of components */ +#define CCD_MAXNDISKS 65536 struct ccdcinfo *sc_cinfo; /* component info */ struct ccdiinfo *sc_itable; /* interleave table */ struct ccdgeom sc_geom; /* pseudo geometry info */ Index: miscfs/umapfs/umap_vfsops.c =================================================================== RCS file: /cvsroot/syssrc/sys/miscfs/umapfs/umap_vfsops.c,v retrieving revision 1.25 retrieving revision 1.25.2.1 diff -u -p -r1.25 -r1.25.2.1 --- umap_vfsops.c 2000/06/10 18:27:04 1.25 +++ umap_vfsops.c 2001/08/16 16:03:44 1.25.2.1 @@ -146,6 +146,11 @@ umapfs_mount(mp, path, data, ndp, p) /* * Now copy in the number of entries and maps for umap mapping. */ + if (args.nentries > MAPFILEENTRIES || args.gnentries > GMAPFILEENTRIES) { + vput(lowerrootvp); + return (error); + } + amp->info_nentries = args.nentries; amp->info_gnentries = args.gnentries; error = copyin(args.mapdata, (caddr_t)amp->info_mapdata, Index: nfs/nfs.h =================================================================== RCS file: /cvsroot/syssrc/sys/nfs/nfs.h,v retrieving revision 1.22.2.2 retrieving revision 1.22.2.3 diff -u -p -r1.22.2.2 -r1.22.2.3 --- nfs.h 2001/04/06 00:37:13 1.22.2.2 +++ nfs.h 2001/08/16 16:03:46 1.22.2.3 @@ -193,9 +193,9 @@ struct nfsd_cargs { char *ncd_dirp; /* Mount dir path */ uid_t ncd_authuid; /* Effective uid */ int ncd_authtype; /* Type of authenticator */ - int ncd_authlen; /* Length of authenticator string */ + u_int ncd_authlen; /* Length of authenticator string */ u_char *ncd_authstr; /* Authenticator string */ - int ncd_verflen; /* and the verifier */ + u_int ncd_verflen; /* and the verifier */ u_char *ncd_verfstr; NFSKERBKEY_T ncd_key; /* Session key */ }; Index: kern/vfs_subr.c =================================================================== RCS file: /cvsroot/syssrc/sys/kern/vfs_subr.c,v retrieving revision 1.128.2.5 retrieving revision 1.128.2.6 diff -u -p -r1.128.2.5 -r1.128.2.6 --- vfs_subr.c 2000/12/14 23:36:02 1.128.2.5 +++ vfs_subr.c 2001/08/16 16:03:45 1.128.2.6 @@ -2012,6 +2012,10 @@ vfs_hang_addrlist(mp, nep, argp) mp->mnt_flag |= MNT_DEFEXPORTED; return (0); } + + if (argp->ex_addrlen > MLEN) + return (EINVAL); + i = sizeof(struct netcred) + argp->ex_addrlen + argp->ex_masklen; np = (struct netcred *)malloc(i, M_NETADDR, M_WAITOK); memset((caddr_t)np, 0, i); Index: kern/sysv_sem.c =================================================================== RCS file: /cvsroot/syssrc/sys/kern/sysv_sem.c,v retrieving revision 1.38 retrieving revision 1.38.2.1 diff -u -p -r1.38 -r1.38.2.1 --- sysv_sem.c 2000/06/02 15:53:05 1.38 +++ sysv_sem.c 2001/08/16 13:53:08 1.38.2.1 @@ -571,7 +571,7 @@ sys_semop(p, v, retval) syscallarg(size_t) nsops; } */ *uap = v; int semid = SCARG(uap, semid); - int nsops = SCARG(uap, nsops); + size_t nsops = SCARG(uap, nsops); struct sembuf sops[MAX_SOPS]; struct semid_ds *semaptr; struct sembuf *sopptr = NULL;