Page MenuHomeFreeBSD

D24596.1775587242.diff
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

D24596.1775587242.diff

Index: lib/libc/sys/read.2
===================================================================
--- lib/libc/sys/read.2
+++ lib/libc/sys/read.2
@@ -28,7 +28,7 @@
.\" @(#)read.2 8.4 (Berkeley) 2/26/94
.\" $FreeBSD$
.\"
-.Dd March 30, 2020
+.Dd May 13, 2020
.Dt READ 2
.Os
.Sh NAME
@@ -199,9 +199,10 @@
The file was marked for non-blocking I/O,
and no data were ready to be read.
.It Bq Er EISDIR
-The file descriptor is associated with a directory residing
-on a file system that does not allow regular read operations on
-directories (e.g.\& NFS).
+The file descriptor is associated with a directory.
+The
+.Xr readdir 3
+function should be used instead.
.It Bq Er EOPNOTSUPP
The file descriptor is associated with a file system and file type that
do not allow regular read operations on it.
Index: sys/fs/ext2fs/ext2_vnops.c
===================================================================
--- sys/fs/ext2fs/ext2_vnops.c
+++ sys/fs/ext2fs/ext2_vnops.c
@@ -2073,7 +2073,7 @@
if (vp->v_type == VLNK) {
if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen)
panic("%s: short symlink", "ext2_read");
- } else if (vp->v_type != VREG && vp->v_type != VDIR)
+ } else if (vp->v_type != VREG)
panic("%s: type %d", "ext2_read", vp->v_type);
#endif
orig_resid = uio->uio_resid;
Index: sys/fs/msdosfs/msdosfs_vnops.c
===================================================================
--- sys/fs/msdosfs/msdosfs_vnops.c
+++ sys/fs/msdosfs/msdosfs_vnops.c
@@ -520,7 +520,6 @@
{
int error = 0;
int blsize;
- int isadir;
ssize_t orig_resid;
u_int n;
u_long diff;
@@ -535,6 +534,18 @@
struct msdosfsmount *pmp = dep->de_pmp;
struct uio *uio = ap->a_uio;
+ /*
+ * This check duplicates a similar check on the vnode that occurs up in
+ * the VFS layer, but it's perhaps necessary. msdosfs, in particular,
+ * are often read from untrusted sources or synthesized on the fly, so
+ * it does not hurt to ensure that the metadata here is consistent with
+ * our assumption having entered msdosfs_read. This may not be
+ * exceptional, so we reject it with an appropriate error rather than
+ * asserting it or panicking.
+ */
+ if ((dep->de_Attributes & ATTR_DIRECTORY) != 0)
+ return (EISDIR);
+
/*
* If they didn't ask for any data, then we are done.
*/
@@ -552,7 +563,6 @@
seqcount = ap->a_ioflag >> IO_SEQSHIFT;
- isadir = dep->de_Attributes & ATTR_DIRECTORY;
do {
if (uio->uio_offset >= dep->de_FileSize)
break;
@@ -560,21 +570,7 @@
rablock = lbn + 1;
blsize = pmp->pm_bpcluster;
on = uio->uio_offset & pmp->pm_crbomask;
- /*
- * If we are operating on a directory file then be sure to
- * do i/o with the vnode for the filesystem instead of the
- * vnode for the directory.
- */
- if (isadir) {
- /* convert cluster # to block # */
- error = pcbmap(dep, lbn, &lbn, 0, &blsize);
- if (error == E2BIG) {
- error = EINVAL;
- break;
- } else if (error)
- break;
- error = bread(pmp->pm_devvp, lbn, blsize, NOCRED, &bp);
- } else if (de_cn2off(pmp, rablock) >= dep->de_FileSize) {
+ if (de_cn2off(pmp, rablock) >= dep->de_FileSize) {
error = bread(vp, lbn, blsize, NOCRED, &bp);
} else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
error = cluster_read(vp, dep->de_FileSize, lbn, blsize,
@@ -601,7 +597,7 @@
error = vn_io_fault_uiomove(bp->b_data + on, (int) n, uio);
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
- if (!isadir && (error == 0 || uio->uio_resid != orig_resid) &&
+ if ((error == 0 || uio->uio_resid != orig_resid) &&
(vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
dep->de_flag |= DE_ACCESS;
return (error);
Index: sys/fs/smbfs/smbfs_vnops.c
===================================================================
--- sys/fs/smbfs/smbfs_vnops.c
+++ sys/fs/smbfs/smbfs_vnops.c
@@ -502,7 +502,7 @@
struct uio *uio = ap->a_uio;
SMBVDEBUG("\n");
- if (vp->v_type != VREG && vp->v_type != VDIR)
+ if (vp->v_type != VREG)
return EPERM;
return smbfs_readvnode(vp, uio, ap->a_cred);
}
Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c
+++ sys/kern/vfs_vnops.c
@@ -1160,6 +1160,15 @@
doio = uio->uio_rw == UIO_READ ? vn_read : vn_write;
vp = fp->f_vnode;
+
+ /*
+ * Checked here as the entry for fo_read calls. We could restrict this
+ * to uio->uio_rw == UIO_READ, but attempts to open() a dirfd writable
+ * will be rejected with EISDIR in vn_open_vnode(). Thus, we won't
+ * see it.
+ */
+ if (vp->v_type == VDIR)
+ return (EISDIR);
foffset_lock_uio(fp, uio, flags);
if (do_vn_io_fault(vp, uio)) {
args.kind = VN_IO_FAULT_FOP;
Index: sys/ufs/ffs/ffs_vnops.c
===================================================================
--- sys/ufs/ffs/ffs_vnops.c
+++ sys/ufs/ffs/ffs_vnops.c
@@ -566,7 +566,7 @@
if (vp->v_type == VLNK) {
if ((int)ip->i_size < vp->v_mount->mnt_maxsymlinklen)
panic("ffs_read: short symlink");
- } else if (vp->v_type != VREG && vp->v_type != VDIR)
+ } else if (vp->v_type != VREG)
panic("ffs_read: type %d", vp->v_type);
#endif
orig_resid = uio->uio_resid;

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 6:40 PM (9 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28296229
Default Alt Text
D24596.1775587242.diff (5 KB)

Event Timeline