Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Implement the vnode scope and adapt tmpfs to use it.



details:   https://anonhg.NetBSD.org/src/rev/a9ca7db86787
branches:  trunk
changeset: 747115:a9ca7db86787
user:      elad <elad%NetBSD.org@localhost>
date:      Thu Sep 03 04:45:27 2009 +0000

description:
Implement the vnode scope and adapt tmpfs to use it.

Mailing list reference:

        http://mail-index.netbsd.org/tech-kern/2009/07/04/msg005404.html

diffstat:

 sys/fs/tmpfs/tmpfs_subr.c                       |  71 +++++++++++++------
 sys/fs/tmpfs/tmpfs_vnops.c                      |  31 +++++++-
 sys/kern/kern_auth.c                            |  87 ++++++++++++++++++++++--
 sys/secmodel/bsd44/secmodel_bsd44_suser.c       |  28 +++++++-
 sys/secmodel/bsd44/suser.h                      |   4 +-
 sys/secmodel/securelevel/secmodel_securelevel.c |  28 +++++++-
 sys/secmodel/securelevel/securelevel.h          |   4 +-
 sys/sys/kauth.h                                 |  44 ++++++++++++-
 8 files changed, 251 insertions(+), 46 deletions(-)

diffs (truncated from 600 to 300 lines):

diff -r 6df61c30dedb -r a9ca7db86787 sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c Thu Sep 03 01:17:29 2009 +0000
+++ b/sys/fs/tmpfs/tmpfs_subr.c Thu Sep 03 04:45:27 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_subr.c,v 1.53 2009/05/07 19:30:30 elad Exp $     */
+/*     $NetBSD: tmpfs_subr.c,v 1.54 2009/09/03 04:45:28 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.53 2009/05/07 19:30:30 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.54 2009/09/03 04:45:28 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -964,6 +964,8 @@
 {
        int error;
        struct tmpfs_node *node;
+       kauth_action_t = KAUTH_VNODE_WRITE_FLAGS;
+       int fs_decision = 0;
 
        KASSERT(VOP_ISLOCKED(vp));
 
@@ -973,30 +975,44 @@
        if (vp->v_mount->mnt_flag & MNT_RDONLY)
                return EROFS;
 
-       /* XXX: The following comes from UFS code, and can be found in
-        * several other file systems.  Shouldn't this be centralized
-        * somewhere? */
-       if (kauth_cred_geteuid(cred) != node->tn_uid &&
-           (error = kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
-           NULL)))
+       if (kauth_cred_geteuid(cred) != node->tn_uid)
+               fs_decision = EACCES;
+
+       /*
+        * If the new flags have non-user flags that are different than
+        * those on the node, we need special permission to change them.
+        */
+       if ((flags & SF_SETTABLE) != (node->tn_flags & SF_SETTABLE)) {
+               action |= KAUTH_VNODE_WRITE_SYSFLAGS;
+               if (!fs_decision)
+                       fs_decision = EPERM;
+       }
+
+       /*
+        * Indicate that this node's flags have system attributes in them if
+        * that's the case.
+        */
+       if (node->tn_flags & (SF_IMMUTABLE | SF_APPEND)) {
+               action |= KAUTH_VNODE_HAS_SYSFLAGS;
+       }
+
+       error = kauth_authorize_vnode(cred, action, vp, NULL, fs_decision);
+       if (error)
                return error;
