diff options
author | bde <bde@FreeBSD.org> | 1998-06-14 08:46:41 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1998-06-14 08:46:41 +0000 |
commit | cc3e00bf7a256405c793961d149b36ca8d09e57a (patch) | |
tree | c3e8512acea8183c9aa7c311a0234ddd6a18c037 /sys/fs/fdescfs | |
parent | 6b90b71a8e744a5203ee6958133be30871b0bb5e (diff) | |
download | FreeBSD-src-cc3e00bf7a256405c793961d149b36ca8d09e57a.zip FreeBSD-src-cc3e00bf7a256405c793961d149b36ca8d09e57a.tar.gz |
Avoid a 64-bit division in fdesc_readdir(). Fixed related overflows
and missing arg checking.
Panic instead of returning bogus error codes or forgetting to check
all cases if fdesc_readdir() gets called for a non-directory. This
can't happen.
Diffstat (limited to 'sys/fs/fdescfs')
-rw-r--r-- | sys/fs/fdescfs/fdesc_vnops.c | 41 |
1 files changed, 14 insertions, 27 deletions
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 00ffcb5..a8ec176 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -35,7 +35,7 @@ * * @(#)fdesc_vnops.c 8.9 (Berkeley) 1/21/94 * - * $Id: fdesc_vnops.c,v 1.36 1998/06/10 19:56:06 alex Exp $ + * $Id: fdesc_vnops.c,v 1.37 1998/06/10 21:21:28 dfr Exp $ */ /* @@ -564,7 +564,6 @@ static struct dirtmp { { FD_STDOUT, UIO_MX, 6, "stdout" }, { FD_STDERR, UIO_MX, 6, "stderr" }, { FD_CTTY, UIO_MX, 3, "tty" }, - { 0 } }; static int @@ -580,8 +579,7 @@ fdesc_readdir(ap) { struct uio *uio = ap->a_uio; struct filedesc *fdp; - int i; - int error; + int error, i, off; /* * We don't allow exporting fdesc mounts, and currently local @@ -590,17 +588,15 @@ fdesc_readdir(ap) if (ap->a_ncookies) panic("fdesc_readdir: not hungry"); - switch (VTOFDESC(ap->a_vp)->fd_type) { - case Fctty: - return (0); - - case Fdesc: - return (ENOTDIR); - - default: - break; - } + if (VTOFDESC(ap->a_vp)->fd_type != Froot && + VTOFDESC(ap->a_vp)->fd_type != Fdevfd) + panic("fdesc_readdir: not dir"); + off = (int)uio->uio_offset; + if (off != uio->uio_offset || off < 0 || (u_int)off % UIO_MX != 0 || + uio->uio_resid < UIO_MX) + return (EINVAL); + i = (u_int)off / UIO_MX; fdp = uio->uio_procp->p_fd; if (VTOFDESC(ap->a_vp)->fd_type == Froot) { @@ -608,17 +604,11 @@ fdesc_readdir(ap) struct dirent *dp = &d; struct dirtmp *dt; - i = uio->uio_offset / UIO_MX; error = 0; - while (uio->uio_resid > 0) { + while (i < sizeof(rootent) / sizeof(rootent[0]) && + uio->uio_resid >= UIO_MX) { dt = &rootent[i]; - if (dt->d_fileno == 0) { - /**eofflagp = 1;*/ - break; - } - i++; - switch (dt->d_fileno) { case FD_CTTY: if (cttyvp(uio->uio_procp) == NULL) @@ -643,17 +633,14 @@ fdesc_readdir(ap) error = uiomove((caddr_t) dp, UIO_MX, uio); if (error) break; + i++; } uio->uio_offset = i * UIO_MX; return (error); } - i = uio->uio_offset / UIO_MX; error = 0; - while (uio->uio_resid > 0) { - if (i >= fdp->fd_nfiles) - break; - + while (i < fdp->fd_nfiles && uio->uio_resid >= UIO_MX) { if (fdp->fd_ofiles[i] != NULL) { struct dirent d; struct dirent *dp = &d; |