diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index e8b6b250e7f4..d305c39f1159 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -3548,11 +3548,14 @@ extattr_set_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return (error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return(error); - if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) - goto done; + if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) { + NDFREE(&nd, 0); + return (error); + } iovlen = uap->iovcnt * sizeof(struct iovec); if (uap->iovcnt > UIO_SMALLIOV) { if (uap->iovcnt > UIO_MAXIOV) { @@ -3617,7 +3620,8 @@ extattr_get_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return (error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return (error); iovlen = uap->iovcnt * sizeof (struct iovec); @@ -3681,11 +3685,12 @@ extattr_delete_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return(error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return(error); if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) { - vrele(nd.ni_vp); + NDFREE(&nd, 0); return (error); } error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred, diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index e8b6b250e7f4..d305c39f1159 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3548,11 +3548,14 @@ extattr_set_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return (error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return(error); - if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) - goto done; + if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) { + NDFREE(&nd, 0); + return (error); + } iovlen = uap->iovcnt * sizeof(struct iovec); if (uap->iovcnt > UIO_SMALLIOV) { if (uap->iovcnt > UIO_MAXIOV) { @@ -3617,7 +3620,8 @@ extattr_get_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return (error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return (error); iovlen = uap->iovcnt * sizeof (struct iovec); @@ -3681,11 +3685,12 @@ extattr_delete_file(p, uap) error = copyin(SCARG(uap, attrname), attrname, EXTATTR_MAXNAMELEN); if (error) return(error); - NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p); + NDINIT(&nd, LOOKUP | LOCKLEAF, FOLLOW, UIO_USERSPACE, + SCARG(uap, path), p); if ((error = namei(&nd)) != 0) return(error); if ((error = vn_start_write(nd.ni_vp, &mp, V_WAIT | PCATCH)) != 0) { - vrele(nd.ni_vp); + NDFREE(&nd, 0); return (error); } error = VOP_SETEXTATTR(nd.ni_vp, attrname, NULL, p->p_cred->pc_ucred, diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index bda7e98e763a..866abfbc309c 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -535,7 +535,7 @@ vop_aclcheck { }; # -#% getextattr vp = = = +#% getextattr vp L L L # vop_getextattr { IN struct vnode *vp;