Module Name:    src
Committed By:   jdolecek
Date:           Fri Aug 19 00:05:43 UTC 2016

Modified Files:
        src/sys/ufs/ext2fs: ext2fs_extern.h ext2fs_htree.c ext2fs_lookup.c

Log Message:
fix bug introduced in rev 1.82 of ext2fs_lookup.c, when ext2fs_add_entry()
was introduced splitting code from ext2fs_direnter() - code used
incorrect new entry size, leading to incomplete entry copy or buffer
overflow; fixed by passing the right size from ext2fs_direnter()


To generate a diff of this commit:
cvs rdiff -u -r1.53 -r1.54 src/sys/ufs/ext2fs/ext2fs_extern.h
cvs rdiff -u -r1.6 -r1.7 src/sys/ufs/ext2fs/ext2fs_htree.c
cvs rdiff -u -r1.86 -r1.87 src/sys/ufs/ext2fs/ext2fs_lookup.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ext2fs/ext2fs_extern.h
diff -u src/sys/ufs/ext2fs/ext2fs_extern.h:1.53 src/sys/ufs/ext2fs/ext2fs_extern.h:1.54
--- src/sys/ufs/ext2fs/ext2fs_extern.h:1.53	Mon Aug 15 18:29:34 2016
+++ src/sys/ufs/ext2fs/ext2fs_extern.h	Fri Aug 19 00:05:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_extern.h,v 1.53 2016/08/15 18:29:34 jdolecek Exp $	*/
+/*	$NetBSD: ext2fs_extern.h,v 1.54 2016/08/19 00:05:43 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993, 1994
@@ -134,7 +134,7 @@ int ext2fs_dirrewrite(struct inode *, co
 			   struct inode *, struct componentname *);
 int ext2fs_dirempty(struct inode *, ino_t, kauth_cred_t);
 int ext2fs_add_entry(struct vnode *, struct ext2fs_direct *,
-    const struct ufs_lookup_results *); 
+    const struct ufs_lookup_results *, size_t); 
 
 /* ext2fs_subr.c */
 int ext2fs_blkatoff(struct vnode *, off_t, char **, struct buf **);
@@ -190,7 +190,7 @@ int ext2fs_htree_lookup(struct inode *, 
 int ext2fs_htree_create_index(struct vnode *, struct componentname *,
     struct ext2fs_direct *);
 int ext2fs_htree_add_entry(struct vnode *, struct ext2fs_direct *,
-    struct componentname *);
+    struct componentname *, size_t);
 
 __END_DECLS
 

