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()
This commit is contained in:
parent
fbe5805edc
commit
39cc5f5a3f
|
@ -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 *, const struct ufs_lookup_results *,
|
|||
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 *, const char *, int, struct buf **,
|
|||
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
|
||||
|
||||
|
|
|
@ -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 <lz@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, struct ext2fs_direct *entry,
|
|||
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,
|
||||
|
|
|
@ -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, struct ext2fs_direct *de,
|
|||
|
||||
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 vnode *dvp,
|
|||
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 vnode *dvp,
|
|||
}
|
||||
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 vnode *dvp,
|
|||
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 vnode *dvp,
|
|||
*/
|
||||
|
||||
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, struct ext2fs_direct *entry,
|
|||
* 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);
|
||||
|
|
Loading…
Reference in New Issue