Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 03 Jul 2011 14:07:04 +0000
From:      gk@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r223909 - in soc2011/gk/ino64-head/sys/fs: cd9660 devfs ext2fs udf
Message-ID:  <20110703140704.B47BF1065687@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gk
Date: Sun Jul  3 14:07:04 2011
New Revision: 223909
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223909

Log:
  In VOP_READDIR return EINVAL if buffer is too small for first entry

Modified:
  soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c
  soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c
  soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c
  soc2011/gk/ino64-head/sys/fs/udf/udf_vnops.c

Modified: soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c
==============================================================================
--- soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c	Sun Jul  3 14:06:46 2011	(r223908)
+++ soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c	Sun Jul  3 14:07:04 2011	(r223909)
@@ -367,6 +367,7 @@
 	off_t curroff;
 	struct uio *uio;
 	off_t uio_off;
+	ssize_t startresid;
 	int eofflag;
 };
 
@@ -384,6 +385,8 @@
 
 	if (idp->uio->uio_resid < dp->d_reclen) {
 		idp->eofflag = 0;
+		if (idp->uio->uio_resid == idp->startresid)
+			return (EINVAL);
 		return (-1);
 	}
 
@@ -486,6 +489,7 @@
 	idp->eofflag = 1;
 	idp->curroff = uio->uio_offset;
 	idp->uio_off = uio->uio_offset;
+	idp->startresid = uio->uio_resid;
 
 	if ((entryoffsetinblock = idp->curroff & bmask) &&
 	    (error = cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp))) {

Modified: soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c	Sun Jul  3 14:06:46 2011	(r223908)
+++ soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c	Sun Jul  3 14:07:04 2011	(r223909)
@@ -1171,6 +1171,7 @@
 	struct devfs_dirent *de;
 	struct devfs_mount *dmp;
 	off_t off;
+	ssize_t startresid;
 
 	if (ap->a_vp->v_type != VDIR)
 		return (ENOTDIR);
@@ -1185,6 +1186,7 @@
 	error = 0;
 	de = ap->a_vp->v_data;
 	off = 0;
+	startresid = uio->uio_resid;
 	TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
 		KASSERT(dd->de_cdp != (void *)0xdeadc0de, ("%s %d\n", __func__, __LINE__));
 		if (dd->de_flags & (DE_COVERED | DE_WHITEOUT))
@@ -1201,8 +1203,12 @@
 		if (off >= uio->uio_offset) {
 			error = vfs_read_dirent(ap, dp);
 			if (error != 0) {
-				if (error < 0)
-					error = 0;
+				if (error < 0) {
+					if (uio->uio_resid == startresid)
+						error = EINVAL;
+					else
+						error = 0;
+				}
 				break;
 			}
 		}

Modified: soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c
==============================================================================
--- soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c	Sun Jul  3 14:06:46 2011	(r223908)
+++ soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c	Sun Jul  3 14:07:04 2011	(r223909)
@@ -201,15 +201,17 @@
 			dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp);
 			dstdp.d_off = offset + dp->e2d_reclen;
 			bcopy(dp->e2d_name, dstdp.d_name, dstdp.d_namlen);
-			bzero(dstdp.d_name + dstdp.d_namlen,
-			    dstdp.d_reclen - offsetof(struct dirent, d_name) -
-			    dstdp.d_namlen);
+			dstdp.d_name[dstdp.d_namlen] = '\0';
 
 			if (dp->e2d_reclen > 0) {
 				error = vfs_read_dirent(ap, &dstdp);
 				if (error != 0) {
-					if (error < 0)
-						error = 0;
+					if (error < 0) {
+						if (offset == startoffset)
+							error = EINVAL;
+						else
+							error = 0;
+					}
 					break;
 				}
 				/* advance dp */

Modified: soc2011/gk/ino64-head/sys/fs/udf/udf_vnops.c
==============================================================================
--- soc2011/gk/ino64-head/sys/fs/udf/udf_vnops.c	Sun Jul  3 14:06:46 2011	(r223908)
+++ soc2011/gk/ino64-head/sys/fs/udf/udf_vnops.c	Sun Jul  3 14:07:04 2011	(r223909)
@@ -744,6 +744,7 @@
 	struct udf_mnt *udfmp;
 	struct fileid_desc *fid;
 	struct udf_dirstream *ds;
+	ssize_t startresid;
 	int error = 0;
 	int dotoff = 0;
 
@@ -755,6 +756,7 @@
 	if (a->a_eofflag != NULL)
 		*a->a_eofflag = 1;	/* reset by vfs_read_dirent */
 
+	startresid = uio->uio_resid;
 	if (uio->uio_offset == 1 || uio->uio_offset == 2) {
 		dotoff = uio->uio_offset;
 		uio->uio_offset = 0;
@@ -826,8 +828,12 @@
 		uio->uio_offset = dir.d_off;
 	}
 
-	if (error < 0)
-		error = 0;
+	if (error < 0) {
+		if (uio->uio_resid == startresid)
+			error = EINVAL;
+		else
+			error = 0;
+	}
 	if (!error)
 		error = ds->error;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110703140704.B47BF1065687>