From owner-p4-projects@FreeBSD.ORG Sat Sep 9 10:00:45 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id EB59E16A47C; Sat, 9 Sep 2006 10:00:44 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A4C0816A403 for ; Sat, 9 Sep 2006 10:00:44 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E0B2143D45 for ; Sat, 9 Sep 2006 10:00:43 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k89A0hAZ024035 for ; Sat, 9 Sep 2006 10:00:43 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k89A0gQV024031 for perforce@freebsd.org; Sat, 9 Sep 2006 10:00:42 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Sat, 9 Sep 2006 10:00:42 GMT Message-Id: <200609091000.k89A0gQV024031@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 105880 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 09 Sep 2006 10:00:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=105880 Change 105880 by rwatson@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 - #ifndef _POSIX_MAC #define _POSIX_MAC #endif @@ -107,6 +105,9 @@ #else /* _KERNEL */ +#include +#include /* 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_ */