Module Name: src Committed By: elad Date: Fri Jul 3 21:17:42 UTC 2009
Modified Files: src/sys/fs/adosfs: advnops.c src/sys/fs/cd9660: cd9660_vnops.c src/sys/fs/efs: efs_vnops.c src/sys/fs/filecorefs: filecore_vnops.c src/sys/fs/hfs: hfs_vnops.c src/sys/fs/msdosfs: msdosfs_vnops.c src/sys/fs/ntfs: ntfs_vnops.c src/sys/fs/ptyfs: ptyfs_vnops.c src/sys/fs/smbfs: smbfs_vnops.c src/sys/fs/sysvbfs: sysvbfs_vnops.c src/sys/fs/tmpfs: tmpfs_vnops.c src/sys/fs/udf: udf_vnops.c src/sys/miscfs/kernfs: kernfs_vnops.c src/sys/miscfs/procfs: procfs_vnops.c src/sys/ufs/ext2fs: ext2fs_vnops.c src/sys/ufs/ufs: ufs_vnops.c Log Message: Where possible, extract the file-system's access() routine to two internal functions: the first checking if the operation is possible (regardless of permissions), the second checking file-system permissions, ACLs, etc. Mailing list reference: http://mail-index.netbsd.org/tech-kern/2009/06/21/msg005311.html To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/fs/adosfs/advnops.c cvs rdiff -u -r1.37 -r1.38 src/sys/fs/cd9660/cd9660_vnops.c cvs rdiff -u -r1.18 -r1.19 src/sys/fs/efs/efs_vnops.c cvs rdiff -u -r1.31 -r1.32 src/sys/fs/filecorefs/filecore_vnops.c cvs rdiff -u -r1.14 -r1.15 src/sys/fs/hfs/hfs_vnops.c cvs rdiff -u -r1.60 -r1.61 src/sys/fs/msdosfs/msdosfs_vnops.c cvs rdiff -u -r1.44 -r1.45 src/sys/fs/ntfs/ntfs_vnops.c cvs rdiff -u -r1.31 -r1.32 src/sys/fs/ptyfs/ptyfs_vnops.c cvs rdiff -u -r1.70 -r1.71 src/sys/fs/smbfs/smbfs_vnops.c cvs rdiff -u -r1.22 -r1.23 src/sys/fs/sysvbfs/sysvbfs_vnops.c cvs rdiff -u -r1.60 -r1.61 src/sys/fs/tmpfs/tmpfs_vnops.c cvs rdiff -u -r1.47 -r1.48 src/sys/fs/udf/udf_vnops.c cvs rdiff -u -r1.137 -r1.138 src/sys/miscfs/kernfs/kernfs_vnops.c cvs rdiff -u -r1.175 -r1.176 src/sys/miscfs/procfs/procfs_vnops.c cvs rdiff -u -r1.87 -r1.88 src/sys/ufs/ext2fs/ext2fs_vnops.c cvs rdiff -u -r1.178 -r1.179 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/fs/adosfs/advnops.c diff -u src/sys/fs/adosfs/advnops.c:1.34 src/sys/fs/adosfs/advnops.c:1.35 --- src/sys/fs/adosfs/advnops.c:1.34 Tue Jun 23 19:36:38 2009 +++ src/sys/fs/adosfs/advnops.c Fri Jul 3 21:17:40 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: advnops.c,v 1.34 2009/06/23 19:36:38 elad Exp $ */ +/* $NetBSD: advnops.c,v 1.35 2009/07/03 21:17:40 elad Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.34 2009/06/23 19:36:38 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: advnops.c,v 1.35 2009/07/03 21:17:40 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -747,6 +747,38 @@ return(error); } +static int +adosfs_check_possible(struct vnode *vp, struct anode *ap, mode_t mode) +{ + + /* + * Disallow write attempts unless the file is a socket, + * fifo, or a block or character device resident on the + * file system. + */ + if (mode & VWRITE) { + switch (vp->v_type) { + case VDIR: + case VLNK: + case VREG: + return (EROFS); + default: + break; + } + } + + return 0; +} + +static int +adosfs_check_permitted(struct vnode *vp, struct anode *ap, mode_t mode, + kauth_cred_t cred) +{ + + return genfs_can_access(vp->v_type, + adunixprot(ap->adprot) & ap->amp->mask, ap->uid, ap->gid, mode, + cred); +} int adosfs_access(void *v) @@ -771,24 +803,13 @@ panic("adosfs_access: not locked"); } #endif - /* - * Disallow write attempts unless the file is a socket, - * fifo, or a block or character device resident on the - * file system. - */ - if (sp->a_mode & VWRITE) { - switch (vp->v_type) { - case VDIR: - case VLNK: - case VREG: - return (EROFS); - default: - break; - } - } - error = genfs_can_access(sp->a_vp->v_type, - adunixprot(ap->adprot) & ap->amp->mask, ap->uid, ap->gid, - sp->a_mode, sp->a_cred); + + error = adosfs_check_possible(vp, ap, sp->a_mode); + if (error) + return error; + + error = adosfs_check_permitted(vp, ap, sp->a_mode, sp->a_cred); + #ifdef ADOSFS_DIAGNOSTIC printf(" %d)", error); #endif Index: src/sys/fs/cd9660/cd9660_vnops.c diff -u src/sys/fs/cd9660/cd9660_vnops.c:1.37 src/sys/fs/cd9660/cd9660_vnops.c:1.38 --- src/sys/fs/cd9660/cd9660_vnops.c:1.37 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/cd9660/cd9660_vnops.c Fri Jul 3 21:17:40 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: cd9660_vnops.c,v 1.37 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: cd9660_vnops.c,v 1.38 2009/07/03 21:17:40 elad Exp $ */ /*- * Copyright (c) 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.37 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.38 2009/07/03 21:17:40 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -84,28 +84,16 @@ int iso_uiodir(struct isoreaddir *, struct dirent *, off_t); int iso_shipdir(struct isoreaddir *); -/* - * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. - * The mode is shifted to select the owner/group/other fields. The - * super user is granted all permissions. - */ -int -cd9660_access(void *v) +static int +cd9660_check_possible(struct vnode *vp, struct iso_node *ip, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct iso_node *ip = VTOI(vp); /* * Disallow write attempts unless the file is a socket, * fifo, or a block or character device resident on the * file system. */ - if (ap->a_mode & VWRITE) { + if (mode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: @@ -116,8 +104,42 @@ } } - return (genfs_can_access(vp->v_type, ip->inode.iso_mode & ALLPERMS, - ip->inode.iso_uid, ip->inode.iso_gid, ap->a_mode, ap->a_cred)); + return 0; +} + +/* + * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. + * The mode is shifted to select the owner/group/other fields. The + * super user is granted all permissions. + */ +static int +cd9660_check_permitted(struct vnode *vp, struct iso_node *ip, mode_t mode, + kauth_cred_t cred) +{ + + return genfs_can_access(vp->v_type, ip->inode.iso_mode & ALLPERMS, + ip->inode.iso_uid, ip->inode.iso_gid, mode, cred); +} + +int +cd9660_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct iso_node *ip = VTOI(vp); + int error; + + error = cd9660_check_possible(vp, ip, ap->a_mode); + if (error) + return error; + + error = cd9660_check_permitted(vp, ip, ap->a_mode, ap->a_cred); + + return error; } int Index: src/sys/fs/efs/efs_vnops.c diff -u src/sys/fs/efs/efs_vnops.c:1.18 src/sys/fs/efs/efs_vnops.c:1.19 --- src/sys/fs/efs/efs_vnops.c:1.18 Tue Jun 23 19:36:40 2009 +++ src/sys/fs/efs/efs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: efs_vnops.c,v 1.18 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: efs_vnops.c,v 1.19 2009/07/03 21:17:41 elad Exp $ */ /* * Copyright (c) 2006 Stephen M. Rumble <rum...@ephemeral.org> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.18 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: efs_vnops.c,v 1.19 2009/07/03 21:17:41 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -128,6 +128,16 @@ return (0); } +static int +efs_check_possible(struct vnode *vp, struct efs_inode *eip, mode_t mode) +{ + + if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) + return (EROFS); + + return 0; +} + /* * Determine the accessiblity of a file based on the permissions allowed by the * specified credentials. @@ -135,6 +145,15 @@ * Returns 0 on success. */ static int +efs_check_possible(struct vnode *vp, struct efs_inode *eip, mode_t mode, + kauth_cred_t cred) +{ + + return genfs_can_access(vp->v_type, eip->ei_mode, eip->ei_uid, + eip->ei_gid, mode, cred); +} + +static int efs_access(void *v) { struct vop_access_args /* { @@ -145,12 +164,15 @@ } */ *ap = v; struct vnode *vp = ap->a_vp; struct efs_inode *eip = EFS_VTOI(vp); + int error; - if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) - return (EROFS); + error = efs_check_possible(vp, eip, ap->a_mode); + if (error) + return error; + + error = efs_check_permitted(vp, eip, ap->a_mode, ap->a_cred); - return (genfs_can_access(vp->v_type, eip->ei_mode, eip->ei_uid, - eip->ei_gid, ap->a_mode, ap->a_cred)); + return error; } /* Index: src/sys/fs/filecorefs/filecore_vnops.c diff -u src/sys/fs/filecorefs/filecore_vnops.c:1.31 src/sys/fs/filecorefs/filecore_vnops.c:1.32 --- src/sys/fs/filecorefs/filecore_vnops.c:1.31 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/filecorefs/filecore_vnops.c Fri Jul 3 21:17:40 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: filecore_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: filecore_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $ */ /*- * Copyright (c) 1994 The Regents of the University of California. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: filecore_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -91,29 +91,17 @@ #include <fs/filecorefs/filecore_extern.h> #include <fs/filecorefs/filecore_node.h> -/* - * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. - * The mode is shifted to select the owner/group/other fields. The - * super user is granted all permissions. - */ -int -filecore_access(void *v) +static int +filecore_check_possible(struct vnode *vp, struct filecore_node *ip, + mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct filecore_node *ip = VTOI(vp); - struct filecore_mnt *fcmp = ip->i_mnt; /* * Disallow write attempts unless the file is a socket, * fifo, or a block or character device resident on the * file system. */ - if (ap->a_mode & VWRITE) { + if (mode & VWRITE) { switch (vp->v_type) { case VDIR: case VLNK: @@ -124,8 +112,43 @@ } } - return (genfs_can_access(vp->v_type, filecore_mode(ip), - fcmp->fc_uid, fcmp->fc_gid, ap->a_mode, ap->a_cred)); + return 0; +} + +/* + * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. + * The mode is shifted to select the owner/group/other fields. The + * super user is granted all permissions. + */ +static int +filecore_check_permitted(struct vnode *vp, struct filecore_node *ip, + mode_t mode, kauth_cred_t cred) +{ + struct filecore_mnt *fcmp = ip->i_mnt; + + return genfs_can_access(vp->v_type, filecore_mode(ip), + fcmp->fc_uid, fcmp->fc_gid, mode, cred); +} + +int +filecore_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct filecore_node *ip = VTOI(vp); + int error; + + error = filecore_check_possible(vp, ip, ap->a_mode); + if (error) + return error; + + error = filecore_check_permitted(vp, ip, ap->a_mode, ap->a_cred); + + return error; } int Index: src/sys/fs/hfs/hfs_vnops.c diff -u src/sys/fs/hfs/hfs_vnops.c:1.14 src/sys/fs/hfs/hfs_vnops.c:1.15 --- src/sys/fs/hfs/hfs_vnops.c:1.14 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/hfs/hfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: hfs_vnops.c,v 1.14 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: hfs_vnops.c,v 1.15 2009/07/03 21:17:41 elad Exp $ */ /*- * Copyright (c) 2005, 2007 The NetBSD Foundation, Inc. @@ -101,7 +101,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.14 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hfs_vnops.c,v 1.15 2009/07/03 21:17:41 elad Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -517,28 +517,17 @@ return 0; } -int -hfs_vop_access(void *v) +static int +hfs_check_possible(struct vnode *vp, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vattr va; - int error; - -#ifdef HFS_DEBUG - printf("VOP = hfs_vop_access()\n"); -#endif /* HFS_DEBUG */ /* * Disallow writes on files, directories, and symlinks * since we have no write support yet. */ - if (ap->a_mode & VWRITE) { - switch (ap->a_vp->v_type) { + if (mode & VWRITE) { + switch (vp->v_type) { case VDIR: case VLNK: case VREG: @@ -548,11 +537,42 @@ } } + return 0; +} + +static int +hfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred) +{ + + return genfs_can_access(va->va_type, va->va_mode, va->va_uid, + va->va_gid, mode, cred); +} + +int +hfs_vop_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vattr va; + int error; + +#ifdef HFS_DEBUG + printf("VOP = hfs_vop_access()\n"); +#endif /* HFS_DEBUG */ + + error = hfs_check_possible(ap->a_vp, ap->a_mode); + if (error) + return error; + if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return error; - return genfs_can_access(va.va_type, va.va_mode, va.va_uid, va.va_gid, - ap->a_mode, ap->a_cred); + error = hfs_check_permitted(&va, ap->a_mode, ap->a_cred); + + return error; } int Index: src/sys/fs/msdosfs/msdosfs_vnops.c diff -u src/sys/fs/msdosfs/msdosfs_vnops.c:1.60 src/sys/fs/msdosfs/msdosfs_vnops.c:1.61 --- src/sys/fs/msdosfs/msdosfs_vnops.c:1.60 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/msdosfs/msdosfs_vnops.c Fri Jul 3 21:17:40 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: msdosfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: msdosfs_vnops.c,v 1.61 2009/07/03 21:17:40 elad Exp $ */ /*- * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank. @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: msdosfs_vnops.c,v 1.61 2009/07/03 21:17:40 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -217,18 +217,9 @@ return (0); } -int -msdosfs_access(void *v) +static int +msdosfs_check_possible(struct vnode *vp, struct denode *dep, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct denode *dep = VTODE(vp); - struct msdosfsmount *pmp = dep->de_pmp; - mode_t mode = ap->a_mode; /* * Disallow write attempts on read-only file systems; @@ -247,13 +238,45 @@ } } + return 0; +} + +static int +msdosfs_check_permitted(struct vnode *vp, struct denode *dep, mode_t mode, + kauth_cred_t cred) +{ + struct msdosfsmount *pmp = dep->de_pmp; + mode_t file_mode; + if ((dep->de_Attributes & ATTR_READONLY) == 0) - mode = S_IRWXU|S_IRWXG|S_IRWXO; + file_mode = S_IRWXU|S_IRWXG|S_IRWXO; else - mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; - return (genfs_can_access(ap->a_vp->v_type, - mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask), - pmp->pm_uid, pmp->pm_gid, ap->a_mode, ap->a_cred)); + file_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; + + return genfs_can_access(vp->v_type, + file_mode & (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask), + pmp->pm_uid, pmp->pm_gid, mode, cred); +} + +int +msdosfs_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct denode *dep = VTODE(vp); + int error; + + error = msdosfs_check_possible(vp, dep, ap->a_mode); + if (error) + return error; + + error = msdosfs_check_permitted(vp, dep, ap->a_mode, ap->a_cred); + + return error; } int Index: src/sys/fs/ntfs/ntfs_vnops.c diff -u src/sys/fs/ntfs/ntfs_vnops.c:1.44 src/sys/fs/ntfs/ntfs_vnops.c:1.45 --- src/sys/fs/ntfs/ntfs_vnops.c:1.44 Tue Jun 23 19:36:40 2009 +++ src/sys/fs/ntfs/ntfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ntfs_vnops.c,v 1.44 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: ntfs_vnops.c,v 1.45 2009/07/03 21:17:41 elad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.44 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ntfs_vnops.c,v 1.45 2009/07/03 21:17:41 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -395,19 +395,9 @@ return (error); } -int -ntfs_access(void *v) +static int +ntfs_check_possible(struct vnode *vp, struct ntnode *ip, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct ntnode *ip = VTONT(vp); - mode_t file_mode, mode = ap->a_mode; - - dprintf(("ntfs_access: %llu\n", (unsigned long long)ip->i_number)); /* * Disallow write attempts on read-only file systems; @@ -425,10 +415,42 @@ } } + return 0; +} + +static int +ntfs_check_permitted(struct vnode *vp, struct ntnode *ip, mode_t mode, + kauth_cred_t cred) +{ + mode_t file_mode; + file_mode = ip->i_mp->ntm_mode | (S_IXUSR|S_IXGRP|S_IXOTH); - return (genfs_can_access(vp->v_type, file_mode, ip->i_mp->ntm_uid, - ip->i_mp->ntm_gid, mode, ap->a_cred)); + return genfs_can_access(vp->v_type, file_mode, ip->i_mp->ntm_uid, + ip->i_mp->ntm_gid, mode, cred); +} + +int +ntfs_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct ntnode *ip = VTONT(vp); + int error; + + dprintf(("ntfs_access: %llu\n", (unsigned long long)ip->i_number)); + + error = ntfs_check_possible(vp, ip, ap->a_mode); + if (error) + return error; + + error = ntfs_check_permitted(vp, ip, ap->a_mode, ap->a_cred); + + return error; } /* Index: src/sys/fs/ptyfs/ptyfs_vnops.c diff -u src/sys/fs/ptyfs/ptyfs_vnops.c:1.31 src/sys/fs/ptyfs/ptyfs_vnops.c:1.32 --- src/sys/fs/ptyfs/ptyfs_vnops.c:1.31 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/ptyfs/ptyfs_vnops.c Fri Jul 3 21:17:40 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ptyfs_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: ptyfs_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $ */ /* * Copyright (c) 1993, 1995 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.31 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.32 2009/07/03 21:17:40 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -498,6 +498,21 @@ return 0; } +static int +ptyfs_check_possible(struct vnode *vp, mode_t mode) +{ + + return 0; +} + +static int +ptyfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred) +{ + + return genfs_can_access(va->va_type, va->va_mode, + va->va_uid, va->va_gid, mode, cred); +} + /* * implement access checking. * @@ -521,8 +536,13 @@ if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return error; - return genfs_can_access(va.va_type, va.va_mode, - va.va_uid, va.va_gid, ap->a_mode, ap->a_cred); + error = ptyfs_check_possible(ap->a_vp, ap->a_mode); + if (error) + return error; + + error = ptyfs_check_permitted(&va, ap->a_mode, ap->a_cred); + + return error; } /* Index: src/sys/fs/smbfs/smbfs_vnops.c diff -u src/sys/fs/smbfs/smbfs_vnops.c:1.70 src/sys/fs/smbfs/smbfs_vnops.c:1.71 --- src/sys/fs/smbfs/smbfs_vnops.c:1.70 Fri Jul 3 18:35:33 2009 +++ src/sys/fs/smbfs/smbfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: smbfs_vnops.c,v 1.70 2009/07/03 18:35:33 njoly Exp $ */ +/* $NetBSD: smbfs_vnops.c,v 1.71 2009/07/03 21:17:41 elad Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.70 2009/07/03 18:35:33 njoly Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smbfs_vnops.c,v 1.71 2009/07/03 21:17:41 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -160,32 +160,16 @@ const struct vnodeopv_desc smbfs_vnodeop_opv_desc = { &smbfs_vnodeop_p, smbfs_vnodeop_entries }; -int -smbfs_access(void *v) +static int +smbfs_check_possible(struct vnode *vp, struct smbnode *np, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; -#ifdef SMB_VNODE_DEBUG - struct smbnode *np = VTOSMB(vp); -#endif - u_int acc_mode = ap->a_mode; - struct smbmount *smp = VTOSMBFS(vp); - - SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n", - (int) np->n_nmlen, np->n_name, - (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode, - acc_mode); /* * Disallow write attempts on read-only file systems; * unless the file is a socket, fifo, or a block or * character device resident on the file system. */ - if (acc_mode & VWRITE) { + if (mode & VWRITE) { switch (vp->v_type) { case VREG: case VDIR: @@ -197,10 +181,45 @@ } } - return (genfs_can_access(vp->v_type, + return 0; +} + +static int +smbfs_check_permitted(struct vnode *vp, struct smbnode *np, mode_t mode, + kauth_cred_t cred) +{ + struct smbmount *smp = VTOSMBFS(vp); + + return genfs_can_access(vp->v_type, (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode, - smp->sm_args.uid, smp->sm_args.gid, - acc_mode, ap->a_cred)); + smp->sm_args.uid, smp->sm_args.gid, mode, cred); +} + +int +smbfs_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct smbnode *np = VTOSMB(vp); + u_int acc_mode = ap->a_mode; + int error; + + SMBVDEBUG("file '%.*s', node mode=%o, acc mode=%x\n", + (int) np->n_nmlen, np->n_name, + (vp->v_type == VDIR) ? smp->sm_args.dir_mode : smp->sm_args.file_mode, + acc_mode); + + error = smbfs_check_possible(vp, np, acc_mode); + if (error) + return error; + + error = smbfs_check_permitted(vp, np, acc_mode, ap->a_cred); + + return error; } /* ARGSUSED */ Index: src/sys/fs/sysvbfs/sysvbfs_vnops.c diff -u src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.22 src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.23 --- src/sys/fs/sysvbfs/sysvbfs_vnops.c:1.22 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/sysvbfs/sysvbfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: sysvbfs_vnops.c,v 1.22 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: sysvbfs_vnops.c,v 1.23 2009/07/03 21:17:41 elad Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.22 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sysvbfs_vnops.c,v 1.23 2009/07/03 21:17:41 elad Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -230,6 +230,27 @@ return 0; } +static int +sysvbfs_check_possible(struct vnode *vp, struct sysvbfs_node *bnode, + mode_t mode) +{ + + if ((mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) + return EROFS; + + return 0; +} + +static int +sysvbfs_check_permitted(struct vnode *vp, struct sysvbfs_node *bnode, + mode_t mode, kauth_cred_t cred) +{ + struct bfs_fileattr *attr = &bnode->inode->attr; + + return genfs_can_access(vp->v_type, attr->mode, attr->uid, attr->gid, + mode, cred); +} + int sysvbfs_access(void *arg) { @@ -240,14 +261,16 @@ } */ *ap = arg; struct vnode *vp = ap->a_vp; struct sysvbfs_node *bnode = vp->v_data; - struct bfs_fileattr *attr = &bnode->inode->attr; DPRINTF("%s:\n", __func__); - if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) - return EROFS; - return genfs_can_access(vp->v_type, attr->mode, attr->uid, attr->gid, - ap->a_mode, ap->a_cred); + error = sysvbfs_check_possible(vp, bnode, ap->a_mode); + if (error) + return error; + + error = sysvbfs_check_permitted(vp, bnode, ap->a_mode, ap->a_cred); + + return error; } int Index: src/sys/fs/tmpfs/tmpfs_vnops.c diff -u src/sys/fs/tmpfs/tmpfs_vnops.c:1.60 src/sys/fs/tmpfs/tmpfs_vnops.c:1.61 --- src/sys/fs/tmpfs/tmpfs_vnops.c:1.60 Tue Jun 23 19:36:39 2009 +++ src/sys/fs/tmpfs/tmpfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $ */ +/* $NetBSD: tmpfs_vnops.c,v 1.61 2009/07/03 21:17:41 elad Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.60 2009/06/23 19:36:39 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.61 2009/07/03 21:17:41 elad Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -337,19 +337,10 @@ /* --------------------------------------------------------------------- */ -int -tmpfs_access(void *v) +static int +tmpfs_check_possible(struct vnode *vp, struct tmpfs_node *node, mode_t mode) { - 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); + int error = 0; switch (vp->v_type) { case VDIR: @@ -382,8 +373,38 @@ goto out; } - error = genfs_can_access(vp->v_type, node->tn_mode, node->tn_uid, + 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, 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)); Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.47 src/sys/fs/udf/udf_vnops.c:1.48 --- src/sys/fs/udf/udf_vnops.c:1.47 Thu Jun 25 17:16:33 2009 +++ src/sys/fs/udf/udf_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.47 2009/06/25 17:16:33 reinoud Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.48 2009/07/03 21:17:41 elad 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.47 2009/06/25 17:16:33 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.48 2009/07/03 21:17:41 elad Exp $"); #endif /* not lint */ @@ -1310,31 +1310,13 @@ /* --------------------------------------------------------------------- */ -int -udf_access(void *v) +static int +udf_check_possible(struct vattr *vap, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - struct proc *a_p; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - mode_t mode = ap->a_mode; - kauth_cred_t cred = ap->a_cred; - /* struct udf_node *udf_node = VTOI(vp); */ - struct vattr vap; int flags; - int error; - - DPRINTF(CALL, ("udf_access called\n")); - - error = VOP_GETATTR(vp, &vap, NULL); - if (error) - return error; /* check if we are allowed to write */ - switch (vap.va_type) { + switch (vap->va_type) { case VDIR: case VLNK: case VREG: @@ -1365,12 +1347,51 @@ if ((mode & VWRITE) && (flags & IMMUTABLE)) return EPERM; + return 0; +} + +static int +udf_check_permitted(struct vnode *vp, struct vattr *vap, mode_t mode, + kauth_cred_t cred) +{ + /* ask the generic genfs_can_access to advice on security */ return genfs_can_access(vp->v_type, - vap.va_mode, vap.va_uid, vap.va_gid, + vap->va_mode, vap->va_uid, vap->va_gid, mode, cred); } +int +udf_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + struct proc *a_p; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + mode_t mode = ap->a_mode; + kauth_cred_t cred = ap->a_cred; + /* struct udf_node *udf_node = VTOI(vp); */ + struct vattr vap; + int error; + + DPRINTF(CALL, ("udf_access called\n")); + + error = VOP_GETATTR(vp, &vap, NULL); + if (error) + return error; + + error = udf_check_possible(&vap, mode); + if (error) + return error; + + error = udf_check_permitted(vp, &vap, mode, cred); + + return error; +} + /* --------------------------------------------------------------------- */ int Index: src/sys/miscfs/kernfs/kernfs_vnops.c diff -u src/sys/miscfs/kernfs/kernfs_vnops.c:1.137 src/sys/miscfs/kernfs/kernfs_vnops.c:1.138 --- src/sys/miscfs/kernfs/kernfs_vnops.c:1.137 Tue Jun 23 19:36:40 2009 +++ src/sys/miscfs/kernfs/kernfs_vnops.c Fri Jul 3 21:17:41 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: kernfs_vnops.c,v 1.137 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $ */ /* * Copyright (c) 1992, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.137 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.138 2009/07/03 21:17:41 elad Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -763,6 +763,21 @@ return (0); } +static int +kernfs_check_possible(struct vnode *vp, mode_t mode) +{ + + return 0; +} + +static int +kernfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred) +{ + + return genfs_can_access(va->va_type, va->va_mode, va->va_uid, va->va_gid, + mode, cred); +} + int kernfs_access(void *v) { @@ -777,8 +792,13 @@ if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return (error); - return (genfs_can_access(va.va_type, va.va_mode, va.va_uid, va.va_gid, - ap->a_mode, ap->a_cred)); + error = kernfs_check_possible(ap->a_vp, ap->a_mode); + if (error) + return error; + + error = kernfs_check_permitted(&va, ap->a_mode, ap->a_cred); + + return error; } static int Index: src/sys/miscfs/procfs/procfs_vnops.c diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.175 src/sys/miscfs/procfs/procfs_vnops.c:1.176 --- src/sys/miscfs/procfs/procfs_vnops.c:1.175 Tue Jun 23 19:36:40 2009 +++ src/sys/miscfs/procfs/procfs_vnops.c Fri Jul 3 21:17:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vnops.c,v 1.175 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: procfs_vnops.c,v 1.176 2009/07/03 21:17:42 elad Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -105,7 +105,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.175 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.176 2009/07/03 21:17:42 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -909,6 +909,21 @@ return (0); } +static int +procfs_check_possible(struct vnode *vp, mode_t mode) +{ + + return 0; +} + +static int +procfs_check_permitted(struct vattr *va, mode_t mode, kauth_cred_t cred) +{ + + return genfs_can_access(va->va_type, va->va_mode, + va->va_uid, va->va_gid, mode, cred); +} + /* * implement access checking. * @@ -932,8 +947,13 @@ if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) return (error); - return (genfs_can_access(va.va_type, va.va_mode, - va.va_uid, va.va_gid, ap->a_mode, ap->a_cred)); + error = procfs_check_possible(ap->a_vp, ap->a_mode); + if (error) + return error; + + error = procfs_check_permitted(&va, ap->a_mode, ap->a_cred); + + return error; } /* Index: src/sys/ufs/ext2fs/ext2fs_vnops.c diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.87 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.88 --- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.87 Tue Jun 23 19:36:40 2009 +++ src/sys/ufs/ext2fs/ext2fs_vnops.c Fri Jul 3 21:17:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.87 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.88 2009/07/03 21:17:42 elad Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.87 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.88 2009/07/03 21:17:42 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -224,17 +224,9 @@ return (0); } -int -ext2fs_access(void *v) +static int +ext2fs_check_possible(struct vnode *vp, struct inode *ip, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - struct inode *ip = VTOI(vp); - mode_t mode = ap->a_mode; /* * Disallow write attempts on read-only file systems; @@ -258,8 +250,38 @@ if ((mode & VWRITE) && (ip->i_e2fs_flags & EXT2_IMMUTABLE)) return (EPERM); - return (genfs_can_access(vp->v_type, ip->i_e2fs_mode & ALLPERMS, - ip->i_uid, ip->i_gid, mode, ap->a_cred)); + return 0; +} + +static int +ext2fs_check_permitted(struct vnode *vp, struct inode *ip, mode_t mode, + kauth_cred_t cred) +{ + + return genfs_can_access(vp->v_type, ip->i_e2fs_mode & ALLPERMS, + ip->i_uid, ip->i_gid, mode, cred); +} + +int +ext2fs_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct inode *ip = VTOI(vp); + mode_t mode = ap->a_mode; + int error; + + error = ext2fs_check_possible(vp, ip, mode); + if (error) + return error; + + error = ext2fs_check_permitted(vp, ip, mode, ap->a_cred); + + return error; } /* ARGSUSED */ Index: src/sys/ufs/ufs/ufs_vnops.c diff -u src/sys/ufs/ufs/ufs_vnops.c:1.178 src/sys/ufs/ufs/ufs_vnops.c:1.179 --- src/sys/ufs/ufs/ufs_vnops.c:1.178 Tue Jun 23 19:36:40 2009 +++ src/sys/ufs/ufs/ufs_vnops.c Fri Jul 3 21:17:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.178 2009/06/23 19:36:40 elad Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.179 2009/07/03 21:17:42 elad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.178 2009/06/23 19:36:40 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.179 2009/07/03 21:17:42 elad Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -272,24 +272,13 @@ return (0); } -int -ufs_access(void *v) +static int +ufs_check_possible(struct vnode *vp, struct inode *ip, mode_t mode) { - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - kauth_cred_t a_cred; - } */ *ap = v; - struct vnode *vp; - struct inode *ip; - mode_t mode; #ifdef QUOTA - int error; -#endif + int error; +#endif /* QUOTA */ - vp = ap->a_vp; - ip = VTOI(vp); - mode = ap->a_mode; /* * Disallow write attempts on read-only file systems; * unless the file is a socket, fifo, or a block or @@ -328,8 +317,42 @@ if ((mode & VWRITE) && (ip->i_flags & IMMUTABLE)) return (EPERM); - return (genfs_can_access(vp->v_type, ip->i_mode & ALLPERMS, - ip->i_uid, ip->i_gid, mode, ap->a_cred)); + return 0; +} + +static int +ufs_check_permitted(struct vnode *vp, struct inode *ip, mode_t mode, + kauth_cred_t cred) +{ + + return genfs_can_access(vp->v_type, ip->i_mode & ALLPERMS, ip->i_uid, + ip->i_gid, mode, cred); +} + +int +ufs_access(void *v) +{ + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + kauth_cred_t a_cred; + } */ *ap = v; + struct vnode *vp; + struct inode *ip; + mode_t mode; + int error; + + vp = ap->a_vp; + ip = VTOI(vp); + mode = ap->a_mode; + + error = ufs_check_possible(vp, ip, mode); + if (error) + return error; + + error = ufs_check_permitted(vp, ip, mode, ap->a_cred); + + return error; } /* ARGSUSED */