summaryrefslogtreecommitdiffstats
path: root/sys/miscfs/fdesc
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1998-06-14 08:46:41 +0000
committerbde <bde@FreeBSD.org>1998-06-14 08:46:41 +0000
commitcc3e00bf7a256405c793961d149b36ca8d09e57a (patch)
treec3e8512acea8183c9aa7c311a0234ddd6a18c037 /sys/miscfs/fdesc
parent6b90b71a8e744a5203ee6958133be30871b0bb5e (diff)
downloadFreeBSD-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/miscfs/fdesc')
-rw-r--r--sys/miscfs/fdesc/fdesc_vnops.c41
1 files changed, 14 insertions, 27 deletions
diff --git a/sys/miscfs/fdesc/fdesc_vnops.c b/sys/miscfs/fdesc/fdesc_vnops.c
index 00ffcb5..a8ec176 100644
--- a/sys/miscfs/fdesc/fdesc_vnops.c
+++ b/sys/miscfs/fdesc/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;
OpenPOWER on IntegriCloud