Module Name: src Committed By: elad Date: Wed Apr 22 22:57:09 UTC 2009
Modified Files: src/sys/fs/ptyfs: ptyfs_vnops.c src/sys/fs/tmpfs: tmpfs_subr.c src/sys/fs/udf: udf_vnops.c src/sys/kern: vfs_subr.c src/sys/miscfs/genfs: genfs.h genfs_vnops.c src/sys/sys: vnode.h src/sys/ufs/ext2fs: ext2fs_vnops.c src/sys/ufs/ufs: ufs_vnops.c Log Message: Per discussion on tech-kern@: - Replace use of label/goto with returns - Rename, change prototype of, and move functions from vfs_subr.c to genfs_vnops.c To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.29 src/sys/fs/ptyfs/ptyfs_vnops.c cvs rdiff -u -r1.51 -r1.52 src/sys/fs/tmpfs/tmpfs_subr.c cvs rdiff -u -r1.39 -r1.40 src/sys/fs/udf/udf_vnops.c cvs rdiff -u -r1.373 -r1.374 src/sys/kern/vfs_subr.c cvs rdiff -u -r1.23 -r1.24 src/sys/miscfs/genfs/genfs.h cvs rdiff -u -r1.168 -r1.169 src/sys/miscfs/genfs/genfs_vnops.c cvs rdiff -u -r1.204 -r1.205 src/sys/sys/vnode.h cvs rdiff -u -r1.84 -r1.85 src/sys/ufs/ext2fs/ext2fs_vnops.c cvs rdiff -u -r1.174 -r1.175 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/ptyfs/ptyfs_vnops.c diff -u src/sys/fs/ptyfs/ptyfs_vnops.c:1.28 src/sys/fs/ptyfs/ptyfs_vnops.c:1.29 --- src/sys/fs/ptyfs/ptyfs_vnops.c:1.28 Mon Apr 20 18:06:27 2009 +++ src/sys/fs/ptyfs/ptyfs_vnops.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ptyfs_vnops.c,v 1.28 2009/04/20 18:06:27 elad Exp $ */ +/* $NetBSD: ptyfs_vnops.c,v 1.29 2009/04/22 22:57:09 elad Exp $ */ /* * Copyright (c) 1993, 1995 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.28 2009/04/20 18:06:27 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ptyfs_vnops.c,v 1.29 2009/04/22 22:57:09 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -464,7 +464,7 @@ struct ptyfsnode *ptyfs = VTOPTYFS(vp); int error; - error = common_chmod_allowed(cred, vp, ptyfs->ptyfs_uid, + error = genfs_can_chmod(vp, cred, ptyfs->ptyfs_uid, ptyfs->ptyfs_gid, mode); if (error) return (error); @@ -490,8 +490,8 @@ if (gid == (gid_t)VNOVAL) gid = ptyfs->ptyfs_gid; - error = common_chown_allowed(cred, ptyfs->ptyfs_uid, ptyfs->ptyfs_gid, - uid, gid); + error = genfs_can_chown(vp, cred, ptyfs->ptyfs_uid, + ptyfs->ptyfs_gid, uid, gid); if (error) return (error); Index: src/sys/fs/tmpfs/tmpfs_subr.c diff -u src/sys/fs/tmpfs/tmpfs_subr.c:1.51 src/sys/fs/tmpfs/tmpfs_subr.c:1.52 --- src/sys/fs/tmpfs/tmpfs_subr.c:1.51 Mon Apr 20 18:06:27 2009 +++ src/sys/fs/tmpfs/tmpfs_subr.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: tmpfs_subr.c,v 1.51 2009/04/20 18:06:27 elad Exp $ */ +/* $NetBSD: tmpfs_subr.c,v 1.52 2009/04/22 22:57:09 elad Exp $ */ /* * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.51 2009/04/20 18:06:27 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.52 2009/04/22 22:57:09 elad Exp $"); #include <sys/param.h> #include <sys/dirent.h> @@ -1033,7 +1033,7 @@ if (node->tn_flags & (IMMUTABLE | APPEND)) return EPERM; - error = common_chmod_allowed(cred, vp, node->tn_uid, node->tn_gid, + error = genfs_can_chmod(vp, cred, node->tn_uid, node->tn_gid, mode); if (error) return (error); @@ -1084,7 +1084,7 @@ if (node->tn_flags & (IMMUTABLE | APPEND)) return EPERM; - error = common_chown_allowed(cred, node->tn_uid, node->tn_gid, uid, + error = genfs_can_chown(vp, cred, node->tn_uid, node->tn_gid, uid, gid); if (error) return (error); Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.39 src/sys/fs/udf/udf_vnops.c:1.40 --- src/sys/fs/udf/udf_vnops.c:1.39 Mon Apr 20 18:06:26 2009 +++ src/sys/fs/udf/udf_vnops.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.39 2009/04/20 18:06:26 elad Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.40 2009/04/22 22:57:09 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.39 2009/04/20 18:06:26 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.40 2009/04/22 22:57:09 elad Exp $"); #endif /* not lint */ @@ -965,7 +965,7 @@ return EINVAL; /* check permissions */ - error = common_chown_allowed(cred, uid, gid, new_uid, new_gid); + error = genfs_can_chown(vp, cred, uid, gid, new_uid, new_gid); if (error) return (error); @@ -1001,7 +1001,7 @@ udf_getownership(udf_node, &uid, &gid); /* check permissions */ - error = common_chmod_allowed(cred, vp, uid, gid, mode); + error = genfs_can_chmod(vp, cred, uid, gid, mode); if (error) return (error); Index: src/sys/kern/vfs_subr.c diff -u src/sys/kern/vfs_subr.c:1.373 src/sys/kern/vfs_subr.c:1.374 --- src/sys/kern/vfs_subr.c:1.373 Tue Apr 21 00:02:37 2009 +++ src/sys/kern/vfs_subr.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_subr.c,v 1.373 2009/04/21 00:02:37 yamt Exp $ */ +/* $NetBSD: vfs_subr.c,v 1.374 2009/04/22 22:57:09 elad Exp $ */ /*- * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. @@ -81,7 +81,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.373 2009/04/21 00:02:37 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.374 2009/04/22 22:57:09 elad Exp $"); #include "opt_ddb.h" #include "opt_compat_netbsd.h" @@ -3207,146 +3207,3 @@ } #endif /* DDB */ -/* - * Common routine to check if chmod() is allowed. - * - * Policy: - * - You must be root, or - * - You must own the file, and - * - You must not set the "sticky" bit (meaningless, see chmod(2)) - * - You must be a member of the group if you're trying to set the - * SGIDf bit - * - * cred - credentials of the invoker - * vp - vnode of the file-system object - * cur_uid, cur_gid - current uid/gid of the file-system object - * new_mode - new mode for the file-system object - * - * Returns 0 if the change is allowed, or an error value otherwise. - */ -int -common_chmod_allowed(kauth_cred_t cred, struct vnode *vp, uid_t cur_uid, - gid_t cur_gid, mode_t new_mode) -{ - int error; - - /* Superuser can always change mode. */ - error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, - NULL); - if (!error) { - goto out; - } - - /* Otherwise, user must own the file. */ - if (kauth_cred_geteuid(cred) != cur_uid) { - goto out; - } - - /* - * Non-root users can't set the sticky bit on files. - */ - if ((vp->v_type != VDIR) && (new_mode & S_ISTXT)) { - error = EFTYPE; - goto out; - } - - /* - * If the invoker is trying to set the SGID bit on the file, - * check group membership. - */ - if (new_mode & S_ISGID) { - int ismember; - - error = kauth_cred_ismember_gid(cred, cur_gid, - &ismember); - if (error) - goto out; - - if (!ismember) { - error = EPERM; - goto out; - } - } - - error = 0; - - out: - return (error); -} - -/* - * Common routine to check if chown() is allowed. - * - * Policy: - * - You must be root, or - * - You must own the file, and - * - You must not try to change ownership, and - * - You must be member of the new group - * - * cred - credentials of the invoker - * cur_uid, cur_gid - current uid/gid of the file-system object - * new_uid, new_gid - target uid/gid of the file-system object - * - * Returns 0 if the change is allowed, or an error value otherwise. - */ -int -common_chown_allowed(kauth_cred_t cred, uid_t cur_uid, gid_t cur_gid, - uid_t new_uid, gid_t new_gid) -{ - int error, ismember; - - /* - * You can only change ownership of a file if: - * You are the superuser, or... - */ - error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, - NULL); - if (!error) { - goto out; - } - - /* - * You own the file and... - */ - if (kauth_cred_geteuid(cred) == cur_uid) { - /* - * You don't try to change ownership, and... - */ - if (new_uid != cur_uid) { - goto out; - } - - /* - * You don't try to change group (no-op), or... - */ - if (new_gid == cur_gid) { - error = 0; - goto out; - } - - /* - * Your effective gid is the new gid, or... - */ - if (kauth_cred_getegid(cred) == new_gid) { - error = 0; - goto out; - } - - /* - * The new gid is one you're a member of. - */ - ismember = 0; - error = kauth_cred_ismember_gid(cred, new_gid, - &ismember); - if (error || !ismember) { - error = EPERM; - goto out; - } - - error = 0; - } - - out: - return (error); -} - Index: src/sys/miscfs/genfs/genfs.h diff -u src/sys/miscfs/genfs/genfs.h:1.23 src/sys/miscfs/genfs/genfs.h:1.24 --- src/sys/miscfs/genfs/genfs.h:1.23 Mon Jan 28 14:31:18 2008 +++ src/sys/miscfs/genfs/genfs.h Wed Apr 22 22:57:08 2009 @@ -1,4 +1,9 @@ -/* $NetBSD: genfs.h,v 1.23 2008/01/28 14:31:18 dholland Exp $ */ +/* $NetBSD: genfs.h,v 1.24 2009/04/22 22:57:08 elad Exp $ */ + +#ifndef _MISCFS_GENFS_GENFS_H_ +#define _MISCFS_GENFS_GENFS_H_ + +#include <sys/vnode.h> int genfs_badop(void *); int genfs_nullop(void *); @@ -30,3 +35,8 @@ int genfs_renamelock_enter(struct mount *); void genfs_renamelock_exit(struct mount *); + +int genfs_can_chmod(vnode_t *, kauth_cred_t, uid_t, gid_t, mode_t); +int genfs_can_chown(vnode_t *, kauth_cred_t, uid_t, gid_t, uid_t, gid_t); + +#endif /* !_MISCFS_GENFS_GENFS_H_ */ Index: src/sys/miscfs/genfs/genfs_vnops.c diff -u src/sys/miscfs/genfs/genfs_vnops.c:1.168 src/sys/miscfs/genfs/genfs_vnops.c:1.169 --- src/sys/miscfs/genfs/genfs_vnops.c:1.168 Sat Apr 18 15:40:33 2009 +++ src/sys/miscfs/genfs/genfs_vnops.c Wed Apr 22 22:57:08 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: genfs_vnops.c,v 1.168 2009/04/18 15:40:33 pooka Exp $ */ +/* $NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.168 2009/04/18 15:40:33 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: genfs_vnops.c,v 1.169 2009/04/22 22:57:08 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -72,6 +72,7 @@ #include <sys/mman.h> #include <sys/file.h> #include <sys/kauth.h> +#include <sys/stat.h> #include <miscfs/genfs/genfs.h> #include <miscfs/genfs/genfs_node.h> @@ -520,3 +521,124 @@ rw_exit(&gp->g_glock); } + +/* + * Common routine to check if chmod() is allowed. + * + * Policy: + * - You must be root, or + * - You must own the file, and + * - You must not set the "sticky" bit (meaningless, see chmod(2)) + * - You must be a member of the group if you're trying to set the + * SGIDf bit + * + * cred - credentials of the invoker + * vp - vnode of the file-system object + * cur_uid, cur_gid - current uid/gid of the file-system object + * new_mode - new mode for the file-system object + * + * Returns 0 if the change is allowed, or an error value otherwise. + */ +int +genfs_can_chmod(vnode_t *vp, kauth_cred_t cred, uid_t cur_uid, + gid_t cur_gid, mode_t new_mode) +{ + int error; + + /* Superuser can always change mode. */ + error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, + NULL); + if (!error) + return (0); + + /* Otherwise, user must own the file. */ + if (kauth_cred_geteuid(cred) != cur_uid) + return (EPERM); + + /* + * Non-root users can't set the sticky bit on files. + */ + if ((vp->v_type != VDIR) && (new_mode & S_ISTXT)) + return (EFTYPE); + + /* + * If the invoker is trying to set the SGID bit on the file, + * check group membership. + */ + if (new_mode & S_ISGID) { + int ismember; + + error = kauth_cred_ismember_gid(cred, cur_gid, + &ismember); + if (error || !ismember) + return (EPERM); + } + + return (0); +} + +/* + * Common routine to check if chown() is allowed. + * + * Policy: + * - You must be root, or + * - You must own the file, and + * - You must not try to change ownership, and + * - You must be member of the new group + * + * cred - credentials of the invoker + * cur_uid, cur_gid - current uid/gid of the file-system object + * new_uid, new_gid - target uid/gid of the file-system object + * + * Returns 0 if the change is allowed, or an error value otherwise. + */ +int +genfs_can_chown(vnode_t *vp, kauth_cred_t cred, uid_t cur_uid, + gid_t cur_gid, uid_t new_uid, gid_t new_gid) +{ + int error, ismember; + + /* + * You can only change ownership of a file if: + * You are the superuser, or... + */ + error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, + NULL); + if (!error) + return (0); + + /* + * You own the file and... + */ + if (kauth_cred_geteuid(cred) == cur_uid) { + /* + * You don't try to change ownership, and... + */ + if (new_uid != cur_uid) + return (EPERM); + + /* + * You don't try to change group (no-op), or... + */ + if (new_gid == cur_gid) + return (0); + + /* + * Your effective gid is the new gid, or... + */ + if (kauth_cred_getegid(cred) == new_gid) + return (0); + + /* + * The new gid is one you're a member of. + */ + ismember = 0; + error = kauth_cred_ismember_gid(cred, new_gid, + &ismember); + if (error || !ismember) + return (EPERM); + } + + return (0); +} + Index: src/sys/sys/vnode.h diff -u src/sys/sys/vnode.h:1.204 src/sys/sys/vnode.h:1.205 --- src/sys/sys/vnode.h:1.204 Mon Apr 20 18:06:26 2009 +++ src/sys/sys/vnode.h Wed Apr 22 22:57:08 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode.h,v 1.204 2009/04/20 18:06:26 elad Exp $ */ +/* $NetBSD: vnode.h,v 1.205 2009/04/22 22:57:08 elad Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -664,9 +664,6 @@ void vfs_mount_print(struct mount *, int, void (*)(const char *, ...)); #endif /* DDB */ -int common_chmod_allowed(kauth_cred_t, struct vnode *, uid_t, gid_t, - mode_t); -int common_chown_allowed(kauth_cred_t, uid_t, gid_t, uid_t, gid_t); #endif /* _KERNEL */ #endif /* !_SYS_VNODE_H_ */ Index: src/sys/ufs/ext2fs/ext2fs_vnops.c diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.84 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.85 --- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.84 Mon Apr 20 18:06:27 2009 +++ src/sys/ufs/ext2fs/ext2fs_vnops.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.84 2009/04/20 18:06:27 elad Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.85 2009/04/22 22:57:09 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.84 2009/04/20 18:06:27 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.85 2009/04/22 22:57:09 elad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -444,7 +444,7 @@ struct inode *ip = VTOI(vp); int error; - error = common_chmod_allowed(cred, vp, ip->i_uid, ip->i_gid, mode); + error = genfs_can_chmod(vp, cred, ip->i_uid, ip->i_gid, mode); if (error) return (error); @@ -472,7 +472,7 @@ if (gid == (gid_t)VNOVAL) gid = ip->i_gid; - error = common_chown_allowed(cred, ip->i_uid, ip->i_gid, uid, gid); + error = genfs_can_chown(vp, cred, ip->i_uid, ip->i_gid, uid, gid); if (error) return (error); Index: src/sys/ufs/ufs/ufs_vnops.c diff -u src/sys/ufs/ufs/ufs_vnops.c:1.174 src/sys/ufs/ufs/ufs_vnops.c:1.175 --- src/sys/ufs/ufs/ufs_vnops.c:1.174 Mon Apr 20 18:06:27 2009 +++ src/sys/ufs/ufs/ufs_vnops.c Wed Apr 22 22:57:09 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.174 2009/04/20 18:06:27 elad Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.175 2009/04/22 22:57:09 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.174 2009/04/20 18:06:27 elad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.175 2009/04/22 22:57:09 elad Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -93,6 +93,7 @@ #include <miscfs/specfs/specdev.h> #include <miscfs/fifofs/fifo.h> +#include <miscfs/genfs/genfs.h> #include <ufs/ufs/inode.h> #include <ufs/ufs/dir.h> @@ -646,7 +647,7 @@ ip = VTOI(vp); - error = common_chmod_allowed(cred, vp, ip->i_uid, ip->i_gid, mode); + error = genfs_can_chmod(vp, cred, ip->i_uid, ip->i_gid, mode); if (error) return (error); @@ -681,7 +682,7 @@ if (gid == (gid_t)VNOVAL) gid = ip->i_gid; - error = common_chown_allowed(cred, ip->i_uid, ip->i_gid, uid, gid); + error = genfs_can_chown(vp, cred, ip->i_uid, ip->i_gid, uid, gid); if (error) return (error);