Index: src/sys/ufs/ext2fs/ext2fs_htree.c
diff -u src/sys/ufs/ext2fs/ext2fs_htree.c:1.6 src/sys/ufs/ext2fs/ext2fs_htree.c:1.7
--- src/sys/ufs/ext2fs/ext2fs_htree.c:1.6	Sun Aug 14 11:42:50 2016
+++ src/sys/ufs/ext2fs/ext2fs_htree.c	Fri Aug 19 00:05:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_htree.c,v 1.6 2016/08/14 11:42:50 jdolecek Exp $	*/
+/*	$NetBSD: ext2fs_htree.c,v 1.7 2016/08/19 00:05:43 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 2010, 2012 Zheng Liu <l...@freebsd.org>
@@ -29,7 +29,7 @@
  * $FreeBSD: head/sys/fs/ext2fs/ext2fs_htree.c 294653 2016-01-24 02:41:49Z pfg $
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_htree.c,v 1.6 2016/08/14 11:42:50 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_htree.c,v 1.7 2016/08/19 00:05:43 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -480,7 +480,7 @@ out1:
  */
 int
 ext2fs_htree_add_entry(struct vnode *dvp, struct ext2fs_direct *entry,
-    struct componentname *cnp)
+    struct componentname *cnp, size_t newentrysize)
 {
 	struct ext2fs_htree_entry *entries, *leaf_node;
 	struct ext2fs_htree_lookup_info info;
@@ -507,7 +507,8 @@ ext2fs_htree_add_entry(struct vnode *dvp
 	blksize = m_fs->e2fs_bsize;
 
 	if (ip->i_crap.ulr_count != 0) 
-		return ext2fs_add_entry(dvp, entry, &(ip->i_crap));
+		return ext2fs_add_entry(dvp, entry, &(ip->i_crap), newentrysize);
+
 	/* Target directory block is full, split it */
 	memset(&info, 0, sizeof(info));
 	error = ext2fs_htree_find_leaf(ip, entry->e2d_name, entry->e2d_namlen,

Index: src/sys/ufs/ext2fs/ext2fs_lookup.c
diff -u src/sys/ufs/ext2fs/ext2fs_lookup.c:1.86 src/sys/ufs/ext2fs/ext2fs_lookup.c:1.87
--- src/sys/ufs/ext2fs/ext2fs_lookup.c:1.86	Sun Aug 14 11:46:05 2016
+++ src/sys/ufs/ext2fs/ext2fs_lookup.c	Fri Aug 19 00:05:43 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_lookup.c,v 1.86 2016/08/14 11:46:05 jdolecek Exp $	*/
+/*	$NetBSD: ext2fs_lookup.c,v 1.87 2016/08/19 00:05:43 jdolecek Exp $	*/
 
 /*
  * Modified for NetBSD 1.2E
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.86 2016/08/14 11:46:05 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.87 2016/08/19 00:05:43 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -839,10 +839,8 @@ ext2fs_dirbadentry(struct vnode *dp, str
 
 	if (reclen < EXT2FS_DIRSIZ(1)) /* e2d_namlen = 1 */
 		error_msg = "rec_len is smaller than minimal";
-#if 0
 	else if (reclen % 4 != 0)
 		error_msg = "rec_len % 4 != 0";
-#endif
 	else if (namlen > EXT2FS_MAXNAMLEN)
 		error_msg = "namlen > EXT2FS_MAXNAMLEN";
 	else if (reclen < EXT2FS_DIRSIZ(namlen))
@@ -880,9 +878,10 @@ ext2fs_direnter(struct inode *ip, struct
 	struct ext2fs_direct newdir;
 	struct iovec aiov;
 	struct uio auio;
-	int error, newentrysize;
+	int error;
 	struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
 	int dirblksiz = ump->um_dirblksiz;
+	size_t newentrysize;
 
 	dp = VTOI(dvp);
 
@@ -895,11 +894,11 @@ ext2fs_direnter(struct inode *ip, struct
 	}
 	memcpy(newdir.e2d_name, cnp->cn_nameptr, (unsigned)cnp->cn_namelen + 1);
 	newentrysize = EXT2FS_DIRSIZ(cnp->cn_namelen);
-	
+
 	if (ext2fs_htree_has_idx(dp)) {
-		error = ext2fs_htree_add_entry(dvp, &newdir, cnp);
+		error = ext2fs_htree_add_entry(dvp, &newdir, cnp, newentrysize);
 		if (error) {
-			dp->i_e2fs_flags&= ~EXT2_INDEX;
+			dp->i_e2fs_flags &= ~EXT2_INDEX;
 			dp->i_flag |= IN_CHANGE | IN_UPDATE;
 		}
 		return error;
@@ -942,7 +941,7 @@ ext2fs_direnter(struct inode *ip, struct
 		return error;
 	}
 
-	error = ext2fs_add_entry(dvp, &newdir, ulr);
+	error = ext2fs_add_entry(dvp, &newdir, ulr, newentrysize);
 	
 	if (!error && ulr->ulr_endoff && ulr->ulr_endoff < ext2fs_size(dp))
 		error = ext2fs_truncate(dvp, (off_t)ulr->ulr_endoff, IO_SYNC,
@@ -956,14 +955,14 @@ ext2fs_direnter(struct inode *ip, struct
  */
 
 int
-ext2fs_add_entry (struct vnode* dvp, struct ext2fs_direct *entry,
-    const struct ufs_lookup_results *ulr) 
+ext2fs_add_entry(struct vnode* dvp, struct ext2fs_direct *entry,
+    const struct ufs_lookup_results *ulr, size_t newentrysize) 
 {	
 	struct ext2fs_direct *ep, *nep;
 	struct inode *dp;
 	struct buf *bp;
 	u_int dsize;
-	int error, loc, newentrysize, spacefree;
+	int error, loc, spacefree;
 	char *dirbuf;
 
 	dp = VTOI(dvp);
@@ -990,7 +989,7 @@ ext2fs_add_entry (struct vnode* dvp, str
 	 * space.
 	 */
 	ep = (struct ext2fs_direct *)dirbuf;
-	newentrysize = dsize = EXT2FS_DIRSIZ(ep->e2d_namlen);
+	dsize = EXT2FS_DIRSIZ(ep->e2d_namlen);
 	spacefree = fs2h16(ep->e2d_reclen) - dsize;
 	for (loc = fs2h16(ep->e2d_reclen); loc < ulr->ulr_count;) {
 		nep = (struct ext2fs_direct *)(dirbuf + loc);

Reply via email to