Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/fs/tmpfs/tmpfs_vnops.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.53.2.2 retrieving revision 1.54 diff -u -p -r1.53.2.2 -r1.54 --- src/sys/fs/tmpfs/tmpfs_vnops.c 2009/07/23 23:32:33 1.53.2.2 +++ src/sys/fs/tmpfs/tmpfs_vnops.c 2009/03/19 13:47:32 1.54 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.53.2.2 2009/07/23 23:32:33 jym Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.54 2009/03/19 13:47:32 pooka Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.53.2.2 2009/07/23 23:32:33 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.54 2009/03/19 13:47:32 pooka Exp $"); #include #include @@ -54,7 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops. #include #include -#include #include #include @@ -205,7 +204,9 @@ tmpfs_lookup(void *v) goto out; } - /* Check permissions */ + /* If we are deleting or renaming the entry, keep + * track of its tmpfs_dirent so that it can be + * easily deleted later. */ if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { @@ -218,7 +219,6 @@ tmpfs_lookup(void *v) error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred); if (error != 0) goto out; - cnp->cn_flags |= SAVENAME; } else de = NULL; @@ -337,10 +337,19 @@ tmpfs_close(void *v) /* --------------------------------------------------------------------- */ -static int -tmpfs_check_possible(struct vnode *vp, struct tmpfs_node *node, mode_t mode) +int +tmpfs_access(void *v) { - int error = 0; + struct vnode *vp = ((struct vop_access_args *)v)->a_vp; + int mode = ((struct vop_access_args *)v)->a_mode; + kauth_cred_t cred = ((struct vop_access_args *)v)->a_cred; + + int error; + struct tmpfs_node *node; + + KASSERT(VOP_ISLOCKED(vp)); + + node = VP_TO_TMPFS_NODE(vp); switch (vp->v_type) { case VDIR: @@ -373,38 +382,8 @@ tmpfs_check_possible(struct vnode *vp, s goto out; } - out: - return error; -} - -static int -tmpfs_check_permitted(struct vnode *vp, struct tmpfs_node *node, mode_t mode, - kauth_cred_t cred) -{ - - return genfs_can_access(vp->v_type, node->tn_mode, node->tn_uid, + error = vaccess(vp->v_type, node->tn_mode, node->tn_uid, node->tn_gid, mode, cred); -} - -int -tmpfs_access(void *v) -{ - struct vnode *vp = ((struct vop_access_args *)v)->a_vp; - int mode = ((struct vop_access_args *)v)->a_mode; - kauth_cred_t cred = ((struct vop_access_args *)v)->a_cred; - - int error; - struct tmpfs_node *node; - - KASSERT(VOP_ISLOCKED(vp)); - - node = VP_TO_TMPFS_NODE(vp); - - error = tmpfs_check_possible(vp, node, mode); - if (error) - goto out; - - error = tmpfs_check_permitted(vp, node, mode, cred); out: KASSERT(VOP_ISLOCKED(vp)); @@ -673,7 +652,10 @@ tmpfs_remove(void *v) node = VP_TO_TMPFS_NODE(vp); tmp = VFS_TO_TMPFS(vp->v_mount); de = tmpfs_dir_lookup(dnode, cnp); - KASSERT(de); + if (de == NULL) { + error = ENOENT; + goto out; + } KASSERT(de->td_node == node); /* Files marked as immutable or append-only cannot be deleted. */ @@ -699,7 +681,6 @@ out: vrele(dvp); else vput(dvp); - PNBUF_PUT(cnp->cn_pnbuf); return error; } @@ -843,14 +824,12 @@ tmpfs_rename(void *v) goto out_unlocked; } - /* - * If the node we were renaming has scarpered, just give up. - */ de = tmpfs_dir_lookup(fdnode, fcnp); - if (de == NULL || de->td_node != fnode) { + if (de == NULL) { error = ENOENT; goto out; } + KASSERT(de->td_node == fnode); /* If source and target are the same file, there is nothing to do. */ if (fvp == tvp) { @@ -858,6 +837,14 @@ tmpfs_rename(void *v) goto out; } + /* Avoid manipulating '.' and '..' entries. */ + if (de == NULL) { + KASSERT(fvp->v_type == VDIR); + error = EINVAL; + goto out; + } + KASSERT(de->td_node == fnode); + /* If replacing an existing entry, ensure we can do the operation. */ if (tvp != NULL) { KASSERT(tnode != NULL); @@ -1050,7 +1037,10 @@ tmpfs_rmdir(void *v) /* Get the directory entry associated with node (vp). */ de = tmpfs_dir_lookup(dnode, cnp); - KASSERT(de); + if (de == NULL) { + error = ENOENT; + goto out; + } KASSERT(de->td_node == node); /* Check flags to see if we are allowed to remove the directory. */ @@ -1082,7 +1072,6 @@ tmpfs_rmdir(void *v) /* Release the nodes. */ vput(dvp); vput(vp); - PNBUF_PUT(cnp->cn_pnbuf); return error; }