Hi,
I'd like to start implementing the vnode scope for some of our
file-systems. As with the rest of kauth(9), we'll do so in several
steps, rather than switch all functionality at once.
The first step will be implementing the back-end itself: the scope
definition, some actions (just read/write/execute for now), an
authorization wrapper, and a bsd44/suser simple listener ("if root
or file-system allows then allow") -- see the attached diff.
Once the back-end is in place, I'll follow-up with some more diffs
transitioning various file-systems to use kauth(9) in different places
-- access, chflags, chmod, etc.
Please review. :)
Thanks,
-e.
Index: kern/kern_auth.c
===================================================================
RCS file: /usr/cvs/src/sys/kern/kern_auth.c,v
retrieving revision 1.62
diff -u -p -r1.62 kern_auth.c
--- kern/kern_auth.c 5 Apr 2009 11:50:51 -0000 1.62
+++ kern/kern_auth.c 3 Jul 2009 23:21:31 -0000
@@ -142,6 +142,7 @@ static kauth_scope_t kauth_builtin_scope
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;
@@ -830,6 +831,10 @@ kauth_init(void)
/* 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);
}
/*
@@ -1052,6 +1057,24 @@ kauth_authorize_device_passthru(kauth_cr
data, NULL));
}
+int
+kauth_authorize_vnode(kauth_cred_t cred, kauth_action_t action,
+ struct vnode *vp, struct vnode *dvp, int fs_decision)
+{
+ int error;
+
+ error = kauth_authorize_action(kauth_builtin_scope_vnode, cred,
+ action, vp, dvp, KAUTH_ARG(fs_decision), NULL);
+
+ if (error)
+ error = EACCES;
+
+ if (!nsecmodels)
+ error = fs_decision;
+
+ return error;
+}
+
static int
kauth_cred_hook(kauth_cred_t cred, kauth_action_t action, void *arg0,
void *arg1)
Index: sys/kauth.h
===================================================================
RCS file: /usr/cvs/src/sys/sys/kauth.h,v
retrieving revision 1.59
diff -u -p -r1.59 kauth.h
--- sys/kauth.h 8 May 2009 11:09:43 -0000 1.59
+++ sys/kauth.h 3 Jul 2009 23:21:08 -0000
@@ -67,6 +67,7 @@ typedef struct kauth_key *kauth_ke
#define KAUTH_SCOPE_MACHDEP "org.netbsd.kauth.machdep"
#define KAUTH_SCOPE_DEVICE "org.netbsd.kauth.device"
#define KAUTH_SCOPE_CRED "org.netbsd.kauth.cred"
+#define KAUTH_SCOPE_VNODE "org.netbsd.kauth.vnode"
/*
* Generic scope - actions.
@@ -282,6 +283,18 @@ enum {
};
/*
+ * Vnode scope - actions.
+ */
+#define KAUTH_VNODE_READ_DATA (1 << 0)
+#define KAUTH_VNODE_LIST_DIRECTORY KAUTH_VNODE_READ_DATA
+#define KAUTH_VNODE_WRITE_DATA (1 << 1)
+#define KAUTH_VNODE_ADD_FILE KAUTH_VNODE_WRITE_DATA
+#define KAUTH_VNODE_EXECUTE (1 << 2)
+#define KAUTH_VNODE_SEARCH KAUTH_VNODE_EXECUTE
+
+#define KAUTH_VNODE_ACCESS (1 << 31)
+
+/*
* Device scope, passthru request - identifiers.
*/
#define KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READ 0x00000001
@@ -323,6 +336,8 @@ int kauth_authorize_device_tty(kauth_cre
int kauth_authorize_device_spec(kauth_cred_t, enum kauth_device_req,
struct vnode *);
int kauth_authorize_device_passthru(kauth_cred_t, dev_t, u_long,
void *);
+int kauth_authorize_vnode(kauth_cred_t, kauth_action_t, struct
vnode *,
+ struct vnode *, int);
/* Kauth credentials management routines. */
kauth_cred_t kauth_cred_alloc(void);
Index: secmodel/bsd44/secmodel_bsd44_suser.c
===================================================================
RCS file: /usr/cvs/src/sys/secmodel/bsd44/secmodel_bsd44_suser.c,v
retrieving revision 1.67
diff -u -p -r1.67 secmodel_bsd44_suser.c
--- secmodel/bsd44/secmodel_bsd44_suser.c 8 May 2009 11:09:43 -0000
1.67
+++ secmodel/bsd44/secmodel_bsd44_suser.c 3 Jul 2009 23:22:39 -0000
@@ -65,7 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: secmodel_bsd
extern int dovfsusermount;
static kauth_listener_t l_generic, l_system, l_process, l_network,
l_machdep,
- l_device;
+ l_device, l_vnode;
void
secmodel_bsd44_suser_start(void)
@@ -82,6 +82,8 @@ secmodel_bsd44_suser_start(void)
secmodel_bsd44_suser_machdep_cb, NULL);
l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
secmodel_bsd44_suser_device_cb, NULL);
+ l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
+ secmodel_bsd44_suser_vnode_cb, NULL);
}
#if defined(_LKM)
@@ -94,6 +96,7 @@ secmodel_bsd44_suser_stop(void)
kauth_unlisten_scope(l_network);
kauth_unlisten_scope(l_machdep);
kauth_unlisten_scope(l_device);
+ kauth_unlisten_scope(l_vnode);
}
#endif /* _LKM */
@@ -1157,3 +1160,27 @@ secmodel_bsd44_suser_device_cb(kauth_cre
return (result);
}
+
+int
+secmodel_bsd44_suser_vnode_cb(kauth_cred_t cred, kauth_action_t
action,
+ void *cookie, void *arg0, void *arg1, void *arg2,
+ void *arg3)
+{
+ bool isroot;
+ int result;
+ struct vnode *vp, *dvp;
+ int fs_decision;
+
+ isroot = (kauth_cred_geteuid(cred) == 0);
+ result = KAUTH_RESULT_DEFER;
+
+ vp = arg0;
+ dvp = arg1;
+ fs_decision = (int)(unsigned long)arg2;