PERFORCE change 105880 for review
Robert Watson
rwatson at FreeBSD.org
Sat Sep 9 10:01:05 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=105880
Change 105880 by rwatson at rwatson_sesame on 2006/09/09 10:00:40
Hook up mac_priv.c, which contains the MAC entry points for both
denying and granting privilege. Add a new composition operator,
MAC_GRANT(), for the grant path. Add a sample policy, mac_privs,
which allows uid's to be assigned additional privileges using a
rule based system.
While here, update privileges, adding one for this policy,
renaming the mount_owner privilege, and removing the VFS revoke
privilege, which is actually just the vfs_admin privilege.
change ifdef's so that user space can include privs.h for use in
the management tool for mac_privs.c.
Affected files ...
.. //depot/projects/trustedbsd/priv/sys/conf/NOTES#3 edit
.. //depot/projects/trustedbsd/priv/sys/conf/files#3 edit
.. //depot/projects/trustedbsd/priv/sys/conf/options#2 edit
.. //depot/projects/trustedbsd/priv/sys/kern/kern_priv.c#2 edit
.. //depot/projects/trustedbsd/priv/sys/modules/Makefile#3 edit
.. //depot/projects/trustedbsd/priv/sys/modules/mac_privs/Makefile#1 add
.. //depot/projects/trustedbsd/priv/sys/security/mac/mac_internal.h#3 edit
.. //depot/projects/trustedbsd/priv/sys/security/mac/mac_priv.c#1 add
.. //depot/projects/trustedbsd/priv/sys/security/mac/mac_system.c#2 edit
.. //depot/projects/trustedbsd/priv/sys/security/mac_privs/mac_privs.c#1 add
.. //depot/projects/trustedbsd/priv/sys/security/mac_privs/mac_privs.h#1 add
.. //depot/projects/trustedbsd/priv/sys/sys/mac.h#2 edit
.. //depot/projects/trustedbsd/priv/sys/sys/mac_policy.h#2 edit
.. //depot/projects/trustedbsd/priv/sys/sys/priv.h#2 edit
Differences ...
==== //depot/projects/trustedbsd/priv/sys/conf/NOTES#3 (text+ko) ====
@@ -1001,6 +1001,7 @@
options MAC_NONE
options MAC_PARTITION
options MAC_PORTACL
+options MAC_PRIVS
options MAC_SEEOTHERUIDS
options MAC_STUB
options MAC_TEST
==== //depot/projects/trustedbsd/priv/sys/conf/files#3 (text+ko) ====
@@ -1912,6 +1912,7 @@
security/mac/mac_net.c optional mac
security/mac/mac_pipe.c optional mac
security/mac/mac_posix_sem.c optional mac
+security/mac/mac_priv.c optional mac
security/mac/mac_process.c optional mac
security/mac/mac_socket.c optional mac
security/mac/mac_system.c optional mac
@@ -1927,6 +1928,7 @@
security/mac_none/mac_none.c optional mac_none
security/mac_partition/mac_partition.c optional mac_partition
security/mac_portacl/mac_portacl.c optional mac_portacl
+security/mac_privs/mac_privs.c optional mac_privs
security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids
security/mac_stub/mac_stub.c optional mac_stub
security/mac_test/mac_test.c optional mac_test
==== //depot/projects/trustedbsd/priv/sys/conf/options#2 (text+ko) ====
@@ -110,6 +110,7 @@
MAC_NONE opt_dontuse.h
MAC_PARTITION opt_dontuse.h
MAC_PORTACL opt_dontuse.h
+MAC_PRIVS opt_dontuse.h
MAC_SEEOTHERUIDS opt_dontuse.h
MAC_STATIC opt_mac.h
MAC_STUB opt_dontuse.h
==== //depot/projects/trustedbsd/priv/sys/kern/kern_priv.c#2 (text+ko) ====
@@ -58,7 +58,8 @@
TUNABLE_INT("security.bsd.suser_enabled", &suser_enabled);
/*
- * Check a credential for privilege.
+ * Check a credential for privilege. Lots of good reasons to deny privilege;
+ * only a few to grant it.
*/
int
priv_check_cred(struct ucred *cred, enum priv priv, int flags)
@@ -68,44 +69,57 @@
KASSERT(PRIV_VALID(priv), ("priv_check_cred: invalid privilege %d",
priv));
-#if defined(MAC) && defined(NOTYET)
+#ifdef MAC
error = mac_priv_check(cred, priv);
if (error)
return (error);
#endif
+ /*
+ * Jail policy will restrict certain privileges that may otherwise be
+ * be granted.
+ *
+ * While debugging the transition from SUSER_ALLOWJAIL to Jail being
+ * aware of specific privileges, perform run-time checking that the
+ * two versions of the policy align. This assertion will go away
+ * once the SUSER_ALLOWJAIL flag has gone away.
+ */
error = prison_priv_check(cred, priv);
+ KASSERT(!jailed(cred) || error == ((flags & SUSER_ALLOWJAIL) ? 0 :
+ EPERM), ("priv_check_cred: prison_priv_check %d but flags %s",
+ error, flags & SUSER_ALLOWJAIL ? "allowjail" : "!allowjail"));
if (error)
return (error);
/*
- * XXXRW: Historic SUSER_ALLOWJAIL check, which allows the calling
- * context to specify whether this privilege is permissible in a
- * jail. This will go away shortly as we will be able to centralize
- * the decision in prison_priv_check().
+ * Having determined if privilege is restricted by various policies,
+ * now determine if privilege is granted. For now, we allow
+ * short-circuit boolean evaluation, so may not call all policies.
+ * Perhaps we should.
*
- * XXXRW: Consider an assertion that this never happens, as the
- * earlier prison_priv_check() function should have rejected it.
+ * Superuser policy grants privilege based on the effective (or in
+ * certain edge cases, real) uid being 0. We allow the policy to be
+ * globally disabled, although this is currently of limited uility.
*/
- if (jailed(cred) && !(flags & SUSER_ALLOWJAIL))
- return (EPERM);
+ if (suser_enabled) {
+ if (flags & SUSER_RUID) {
+ if (cred->cr_ruid == 0)
+ return (0);
+ } else {
+ if (cred->cr_uid == 0)
+ return (0);
+ }
+ }
/*
- * Global super-user privilege frob.
+ * Now check with MAC, if enabled, to see if a policy module grants
+ * privilege.
*/
- if (!suser_enabled)
- return (EPERM);
-
- /*
- * Check for uid 0.
- */
- if (((flags & SUSER_RUID) ? cred->cr_ruid : cred->cr_uid) != 0)
- return (EPERM);
-
- /*
- * Privilege is granted.
- */
- return (0);
+#ifdef MAC
+ if (mac_priv_grant(cred, priv) == 0)
+ return (0);
+#endif
+ return (EPERM);
}
int
==== //depot/projects/trustedbsd/priv/sys/modules/Makefile#3 (text+ko) ====
@@ -147,6 +147,7 @@
mac_none \
mac_partition \
mac_portacl \
+ mac_privs \
mac_seeotheruids \
mac_stub \
mac_test \
==== //depot/projects/trustedbsd/priv/sys/security/mac/mac_internal.h#3 (text+ko) ====
@@ -2,6 +2,7 @@
* Copyright (c) 1999-2002 Robert N. M. Watson
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2004 Networks Associates Technology, Inc.
+ * Copyright (c) 2006 nCircle Network Security, Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@@ -12,6 +13,9 @@
* Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
* as part of the DARPA CHATS research program.
*
+ * This software was developed by Robert N. M. Watson for the TrustedBSD
+ * Project under contract to nCircle Network Security, Inc.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -168,6 +172,36 @@
} while (0)
/*
+ * MAC_GRANT performs the designated check by walking the policy module
+ * list and checking with each as to how it feels about the request. Unlike
+ * MAC_CHECK, it grants if any policies return '0', and otherwise returns
+ * EPERM. Note that it returns its value via 'error' in the scope of the
+ * caller.
+ */
+#define MAC_GRANT(check, args...) do { \
+ struct mac_policy_conf *mpc; \
+ int entrycount; \
+ \
+ error = EPERM; \
+ LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list) { \
+ if (mpc->mpc_ops->mpo_ ## check != NULL) { \
+ if (mpc->mpc_ops->mpo_ ## check(args) == 0) \
+ error = 0; \
+ } \
+ } \
+ if ((entrycount = mac_policy_list_conditional_busy()) != 0) { \
+ LIST_FOREACH(mpc, &mac_policy_list, mpc_list) { \
+ if (mpc->mpc_ops->mpo_ ## check != NULL) { \
+ if (mpc->mpc_ops->mpo_ ## check (args) \
+ == 0) \
+ error = 0; \
+ } \
+ } \
+ mac_policy_list_unbusy(); \
+ } \
+} while (0)
+
+/*
* MAC_BOOLEAN performs the designated boolean composition by walking
* the module list, invoking each instance of the operation, and
* combining the results using the passed C operator. Note that it
==== //depot/projects/trustedbsd/priv/sys/security/mac/mac_system.c#2 (text+ko) ====
==== //depot/projects/trustedbsd/priv/sys/sys/mac.h#2 (text+ko) ====
@@ -47,8 +47,6 @@
#ifndef _SYS_MAC_H_
#define _SYS_MAC_H_
-#include <sys/_label.h>
-
#ifndef _POSIX_MAC
#define _POSIX_MAC
#endif
@@ -107,6 +105,9 @@
#else /* _KERNEL */
+#include <sys/_label.h>
+#include <sys/priv.h> /* XXXRW: Until name space issues resolved. */
+
/*
* Kernel functions to manage and evaluate labels.
*/
@@ -464,6 +465,8 @@
struct label *label);
void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred);
void mac_associate_nfsd_label(struct ucred *cred);
+int mac_priv_check(struct ucred *cred, enum priv priv);
+int mac_priv_grant(struct ucred *cred, enum priv priv);
/*
* Calls to help various file systems implement labeling functionality
==== //depot/projects/trustedbsd/priv/sys/sys/mac_policy.h#2 (text+ko) ====
@@ -68,6 +68,7 @@
struct mac_policy_conf;
struct mbuf;
struct mount;
+struct msg;
struct msqid_kernel;
struct pipepair;
struct proc;
@@ -590,6 +591,8 @@
struct ucred *file_cred, struct vnode *vp,
struct label *label);
typedef void (*mpo_associate_nfsd_label_t)(struct ucred *cred);
+typedef int (*mpo_priv_check_t)(struct ucred *cred, enum priv priv);
+typedef int (*mpo_priv_grant_t)(struct ucred *cred, enum priv priv);
struct mac_policy_ops {
/*
@@ -879,6 +882,8 @@
mpo_check_vnode_stat_t mpo_check_vnode_stat;
mpo_check_vnode_write_t mpo_check_vnode_write;
mpo_associate_nfsd_label_t mpo_associate_nfsd_label;
+ mpo_priv_check_t mpo_priv_check;
+ mpo_priv_grant_t mpo_priv_grant;
};
/*
==== //depot/projects/trustedbsd/priv/sys/sys/priv.h#2 (text+ko) ====
@@ -36,14 +36,6 @@
#define _SYS_PRIV_H_
/*
- * Eventually we may need to export the privilege list to user space. Until
- * then, don't do so unnecessarily.
- */
-#ifndef _KERNEL
-#error "no user-serviceable parts inside"
-#endif
-
-/*
* Privilege list. In no particular order.
*
* Think carefully before adding or reusing one of these privileges -- are
@@ -52,6 +44,9 @@
* modules. Particular numeric privilege assignments are part of the
* loadable kernel module ABI, and should not be changed across minor
* releases.
+ *
+ * When adding a new privilege, remember to determine if it's appropriate for
+ * use in jail, and update the privilege switch in kern_jail.c as necessary.
*/
enum priv {
/* Track beginning of privilege list. */
@@ -116,6 +111,7 @@
PRIV_KLD_LOAD, /* Load a kernel module. */
PRIV_KLD_UNLOAD, /* Unload a kernel module. */
PRIV_MAC_PARTITION, /* Privilege in mac_partition policy. */
+ PRIV_MAC_PRIVS, /* Privilege in the mac_privs policy. */
PRIV_PROC_LIMIT, /* Exceed user process limit. */
PRIV_PROC_SETLOGIN, /* Can call setlogin. */
PRIV_PROC_SETRLIMIT, /* Can raise resources limits. */
@@ -173,11 +169,10 @@
PRIV_VFS_LINK, /* bsd.hardlink_check_uid */
PRIV_VFS_MKNOD_DEV, /* Can create device nodes. */
PRIV_VFS_MOUNT, /* Can mount(). */
- PRIV_VFS_MOUNTOWNER, /* Override owner on user mounts. */
+ PRIV_VFS_MOUNT_OWNER, /* Override owner on user mounts. */
PRIV_VFS_MOUNT_EXPORTED, /* Can set MNT_EXPORTED on mount. */
PRIV_VFS_MOUNT_PERM, /* Override device node perms at mount. */
PRIV_VFS_MOUNT_SUIDDIR, /* Can set MNT_SUIDDIR on mount. */
- PRIV_VFS_REVOKE, /* Can revoke(). */
PRIV_VFS_SETGID, /* Can setgid if not in group. */
PRIV_VFS_STICKYFILE, /* Can set sticky bit on file. */
PRIV_VFS_SYSFLAGS, /* Can modify system flags. */
@@ -297,6 +292,7 @@
*/
#define PRIV_VALID(x) ((x) > _PRIV_LOWEST && (x) < _PRIV_HIGHEST)
+#ifdef _KERNEL
/*
* Privilege check interfaces, modeled after historic suser() interfacs, but
* with the addition of a specific privilege name. The existing SUSER_* flag
@@ -308,5 +304,6 @@
struct ucred;
int priv_check(struct thread *td, enum priv priv);
int priv_check_cred(struct ucred *cred, enum priv priv, int flags);
+#endif
#endif /* !_SYS_PRIV_H_ */
More information about the trustedbsd-cvs
mailing list