Module Name: src Committed By: christos Date: Sun Mar 27 16:24:59 UTC 2022
Modified Files: src/sys/coda: coda_vnops.c src/sys/fs/tmpfs: tmpfs_vnops.c src/sys/fs/udf: udf_vnops.c src/sys/fs/v7fs: v7fs_vnops.c src/sys/nfs: nfs_vnops.c src/sys/ufs/chfs: chfs_vnops.c src/sys/ufs/ext2fs: ext2fs_vnops.c src/sys/ufs/lfs: ulfs_vnops.c src/sys/ufs/ufs: ufs_vnops.c Log Message: add a kauth vnode check for creating links To generate a diff of this commit: cvs rdiff -u -r1.117 -r1.118 src/sys/coda/coda_vnops.c cvs rdiff -u -r1.148 -r1.149 src/sys/fs/tmpfs/tmpfs_vnops.c cvs rdiff -u -r1.119 -r1.120 src/sys/fs/udf/udf_vnops.c cvs rdiff -u -r1.34 -r1.35 src/sys/fs/v7fs/v7fs_vnops.c cvs rdiff -u -r1.321 -r1.322 src/sys/nfs/nfs_vnops.c cvs rdiff -u -r1.47 -r1.48 src/sys/ufs/chfs/chfs_vnops.c cvs rdiff -u -r1.136 -r1.137 src/sys/ufs/ext2fs/ext2fs_vnops.c cvs rdiff -u -r1.55 -r1.56 src/sys/ufs/lfs/ulfs_vnops.c cvs rdiff -u -r1.261 -r1.262 src/sys/ufs/ufs/ufs_vnops.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/coda/coda_vnops.c diff -u src/sys/coda/coda_vnops.c:1.117 src/sys/coda/coda_vnops.c:1.118 --- src/sys/coda/coda_vnops.c:1.117 Sun Dec 5 03:10:39 2021 +++ src/sys/coda/coda_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: coda_vnops.c,v 1.117 2021/12/05 08:10:39 msaitoh Exp $ */ +/* $NetBSD: coda_vnops.c,v 1.118 2022/03/27 16:24:58 christos Exp $ */ /* * @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.117 2021/12/05 08:10:39 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: coda_vnops.c,v 1.118 2022/03/27 16:24:58 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1198,6 +1198,10 @@ coda_link(void *v) error = EFAULT; /* XXX better value */ goto exit; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto exit; error = venus_link(vtomi(vp), &cp->c_fid, &dcp->c_fid, nm, len, cred, l); VOP_UNLOCK(vp); Index: src/sys/fs/tmpfs/tmpfs_vnops.c diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.148 src/sys/fs/tmpfs/tmpfs_vnops.c:1.149 --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.148 Tue Oct 19 23:08:17 2021 +++ src/sys/fs/tmpfs/tmpfs_vnops.c Sun Mar 27 12:24:57 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.148 2021/10/20 03:08:17 thorpej Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.149 2022/03/27 16:24:57 christos Exp $ */ /* * Copyright (c) 2005, 2006, 2007, 2020 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.148 2021/10/20 03:08:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.149 2022/03/27 16:24:57 christos Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -801,6 +801,11 @@ tmpfs_link(void *v) goto out; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto out; + /* Allocate a new directory entry to represent the inode. */ error = tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), cnp->cn_nameptr, cnp->cn_namelen, &de); Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.119 src/sys/fs/udf/udf_vnops.c:1.120 --- src/sys/fs/udf/udf_vnops.c:1.119 Wed Feb 16 17:00:56 2022 +++ src/sys/fs/udf/udf_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.119 2022/02/16 22:00:56 andvar Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.120 2022/03/27 16:24:58 christos Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.119 2022/02/16 22:00:56 andvar Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.120 2022/03/27 16:24:58 christos Exp $"); #endif /* not lint */ @@ -1559,18 +1559,21 @@ udf_do_link(struct vnode *dvp, struct vn udf_node = VTOI(vp); error = VOP_GETATTR(vp, &vap, FSCRED); - if (error) { - VOP_UNLOCK(vp); - return error; - } + if (error) + goto out; /* check link count overflow */ if (vap.va_nlink >= (1<<16)-1) { /* uint16_t */ - VOP_UNLOCK(vp); - return EMLINK; + error = EMLINK; + goto out; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto out; error = udf_dir_attach(dir_node->ump, dir_node, udf_node, &vap, cnp); +out: if (error) VOP_UNLOCK(vp); return error; Index: src/sys/fs/v7fs/v7fs_vnops.c diff -u src/sys/fs/v7fs/v7fs_vnops.c:1.34 src/sys/fs/v7fs/v7fs_vnops.c:1.35 --- src/sys/fs/v7fs/v7fs_vnops.c:1.34 Fri Feb 11 05:55:15 2022 +++ src/sys/fs/v7fs/v7fs_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: v7fs_vnops.c,v 1.34 2022/02/11 10:55:15 hannken Exp $ */ +/* $NetBSD: v7fs_vnops.c,v 1.35 2022/03/27 16:24:58 christos Exp $ */ /*- * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.34 2022/02/11 10:55:15 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: v7fs_vnops.c,v 1.35 2022/03/27 16:24:58 christos Exp $"); #if defined _KERNEL_OPT #include "opt_v7fs.h" #endif @@ -745,21 +745,27 @@ v7fs_link(void *v) struct v7fs_inode *p = &node->inode; struct v7fs_self *fs = node->v7fsmount->core; struct componentname *cnp = a->a_cnp; - int error = 0; + int error, abrt = 1; DPRINTF("%p\n", vp); - /* Lock soruce file */ + /* Lock source file */ if ((error = vn_lock(vp, LK_EXCLUSIVE))) { DPRINTF("lock failed. %p\n", vp); - VOP_ABORTOP(dvp, cnp); goto unlock; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto unlock; + abrt = 0; error = v7fs_file_link(fs, parent, p, cnp->cn_nameptr, cnp->cn_namelen); /* Sync dirent size change. */ uvm_vnp_setsize(dvp, v7fs_inode_filesize(&parent_node->inode)); VOP_UNLOCK(vp); unlock: + if (abrt) + VOP_ABORTOP(dvp, cnp); return error; } Index: src/sys/nfs/nfs_vnops.c diff -u src/sys/nfs/nfs_vnops.c:1.321 src/sys/nfs/nfs_vnops.c:1.322 --- src/sys/nfs/nfs_vnops.c:1.321 Tue Oct 19 23:08:18 2021 +++ src/sys/nfs/nfs_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: nfs_vnops.c,v 1.321 2021/10/20 03:08:18 thorpej Exp $ */ +/* $NetBSD: nfs_vnops.c,v 1.322 2022/03/27 16:24:58 christos Exp $ */ /* * Copyright (c) 1989, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.321 2021/10/20 03:08:18 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.322 2022/03/27 16:24:58 christos Exp $"); #ifdef _KERNEL_OPT #include "opt_nfs.h" @@ -2012,6 +2012,13 @@ nfs_link(void *v) return error; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) { + VOP_ABORTOP(dvp, cnp); + return error; + } + /* * Push all writes to the server, so that the attribute cache * doesn't get "out of sync" with the server. Index: src/sys/ufs/chfs/chfs_vnops.c diff -u src/sys/ufs/chfs/chfs_vnops.c:1.47 src/sys/ufs/chfs/chfs_vnops.c:1.48 --- src/sys/ufs/chfs/chfs_vnops.c:1.47 Tue Dec 7 16:37:37 2021 +++ src/sys/ufs/chfs/chfs_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: chfs_vnops.c,v 1.47 2021/12/07 21:37:37 andvar Exp $ */ +/* $NetBSD: chfs_vnops.c,v 1.48 2022/03/27 16:24:58 christos Exp $ */ /*- * Copyright (c) 2010 Department of Software Engineering, @@ -1081,32 +1081,36 @@ chfs_link(void *v) struct componentname *cnp = ((struct vop_link_v2_args *) v)->a_cnp; struct chfs_inode *ip, *parent; - int error = 0; + int error, abrt = 1; if (vp->v_type == VDIR) { - VOP_ABORTOP(dvp, cnp); error = EISDIR; goto out; } if (dvp->v_mount != vp->v_mount) { - VOP_ABORTOP(dvp, cnp); error = EXDEV; goto out; } - if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) { - VOP_ABORTOP(dvp, cnp); + if (dvp != vp && (error = vn_lock(vp, LK_EXCLUSIVE))) + goto out; + + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) goto out; - } parent = VTOI(dvp); ip = VTOI(vp); + abrt = 0; error = chfs_do_link(ip, parent, cnp->cn_nameptr, cnp->cn_namelen, ip->ch_type); if (dvp != vp) VOP_UNLOCK(vp); out: + if (abrt) + VOP_ABORTOP(dvp, cnp); return error; } Index: src/sys/ufs/ext2fs/ext2fs_vnops.c diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.136 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.137 --- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.136 Tue Oct 19 23:08:19 2021 +++ src/sys/ufs/ext2fs/ext2fs_vnops.c Sun Mar 27 12:24:58 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.136 2021/10/20 03:08:19 thorpej Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.137 2022/03/27 16:24:58 christos Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.136 2021/10/20 03:08:19 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.137 2022/03/27 16:24:58 christos Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -580,7 +580,7 @@ ext2fs_link(void *v) struct vnode *vp = ap->a_vp; struct componentname *cnp = ap->a_cnp; struct inode *ip; - int error; + int error, abrt = 1; struct ufs_lookup_results *ulr; KASSERT(dvp != vp); @@ -592,23 +592,24 @@ ext2fs_link(void *v) UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); error = vn_lock(vp, LK_EXCLUSIVE); - if (error) { - VOP_ABORTOP(dvp, cnp); + if (error) goto out2; - } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto out1; ip = VTOI(vp); if ((nlink_t)ip->i_e2fs_nlink >= EXT2FS_LINK_MAX) { - VOP_ABORTOP(dvp, cnp); error = EMLINK; goto out1; } if (ip->i_e2fs_flags & (EXT2_IMMUTABLE | EXT2_APPEND)) { - VOP_ABORTOP(dvp, cnp); error = EPERM; goto out1; } ip->i_e2fs_nlink++; ip->i_flag |= IN_CHANGE; + abrt = 0; error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT); if (!error) error = ext2fs_direnter(ip, dvp, ulr, cnp); @@ -619,6 +620,8 @@ ext2fs_link(void *v) out1: VOP_UNLOCK(vp); out2: + if (abrt) + VOP_ABORTOP(dvp, cnp); return error; } Index: src/sys/ufs/lfs/ulfs_vnops.c diff -u src/sys/ufs/lfs/ulfs_vnops.c:1.55 src/sys/ufs/lfs/ulfs_vnops.c:1.56 --- src/sys/ufs/lfs/ulfs_vnops.c:1.55 Tue Oct 19 23:08:19 2021 +++ src/sys/ufs/lfs/ulfs_vnops.c Sun Mar 27 12:24:59 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ulfs_vnops.c,v 1.55 2021/10/20 03:08:19 thorpej Exp $ */ +/* $NetBSD: ulfs_vnops.c,v 1.56 2022/03/27 16:24:59 christos Exp $ */ /* from NetBSD: ufs_vnops.c,v 1.232 2016/05/19 18:32:03 riastradh Exp */ /*- @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.55 2021/10/20 03:08:19 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.56 2022/03/27 16:24:59 christos Exp $"); #if defined(_KERNEL_OPT) #include "opt_lfs.h" @@ -561,7 +561,7 @@ ulfs_link(void *v) struct vnode *vp = ap->a_vp; struct componentname *cnp = ap->a_cnp; struct inode *ip; - int error; + int error, abrt = 1; struct ulfs_lookup_results *ulr; KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); @@ -573,26 +573,26 @@ ulfs_link(void *v) ULFS_CHECK_CRAPCOUNTER(VTOI(dvp)); error = vn_lock(vp, LK_EXCLUSIVE); - if (error) { - VOP_ABORTOP(dvp, cnp); + if (error) goto out2; - } if (vp->v_mount != dvp->v_mount) { error = ENOENT; - VOP_ABORTOP(dvp, cnp); goto out2; } ip = VTOI(vp); if ((nlink_t)ip->i_nlink >= LINK_MAX) { - VOP_ABORTOP(dvp, cnp); error = EMLINK; goto out1; } if (ip->i_flags & (IMMUTABLE | APPEND)) { - VOP_ABORTOP(dvp, cnp); error = EPERM; goto out1; } + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto out1; + abrt = 0; ip->i_nlink++; DIP_ASSIGN(ip, nlink, ip->i_nlink); ip->i_state |= IN_CHANGE; @@ -608,6 +608,8 @@ ulfs_link(void *v) } out1: VOP_UNLOCK(vp); + if (abrt) + VOP_ABORTOP(dvp, cnp); out2: return (error); } Index: src/sys/ufs/ufs/ufs_vnops.c diff -u src/sys/ufs/ufs/ufs_vnops.c:1.261 src/sys/ufs/ufs/ufs_vnops.c:1.262 --- src/sys/ufs/ufs/ufs_vnops.c:1.261 Fri Nov 26 12:35:12 2021 +++ src/sys/ufs/ufs/ufs_vnops.c Sun Mar 27 12:24:59 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.261 2021/11/26 17:35:12 christos Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.262 2022/03/27 16:24:59 christos Exp $ */ /*- * Copyright (c) 2008, 2020 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.261 2021/11/26 17:35:12 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.262 2022/03/27 16:24:59 christos Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -893,7 +893,7 @@ ufs_link(void *v) struct mount *mp = dvp->v_mount; struct inode *ip; struct direct *newdir; - int error; + int error, abrt = 1; struct ufs_lookup_results *ulr; KASSERT(dvp != vp); @@ -905,29 +905,32 @@ ufs_link(void *v) UFS_CHECK_CRAPCOUNTER(VTOI(dvp)); error = vn_lock(vp, LK_EXCLUSIVE); - if (error) { - VOP_ABORTOP(dvp, cnp); + if (error) goto out2; - } + ip = VTOI(vp); if ((nlink_t)ip->i_nlink >= LINK_MAX) { - VOP_ABORTOP(dvp, cnp); error = EMLINK; goto out1; } if (ip->i_flags & (IMMUTABLE | APPEND)) { - VOP_ABORTOP(dvp, cnp); error = EPERM; goto out1; } + + error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_ADD_LINK, vp, + dvp, 0); + if (error) + goto out1; + error = UFS_WAPBL_BEGIN(mp); - if (error) { - VOP_ABORTOP(dvp, cnp); + if (error) goto out1; - } + ip->i_nlink++; DIP_ASSIGN(ip, nlink, ip->i_nlink); ip->i_flag |= IN_CHANGE; + abrt = 0; error = UFS_UPDATE(vp, NULL, NULL, UPDATE_DIROP); if (!error) { newdir = pool_cache_get(ufs_direct_cache, PR_WAITOK); @@ -945,6 +948,8 @@ ufs_link(void *v) out1: VOP_UNLOCK(vp); out2: + if (abrt) + VOP_ABORTOP(dvp, cnp); return (error); }