Index: sys/i386/linux/linprocfs/linprocfs_misc.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linprocfs/Attic/linprocfs_misc.c,v retrieving revision 1.3.2.8 diff -p -c -r1.3.2.8 linprocfs_misc.c *** sys/i386/linux/linprocfs/linprocfs_misc.c 25 Jun 2001 19:46:47 -0000 1.3.2.8 --- sys/i386/linux/linprocfs/linprocfs_misc.c 3 Oct 2003 12:39:55 -0000 *************** linprocfs_domeminfo(curp, p, pfs, uio) *** 85,91 **** struct uio *uio; { char *ps; - int xlen; char psbuf[512]; /* XXX - conservative */ unsigned long memtotal; /* total memory in bytes */ unsigned long memused; /* used memory in bytes */ --- 85,90 ---- *************** linprocfs_domeminfo(curp, p, pfs, uio) *** 156,166 **** B2K(memshared), B2K(buffers), B2K(cached), B2K(swaptotal), B2K(swapfree)); ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 155,161 ---- B2K(memshared), B2K(buffers), B2K(cached), B2K(swaptotal), B2K(swapfree)); ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } int *************** linprocfs_docpuinfo(curp, p, pfs, uio) *** 171,177 **** struct uio *uio; { char *ps; - int xlen; char psbuf[512]; /* XXX - conservative */ int class; int i; --- 166,171 ---- *************** linprocfs_docpuinfo(curp, p, pfs, uio) *** 248,259 **** (tsc_freq + 4999) / 1000000, ((tsc_freq + 4999) / 10000) % 100); } ! ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 242,248 ---- (tsc_freq + 4999) / 1000000, ((tsc_freq + 4999) / 10000) % 100); } ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } int *************** linprocfs_dostat(curp, p, pfs, uio) *** 265,271 **** { char *ps; char psbuf[512]; - int xlen; ps = psbuf; ps += sprintf(ps, --- 254,259 ---- *************** linprocfs_dostat(curp, p, pfs, uio) *** 287,297 **** cnt.v_intr, cnt.v_swtch, boottime.tv_sec); ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 275,281 ---- cnt.v_intr, cnt.v_swtch, boottime.tv_sec); ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } int *************** linprocfs_douptime(curp, p, pfs, uio) *** 302,308 **** struct uio *uio; { char *ps; - int xlen; char psbuf[64]; struct timeval tv; --- 286,291 ---- *************** linprocfs_douptime(curp, p, pfs, uio) *** 311,321 **** ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", tv.tv_sec, tv.tv_usec / 10000, T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 294,300 ---- ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", tv.tv_sec, tv.tv_usec / 10000, T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } int *************** linprocfs_doversion(curp, p, pfs, uio) *** 332,341 **** for (xlen = 0; ps[xlen] != '\n'; ++xlen) /* nothing */ ; ++xlen; ! xlen -= uio->uio_offset; ! ps += uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 311,317 ---- for (xlen = 0; ps[xlen] != '\n'; ++xlen) /* nothing */ ; ++xlen; ! return (uiomove_frombuf(ps, xlen, uio)); } int *************** linprocfs_doprocstat(curp, p, pfs, uio) *** 346,352 **** struct uio *uio; { char *ps, psbuf[1024]; - int xlen; ps = psbuf; ps += sprintf(ps, "%d", p->p_pid); --- 322,327 ---- *************** linprocfs_doprocstat(curp, p, pfs, uio) *** 388,398 **** #undef PS_ADD ps += sprintf(ps, "\n"); ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } /* --- 363,369 ---- #undef PS_ADD ps += sprintf(ps, "\n"); ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } /* *************** linprocfs_doprocstatus(curp, p, pfs, uio *** 419,425 **** { char *ps, psbuf[1024]; char *state; ! int i, xlen; ps = psbuf; --- 390,396 ---- { char *ps, psbuf[1024]; char *state; ! int i; ps = psbuf; *************** linprocfs_doprocstatus(curp, p, pfs, uio *** 490,500 **** PS_ADD(ps, "CapEff:\t%016x\n", 0); #undef PS_ADD ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } int --- 461,467 ---- PS_ADD(ps, "CapEff:\t%016x\n", 0); #undef PS_ADD ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } int *************** linprocfs_doloadavg(curp, p, pfs, uio) *** 504,511 **** struct pfsnode *pfs; struct uio *uio; { ! char *ps, psbuf[512]; ! int xlen; extern int nextpid; ps=psbuf; --- 471,477 ---- struct pfsnode *pfs; struct uio *uio; { ! char *ps, psbuf[512]; extern int nextpid; ps=psbuf; *************** linprocfs_doloadavg(curp, p, pfs, uio) *** 522,531 **** -1, /* number of tasks */ nextpid /* The last pid */ ); ! ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); } --- 488,492 ---- -1, /* number of tasks */ nextpid /* The last pid */ ); ! return (uiomove_frombuf(psbuf, ps - psbuf, uio)); } Index: sys/kern/kern_subr.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_subr.c,v retrieving revision 1.31.2.2 diff -p -c -r1.31.2.2 kern_subr.c *** sys/kern/kern_subr.c 21 Apr 2002 08:09:37 -0000 1.31.2.2 --- sys/kern/kern_subr.c 3 Oct 2003 12:39:55 -0000 *************** *** 47,52 **** --- 47,53 ---- #include #include #include + #include #include #include *************** uiomove(cp, n, uio) *** 117,122 **** --- 118,145 ---- if (curproc) curproc->p_flag = (curproc->p_flag & ~P_DEADLKTREAT) | save; return (error); + } + + /* + * Wrapper for uiomove() that validates the arguments against a known-good + * kernel buffer. Currently, uiomove accepts a signed (n) argument, which + * is almost definitely a bad thing, so we catch that here as well. We + * return a runtime failure, but it might be desirable to generate a runtime + * assertion failure instead. + */ + int + uiomove_frombuf(void *buf, int buflen, struct uio *uio) + { + unsigned int offset, n; + + if (uio->uio_offset < 0 || uio->uio_resid < 0 || + (offset = uio->uio_offset) != uio->uio_offset) + return (EINVAL); + if (buflen <= 0 || offset >= buflen) + return (0); + if ((n = buflen - offset) > INT_MAX) + return (EINVAL); + return (uiomove((char *)buf + offset, n, uio)); } int Index: sys/miscfs/procfs/procfs_dbregs.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/Attic/procfs_dbregs.c,v retrieving revision 1.4.2.3 diff -p -c -r1.4.2.3 procfs_dbregs.c *** sys/miscfs/procfs/procfs_dbregs.c 22 Jan 2002 17:22:59 -0000 1.4.2.3 --- sys/miscfs/procfs/procfs_dbregs.c 3 Oct 2003 12:39:55 -0000 *************** procfs_dodbregs(curp, p, pfs, uio) *** 59,88 **** { int error; struct dbreg r; - char *kv; - int kl; /* Can't trace a process that's currently exec'ing. */ if ((p->p_flag & P_INEXEC) != 0) return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return (EPERM); - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; PHOLD(p); ! ! if (kl < 0) ! error = EINVAL; ! else ! error = procfs_read_dbregs(p, &r); if (error == 0) ! error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; --- 59,75 ---- { int error; struct dbreg r; /* Can't trace a process that's currently exec'ing. */ if ((p->p_flag & P_INEXEC) != 0) return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return (EPERM); PHOLD(p); ! error = procfs_read_dbregs(p, &r); if (error == 0) ! error = uiomove_frombuf(&r, sizeof(r), uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; Index: sys/miscfs/procfs/procfs_fpregs.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/Attic/procfs_fpregs.c,v retrieving revision 1.11.2.3 diff -p -c -r1.11.2.3 procfs_fpregs.c *** sys/miscfs/procfs/procfs_fpregs.c 22 Jan 2002 17:22:59 -0000 1.11.2.3 --- sys/miscfs/procfs/procfs_fpregs.c 3 Oct 2003 12:39:55 -0000 *************** procfs_dofpregs(curp, p, pfs, uio) *** 56,85 **** { int error; struct fpreg r; - char *kv; - int kl; /* Can't trace a process that's currently exec'ing. */ if ((p->p_flag & P_INEXEC) != 0) return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return EPERM; - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; PHOLD(p); ! if (kl < 0) ! error = EINVAL; ! else ! error = procfs_read_fpregs(p, &r); if (error == 0) ! error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; --- 56,73 ---- { int error; struct fpreg r; /* Can't trace a process that's currently exec'ing. */ if ((p->p_flag & P_INEXEC) != 0) return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return EPERM; PHOLD(p); ! error = procfs_read_fpregs(p, &r); if (error == 0) ! error = uiomove_frombuf(&r, sizeof(r), uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; Index: sys/miscfs/procfs/procfs_regs.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/Attic/procfs_regs.c,v retrieving revision 1.10.2.3 diff -p -c -r1.10.2.3 procfs_regs.c *** sys/miscfs/procfs/procfs_regs.c 22 Jan 2002 17:22:59 -0000 1.10.2.3 --- sys/miscfs/procfs/procfs_regs.c 3 Oct 2003 12:39:55 -0000 *************** procfs_doregs(curp, p, pfs, uio) *** 65,86 **** return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return EPERM; - kl = sizeof(r); - kv = (char *) &r; - - kv += uio->uio_offset; - kl -= uio->uio_offset; - if (kl > uio->uio_resid) - kl = uio->uio_resid; PHOLD(p); ! if (kl < 0) ! error = EINVAL; ! else ! error = procfs_read_regs(p, &r); if (error == 0) ! error = uiomove(kv, kl, uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; --- 65,76 ---- return EAGAIN; if (!CHECKIO(curp, p) || p_trespass(curp, p)) return EPERM; PHOLD(p); ! error = procfs_read_regs(p, &r); if (error == 0) ! error = uiomove_frombuf(&r, sizeof(r), uio); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (p->p_stat != SSTOP) error = EBUSY; Index: sys/miscfs/procfs/procfs_rlimit.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/Attic/procfs_rlimit.c,v retrieving revision 1.5 diff -p -c -r1.5 procfs_rlimit.c *** sys/miscfs/procfs/procfs_rlimit.c 8 Dec 1999 08:59:37 -0000 1.5 --- sys/miscfs/procfs/procfs_rlimit.c 3 Oct 2003 12:39:55 -0000 *************** procfs_dorlimit(curp, p, pfs, uio) *** 64,70 **** { char *ps; int i; - int xlen; int error; char psbuf[512]; /* XXX - conservative */ --- 64,69 ---- *************** procfs_dorlimit(curp, p, pfs, uio) *** 109,128 **** } } ! /* ! * This logic is rather tasty - but its from procfs_status.c, so ! * I guess I'll use it here. ! */ ! ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! if (xlen <= 0) ! error = 0; ! else ! error = uiomove(ps, xlen, uio); ! return (error); } --- 108,114 ---- } } ! error = uiomove_frombuf(psbuf, ps - psbuf, uio); return (error); } Index: sys/miscfs/procfs/procfs_status.c =================================================================== RCS file: /home/ncvs/src/sys/miscfs/procfs/Attic/procfs_status.c,v retrieving revision 1.20.2.4 diff -p -c -r1.20.2.4 procfs_status.c *** sys/miscfs/procfs/procfs_status.c 22 Jan 2002 17:22:59 -0000 1.20.2.4 --- sys/miscfs/procfs/procfs_status.c 3 Oct 2003 12:39:55 -0000 *************** procfs_dostatus(curp, p, pfs, uio) *** 166,180 **** ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n"); DOCHECK(); ! xlen = ps - psbuf; ! xlen -= uio->uio_offset; ! ps = psbuf + uio->uio_offset; ! xlen = imin(xlen, uio->uio_resid); ! if (xlen <= 0) ! error = 0; ! else ! error = uiomove(ps, xlen, uio); ! return (error); bailout: --- 166,172 ---- ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n"); DOCHECK(); ! error = uiomove_frombuf(psbuf, ps - psbuf, uio); return (error); bailout: *************** procfs_docmdline(curp, p, pfs, uio) *** 246,258 **** buflen = ps - buf; } ! buflen -= uio->uio_offset; ! ps = bp + uio->uio_offset; ! xlen = min(buflen, uio->uio_resid); ! if (xlen <= 0) ! error = 0; ! else ! error = uiomove(ps, xlen, uio); if (buf) FREE(buf, M_TEMP); return (error); --- 238,244 ---- buflen = ps - buf; } ! error = uiomove_frombuf(bp, buflen, uio); if (buf) FREE(buf, M_TEMP); return (error); Index: sys/sys/uio.h =================================================================== RCS file: /home/ncvs/src/sys/sys/uio.h,v retrieving revision 1.11.2.1 diff -p -c -r1.11.2.1 uio.h *** sys/sys/uio.h 28 Sep 2001 16:58:35 -0000 1.11.2.1 --- sys/sys/uio.h 3 Oct 2003 12:39:55 -0000 *************** struct vm_object; *** 78,83 **** --- 78,84 ---- void uio_yield __P((void)); int uiomove __P((caddr_t, int, struct uio *)); + int uiomove_frombuf __P((void *buf, int buflen, struct uio *uio)); int uiomoveco __P((caddr_t, int, struct uio *, struct vm_object *)); int uioread __P((int, struct uio *, struct vm_object *, int *));