From 21379a643b17a4036c71d1ef4fc1dc1b7da3df41 Mon Sep 17 00:00:00 2001 From: bp Date: Sat, 8 Jan 2000 10:45:54 +0000 Subject: Treat negative uio_offset value as eof (idea by: bde). Prevent overflows by casting uio_offset to uoff_t. Return correct error number if directory entry is broken. Reviewed by: bde --- sys/fs/msdosfs/msdosfs_vnops.c | 19 +++++++++++-------- sys/msdosfs/msdosfs_vnops.c | 19 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 15e8578..5ce4990 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -566,8 +566,8 @@ msdosfs_read(ap) if (uio->uio_offset < 0) return (EINVAL); - if (uio->uio_offset > DOS_FILESIZE_MAX) - return (EFBIG); + if ((uoff_t)uio->uio_offset > DOS_FILESIZE_MAX) + return (0); /* * If they didn't ask for any data, then we are done. */ @@ -590,7 +590,10 @@ msdosfs_read(ap) if (isadir) { /* convert cluster # to block # */ error = pcbmap(dep, lbn, &lbn, 0, &blsize); - if (error) + if (error == E2BIG) { + error = EINVAL; + break; + } else if (error) break; error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp); } else { @@ -676,24 +679,24 @@ msdosfs_write(ap) } if (uio->uio_offset < 0) - return (EINVAL); + return (EFBIG); if (uio->uio_resid == 0) return (0); - if (uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX) - return (EFBIG); - /* * If they've exceeded their filesize limit, tell them about it. */ if (p && - ((uio->uio_offset + uio->uio_resid) > + ((uoff_t)uio->uio_offset + uio->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) { psignal(p, SIGXFSZ); return (EFBIG); } + if ((uoff_t)uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX) + return (EFBIG); + /* * If the offset we are starting the write at is beyond the end of * the file, then they've done a seek. Unix filesystems allow diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 15e8578..5ce4990 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -566,8 +566,8 @@ msdosfs_read(ap) if (uio->uio_offset < 0) return (EINVAL); - if (uio->uio_offset > DOS_FILESIZE_MAX) - return (EFBIG); + if ((uoff_t)uio->uio_offset > DOS_FILESIZE_MAX) + return (0); /* * If they didn't ask for any data, then we are done. */ @@ -590,7 +590,10 @@ msdosfs_read(ap) if (isadir) { /* convert cluster # to block # */ error = pcbmap(dep, lbn, &lbn, 0, &blsize); - if (error) + if (error == E2BIG) { + error = EINVAL; + break; + } else if (error) break; error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp); } else { @@ -676,24 +679,24 @@ msdosfs_write(ap) } if (uio->uio_offset < 0) - return (EINVAL); + return (EFBIG); if (uio->uio_resid == 0) return (0); - if (uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX) - return (EFBIG); - /* * If they've exceeded their filesize limit, tell them about it. */ if (p && - ((uio->uio_offset + uio->uio_resid) > + ((uoff_t)uio->uio_offset + uio->uio_resid > p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) { psignal(p, SIGXFSZ); return (EFBIG); } + if ((uoff_t)uio->uio_offset + uio->uio_resid > DOS_FILESIZE_MAX) + return (EFBIG); + /* * If the offset we are starting the write at is beyond the end of * the file, then they've done a seek. Unix filesystems allow -- cgit v1.1