-       if (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER, NULL) == 0) {
-               /* The super-user is only allowed to change flags if the file
-                * wasn't protected before and the securelevel is zero. */
-               if ((node->tn_flags & (SF_IMMUTABLE | SF_APPEND)) &&
-                   kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_CHSYSFLAGS,
-                    0, NULL, NULL, NULL))
-                       return EPERM;
+
+       /*
+        * Set the flags. If we're not setting non-user flags, be careful not
+        * to overwrite them.
+        *
+        * XXX: Can't we always assign here? if the system flags are different,
+        *      the code above should catch attempts to change them without
+        *      proper permissions, and if we're here it means it's okay to
+        *      change them...
+        */
+       if (action & KAUTH_VNODE_WRITE_SYSFLAGS) {
                node->tn_flags = flags;
        } else {
-               /* Regular users can change flags provided they only want to
-                * change user-specific ones, not those reserved for the
-                * super-user. */
-               if ((node->tn_flags & (SF_IMMUTABLE | SF_APPEND)) ||
-                   (flags & UF_SETTABLE) != flags)
-                       return EPERM;
-               if ((node->tn_flags & SF_SETTABLE) != (flags & SF_SETTABLE))
-                       return EPERM;
+               /* Clear all user-settable flags and re-set them. */
                node->tn_flags &= SF_SETTABLE;
                node->tn_flags |= (flags & UF_SETTABLE);
        }
@@ -1036,6 +1052,9 @@
 
        error = genfs_can_chmod(vp, cred, node->tn_uid, node->tn_gid,
            mode);
+
+       error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_SECURITY, vp,
+           NULL, error);
        if (error)
                return (error);
 
@@ -1087,6 +1106,9 @@
 
        error = genfs_can_chown(vp, cred, node->tn_uid, node->tn_gid, uid,
            gid);
+
+       error = kauth_authorize_vnode(cred, KAUTH_VNODE_CHANGE_OWNERSHIP, vp,
+           NULL, error);
        if (error)
                return (error);
 
@@ -1186,6 +1208,9 @@
                return EPERM;
 
        error = genfs_can_chtimes(vp, vaflags, node->tn_uid, cred);
+
+       error = kauth_authorize_vnode(cred, KAUTH_VNODE_WRITE_TIMES, vp, NULL,
+           error);
        if (error)
                return (error);
 
diff -r 6df61c30dedb -r a9ca7db86787 sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c        Thu Sep 03 01:17:29 2009 +0000
+++ b/sys/fs/tmpfs/tmpfs_vnops.c        Thu Sep 03 04:45:27 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tmpfs_vnops.c,v 1.61 2009/07/03 21:17:41 elad Exp $    */
+/*     $NetBSD: tmpfs_vnops.c,v 1.62 2009/09/03 04:45:28 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.61 2009/07/03 21:17:41 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.62 2009/09/03 04:45:28 elad Exp $");
 
 #include <sys/param.h>
 #include <sys/dirent.h>
@@ -209,15 +209,31 @@
                        if ((cnp->cn_flags & ISLASTCN) &&
                            (cnp->cn_nameiop == DELETE ||
                            cnp->cn_nameiop == RENAME)) {
+                               kauth_action_t action = 0;
+
+                               /* This is the file-system's decision. */
                                if ((dnode->tn_mode & S_ISTXT) != 0 &&
-                                   kauth_authorize_generic(cnp->cn_cred,
-                                    KAUTH_GENERIC_ISSUSER, NULL) != 0 &&
                                    kauth_cred_geteuid(cnp->cn_cred) != dnode->tn_uid &&
                                    kauth_cred_geteuid(cnp->cn_cred) != tnode->tn_uid)
-                                       return EPERM;
-                               error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+                                       error = EPERM;
+                               else
+                                       error = 0;
+
+                               /* Only bother if we're not already failing it. */
+                               if (!error) {
+                                       error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred);
+                               }
+
+                               if (cnp->cn_nameiop == DELETE)
+                                       action |= KAUTH_VNODE_DELETE;
+                               else /* if (cnp->cn_nameiop == RENAME) */
+                                       action |= KAUTH_VNODE_RENAME;
+
+                               error = kauth_authorize_vnode(cnp->cn_cred,
+                                   action, *vpp, dvp, error);
                                if (error != 0)
                                        goto out;
+
                                cnp->cn_flags |= SAVENAME;
                        } else
                                de = NULL;
@@ -406,6 +422,9 @@
 
        error = tmpfs_check_permitted(vp, node, mode, cred);
 
+       error = kauth_authorize_vnode(cred, kauth_mode_to_action(mode), vp,
+           NULL, error);
+
 out:
        KASSERT(VOP_ISLOCKED(vp));
 
