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);