diff -r 6df61c30dedb -r a9ca7db86787 sys/kern/kern_auth.c
--- a/sys/kern/kern_auth.c      Thu Sep 03 01:17:29 2009 +0000
+++ b/sys/kern/kern_auth.c      Thu Sep 03 04:45:27 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_auth.c,v 1.63 2009/08/16 11:01:12 yamt Exp $ */
+/* $NetBSD: kern_auth.c,v 1.64 2009/09/03 04:45:27 elad Exp $ */
 
 /*-
  * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_auth.c,v 1.63 2009/08/16 11:01:12 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_auth.c,v 1.64 2009/09/03 04:45:27 elad Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -68,6 +68,7 @@
 #include <sys/sysctl.h>                /* for pi_[p]cread */
 #include <sys/atomic.h>
 #include <sys/specificdata.h>
+#include <sys/vnode.h>
 
 /*
  * Secmodel-specific credentials.
@@ -142,6 +143,7 @@
 static kauth_scope_t kauth_builtin_scope_machdep;
 static kauth_scope_t kauth_builtin_scope_device;
 static kauth_scope_t kauth_builtin_scope_cred;
+static kauth_scope_t kauth_builtin_scope_vnode;
 
 static unsigned int nsecmodels = 0;
 
@@ -831,6 +833,10 @@
        /* Register device scope. */
        kauth_builtin_scope_device = kauth_register_scope(KAUTH_SCOPE_DEVICE,
            NULL, NULL);
+
+       /* Register vnode scope. */
+       kauth_builtin_scope_vnode = kauth_register_scope(KAUTH_SCOPE_VNODE,
+           NULL, NULL);
 }
 
 /*
@@ -924,11 +930,16 @@
  * credential - credentials of the user ("actor") making the request.
  * action - request identifier.
  * arg[0-3] - passed unmodified to listener(s).
+ *
+ * Returns the aggregated result:
+ *     - KAUTH_RESULT_ALLOW if there is at least one KAUTH_RESULT_ALLOW and
+ *       zero KAUTH_DESULT_DENY
+ *     - KAUTH_RESULT_DENY if there is at least one KAUTH_RESULT_DENY
+ *     - KAUTH_RESULT_DEFER if there is nothing but KAUTH_RESULT_DEFER
  */
-int
-kauth_authorize_action(kauth_scope_t scope, kauth_cred_t cred,
-                      kauth_action_t action, void *arg0, void *arg1,
-                      void *arg2, void *arg3)
+static int
+kauth_authorize_action_internal(kauth_scope_t scope, kauth_cred_t cred,
+    kauth_action_t action, void *arg0, void *arg1, void *arg2, void *arg3)
 {
        kauth_listener_t listener;
        int error, allow, fail;
@@ -958,16 +969,34 @@
        /* rw_exit(&kauth_lock); */
 
        if (fail)
+               return (KAUTH_RESULT_DENY);
+
+       if (allow)
+               return (KAUTH_RESULT_ALLOW);
+
+       return (KAUTH_RESULT_DEFER);
+};
+
+int
+kauth_authorize_action(kauth_scope_t scope, kauth_cred_t cred,
+    kauth_action_t action, void *arg0, void *arg1, void *arg2, void *arg3)
+{
+       int r;
+
+       r = kauth_authorize_action_internal(scope, cred, action, arg0, arg1,
+           arg2, arg3);
+
+       if (r == KAUTH_RESULT_DENY)
                return (EPERM);
 
-       if (allow)
+       if (r == KAUTH_RESULT_ALLOW)
                return (0);
 
        if (!nsecmodels)
                return (0);
 
        return (EPERM);
-};
+}
 
 /*
  * Generic scope authorization wrapper.
@@ -1053,6 +1082,48 @@
            data, NULL));
 }
 
+kauth_action_t
+kauth_mode_to_action(mode_t mode)
+{
+       kauth_action_t action = 0;
+
+       if (mode & VREAD)



Home | Main Index | Thread Index | Old Index