Introduce two related changes to the TrustedBSD MAC Framework:

(1) Abstract interpreter vnode labeling in execve(2) and mac_execve(2)
    so that the general exec code isn't aware of the details of
    allocating, copying, and freeing labels, rather, simply passes in
    a void pointer to start and stop functions that will be used by
    the framework.  This change will be MFC'd.

(2) Introduce a new flags field to the MAC_POLICY_SET(9) interface
    allowing policies to declare which types of objects require label
    allocation, initialization, and destruction, and define a set of
    flags covering various supported object types (MPC_OBJECT_PROC,
    MPC_OBJECT_VNODE, MPC_OBJECT_INPCB, ...).  This change reduces the
    overhead of compiling the MAC Framework into the kernel if policies
    aren't loaded, or if policies require labels on only a small number
    or even no object types.  Each time a policy is loaded or unloaded,
    we recalculate a mask of labeled object types across all policies
    present in the system.  Eliminate MAC_ALWAYS_LABEL_MBUF option as it
    is no longer required.

MFC after:	1 week ((1) only)
Reviewed by:	csjp
Obtained from:	TrustedBSD Project
Sponsored by:	Apple, Inc.
This commit is contained in:
Robert Watson 2008-08-23 15:26:36 +00:00
parent 99448af81e
commit 6356dba0b4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=182063
29 changed files with 461 additions and 169 deletions

View File

@ -114,7 +114,6 @@ KTRACE
KTRACE_REQUEST_POOL opt_ktrace.h
LIBICONV
MAC
MAC_ALWAYS_LABEL_MBUF opt_mac.h
MAC_BIBA opt_dontuse.h
MAC_BSDEXTENDED opt_dontuse.h
MAC_IFOFF opt_dontuse.h

View File

@ -336,7 +336,7 @@ do_execve(td, args, mac_p)
int vfslocked;
int textset;
#ifdef MAC
struct label *interplabel = NULL;
struct label *interpvplabel = NULL;
int will_transition;
#endif
#ifdef HWPMC_HOOKS
@ -494,8 +494,7 @@ do_execve(td, args, mac_p)
if (args->fname != NULL)
NDFREE(ndp, NDF_ONLY_PNBUF);
#ifdef MAC
interplabel = mac_vnode_label_alloc();
mac_vnode_copy_label(binvp->v_label, interplabel);
mac_execve_interpreter_enter(binvp, &interpvplabel);
#endif
if (imgp->opened) {
VOP_CLOSE(binvp, FREAD, td->td_ucred, td);
@ -627,7 +626,7 @@ do_execve(td, args, mac_p)
attr.va_gid;
#ifdef MAC
will_transition = mac_vnode_execve_will_transition(oldcred, imgp->vp,
interplabel, imgp);
interpvplabel, imgp);
credential_changing |= will_transition;
#endif
@ -681,7 +680,7 @@ do_execve(td, args, mac_p)
#ifdef MAC
if (will_transition) {
mac_vnode_execve_transition(oldcred, newcred, imgp->vp,
interplabel, imgp);
interpvplabel, imgp);
}
#endif
/*
@ -880,8 +879,7 @@ do_execve(td, args, mac_p)
done2:
#ifdef MAC
mac_execve_exit(imgp);
if (interplabel != NULL)
mac_vnode_label_free(interplabel);
mac_execve_interpreter_exit(interpvplabel);
#endif
VFS_UNLOCK_GIANT(vfslocked);
exec_free_args(args);

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -125,22 +126,14 @@ SYSCTL_UINT(_security_mac, OID_AUTO, max_slots, CTLFLAG_RD, &mac_max_slots,
static int mac_late = 0;
/*
* Flag to indicate whether or not we should allocate label storage for new
* mbufs. Since most dynamic policies we currently work with don't rely on
* mbuf labeling, try to avoid paying the cost of mtag allocation unless
* specifically notified of interest. One result of this is that if a
* dynamically loaded policy requests mbuf labels, it must be able to deal
* with a NULL label being returned on any mbufs that were already in flight
* when the policy was loaded. Since the policy already has to deal with
* uninitialized labels, this probably won't be a problem. Note: currently
* no locking. Will this be a problem?
*
* In the future, we may want to allow objects to request labeling on a per-
* object type basis, rather than globally for all objects.
* Each policy declares a mask of object types requiring labels to be
* allocated for them. For convenience, we combine and cache the bitwise or
* of the per-policy object flags to track whether we will allocate a label
* for an object type at run-time.
*/
#ifndef MAC_ALWAYS_LABEL_MBUF
int mac_labelmbufs = 0;
#endif
uint64_t mac_labeled;
SYSCTL_QUAD(_security_mac, OID_AUTO, labeled, CTLFLAG_RD, &mac_labeled, 0,
"Mask of object types being labeled");
MALLOC_DEFINE(M_MACTEMP, "mactemp", "MAC temporary label storage");
@ -344,23 +337,15 @@ mac_late_init(void)
static void
mac_policy_updateflags(void)
{
#ifndef MAC_ALWAYS_LABEL_MBUF
struct mac_policy_conf *tmpc;
int labelmbufs;
struct mac_policy_conf *mpc;
mac_policy_assert_exclusive();
labelmbufs = 0;
LIST_FOREACH(tmpc, &mac_static_policy_list, mpc_list) {
if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
labelmbufs++;
}
LIST_FOREACH(tmpc, &mac_policy_list, mpc_list) {
if (tmpc->mpc_loadtime_flags & MPC_LOADTIME_FLAG_LABELMBUFS)
labelmbufs++;
}
mac_labelmbufs = (labelmbufs != 0);
#endif
mac_labeled = 0;
LIST_FOREACH(mpc, &mac_static_policy_list, mpc_list)
mac_labeled |= mpc->mpc_labeled;
LIST_FOREACH(mpc, &mac_policy_list, mpc_list)
mac_labeled |= mpc->mpc_labeled;
}
static int

View File

@ -249,9 +249,12 @@ int mac_proc_check_wait(struct ucred *cred, struct proc *p);
void mac_proc_create_init(struct ucred *cred);
void mac_proc_create_swapper(struct ucred *cred);
void mac_proc_destroy(struct proc *);
void mac_proc_init(struct proc *);
int mac_execve_enter(struct image_params *imgp, struct mac *mac_p);
void mac_execve_exit(struct image_params *imgp);
void mac_proc_init(struct proc *);
void mac_execve_interpreter_enter(struct vnode *interpvp,
struct label **interplabel);
void mac_execve_interpreter_exit(struct label *interpvplabel);
int mac_socket_check_accept(struct ucred *cred, struct socket *so);
int mac_socket_check_bind(struct ucred *cred, struct socket *so,
@ -422,11 +425,6 @@ int mac_vnode_execve_will_transition(struct ucred *cred,
void mac_vnode_relabel(struct ucred *cred, struct vnode *vp,
struct label *newlabel);
struct label *mac_cred_label_alloc(void);
void mac_cred_label_free(struct label *);
struct label *mac_vnode_label_alloc(void);
void mac_vnode_label_free(struct label *);
void mac_cred_mmapped_drop_perms(struct thread *td, struct ucred *cred);
/*

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2004 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -91,9 +92,12 @@ int
mac_inpcb_init(struct inpcb *inp, int flag)
{
inp->inp_label = mac_inpcb_label_alloc(flag);
if (inp->inp_label == NULL)
return (ENOMEM);
if (mac_labeled & MPC_OBJECT_INPCB) {
inp->inp_label = mac_inpcb_label_alloc(flag);
if (inp->inp_label == NULL)
return (ENOMEM);
} else
inp->inp_label = NULL;
return (0);
}
@ -120,9 +124,12 @@ int
mac_ipq_init(struct ipq *q, int flag)
{
q->ipq_label = mac_ipq_label_alloc(flag);
if (q->ipq_label == NULL)
return (ENOMEM);
if (mac_labeled & MPC_OBJECT_IPQ) {
q->ipq_label = mac_ipq_label_alloc(flag);
if (q->ipq_label == NULL)
return (ENOMEM);
} else
q->ipq_label = NULL;
return (0);
}
@ -138,8 +145,10 @@ void
mac_inpcb_destroy(struct inpcb *inp)
{
mac_inpcb_label_free(inp->inp_label);
inp->inp_label = NULL;
if (inp->inp_label != NULL) {
mac_inpcb_label_free(inp->inp_label);
inp->inp_label = NULL;
}
}
static void
@ -154,8 +163,10 @@ void
mac_ipq_destroy(struct ipq *q)
{
mac_ipq_label_free(q->ipq_label);
q->ipq_label = NULL;
if (q->ipq_label != NULL) {
mac_ipq_label_free(q->ipq_label);
q->ipq_label = NULL;
}
}
void
@ -349,9 +360,11 @@ void
mac_syncache_destroy(struct label **label)
{
MAC_PERFORM(syncache_destroy_label, *label);
mac_labelzone_free(*label);
*label = NULL;
if (*label != NULL) {
MAC_PERFORM(syncache_destroy_label, *label);
mac_labelzone_free(*label);
*label = NULL;
}
}
int
@ -359,21 +372,26 @@ mac_syncache_init(struct label **label)
{
int error;
*label = mac_labelzone_alloc(M_NOWAIT);
if (*label == NULL)
return (ENOMEM);
/*
* Since we are holding the inpcb locks the policy can not allocate
* policy specific label storage using M_WAITOK. So we need to do a
* MAC_CHECK instead of the typical MAC_PERFORM so we can propagate
* allocation failures back to the syncache code.
*/
MAC_CHECK(syncache_init_label, *label, M_NOWAIT);
if (error) {
MAC_PERFORM(syncache_destroy_label, *label);
mac_labelzone_free(*label);
}
return (error);
if (mac_labeled & MPC_OBJECT_SYNCACHE) {
*label = mac_labelzone_alloc(M_NOWAIT);
if (*label == NULL)
return (ENOMEM);
/*
* Since we are holding the inpcb locks the policy can not
* allocate policy specific label storage using M_WAITOK. So
* we need to do a MAC_CHECK instead of the typical
* MAC_PERFORM so we can propagate allocation failures back
* to the syncache code.
*/
MAC_CHECK(syncache_init_label, *label, M_NOWAIT);
if (error) {
MAC_PERFORM(syncache_destroy_label, *label);
mac_labelzone_free(*label);
}
return (error);
} else
*label = NULL;
return (0);
}
void

View File

@ -88,9 +88,7 @@ struct label {
*/
extern struct mac_policy_list_head mac_policy_list;
extern struct mac_policy_list_head mac_static_policy_list;
#ifndef MAC_ALWAYS_LABEL_MBUF
extern int mac_labelmbufs;
#endif
extern uint64_t mac_labeled;
extern struct mtx mac_ifnet_mtx;
/*
@ -121,10 +119,14 @@ int mac_allocate_slot(void);
* MAC Framework per-object type functions. It's not yet clear how the
* namespaces, etc, should work for these, so for now, sort by object type.
*/
struct label *mac_cred_label_alloc(void);
void mac_cred_label_free(struct label *label);
struct label *mac_pipe_label_alloc(void);
void mac_pipe_label_free(struct label *label);
struct label *mac_socket_label_alloc(int flag);
void mac_socket_label_free(struct label *label);
struct label *mac_vnode_label_alloc(void);
void mac_vnode_label_free(struct label *label);
int mac_cred_check_relabel(struct ucred *cred, struct label *newlabel);
int mac_cred_externalize_label(struct label *label, char *elements,

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2004 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -112,7 +113,10 @@ void
mac_bpfdesc_init(struct bpf_d *d)
{
d->bd_label = mac_bpfdesc_label_alloc();
if (mac_labeled & MPC_OBJECT_BPFDESC)
d->bd_label = mac_bpfdesc_label_alloc();
else
d->bd_label = NULL;
}
static struct label *
@ -129,7 +133,10 @@ void
mac_ifnet_init(struct ifnet *ifp)
{
ifp->if_label = mac_ifnet_label_alloc();
if (mac_labeled & MPC_OBJECT_IFNET)
ifp->if_label = mac_ifnet_label_alloc();
else
ifp->if_label = NULL;
}
int
@ -157,24 +164,18 @@ mac_mbuf_init(struct mbuf *m, int flag)
M_ASSERTPKTHDR(m);
#ifndef MAC_ALWAYS_LABEL_MBUF
/*
* If conditionally allocating mbuf labels, don't allocate unless
* they are required.
*/
if (!mac_labelmbufs)
return (0);
#endif
tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
flag);
if (tag == NULL)
return (ENOMEM);
error = mac_mbuf_tag_init(tag, flag);
if (error) {
m_tag_free(tag);
return (error);
if (mac_labeled & MPC_OBJECT_MBUF) {
tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
flag);
if (tag == NULL)
return (ENOMEM);
error = mac_mbuf_tag_init(tag, flag);
if (error) {
m_tag_free(tag);
return (error);
}
m_tag_prepend(m, tag);
}
m_tag_prepend(m, tag);
return (0);
}
@ -190,8 +191,10 @@ void
mac_bpfdesc_destroy(struct bpf_d *d)
{
mac_bpfdesc_label_free(d->bd_label);
d->bd_label = NULL;
if (d->bd_label != NULL) {
mac_bpfdesc_label_free(d->bd_label);
d->bd_label = NULL;
}
}
static void
@ -206,8 +209,10 @@ void
mac_ifnet_destroy(struct ifnet *ifp)
{
mac_ifnet_label_free(ifp->if_label);
ifp->if_label = NULL;
if (ifp->if_label != NULL) {
mac_ifnet_label_free(ifp->if_label);
ifp->if_label = NULL;
}
}
void
@ -359,6 +364,9 @@ mac_ifnet_ioctl_get(struct ucred *cred, struct ifreq *ifr,
struct mac mac;
int error;
if (!(mac_labeled & MPC_OBJECT_IFNET))
return (EINVAL);
error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
if (error)
return (error);
@ -399,6 +407,9 @@ mac_ifnet_ioctl_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifp)
char *buffer;
int error;
if (!(mac_labeled & MPC_OBJECT_IFNET))
return (EINVAL);
error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
if (error)
return (error);

View File

@ -68,7 +68,10 @@ void
mac_pipe_init(struct pipepair *pp)
{
pp->pp_label = mac_pipe_label_alloc();
if (mac_labeled & MPC_OBJECT_PIPE)
pp->pp_label = mac_pipe_label_alloc();
else
pp->pp_label = NULL;
}
void
@ -83,8 +86,10 @@ void
mac_pipe_destroy(struct pipepair *pp)
{
mac_pipe_label_free(pp->pp_label);
pp->pp_label = NULL;
if (pp->pp_label != NULL) {
mac_pipe_label_free(pp->pp_label);
pp->pp_label = NULL;
}
}
void

View File

@ -2,6 +2,7 @@
* Copyright (c) 1999-2002, 2007 Robert N. M. Watson
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -929,17 +930,44 @@ struct mac_policy_conf {
int mpc_loadtime_flags; /* flags */
int *mpc_field_off; /* security field */
int mpc_runtime_flags; /* flags */
int _mpc_spare1; /* Spare. */
uint64_t mpc_labeled; /* Labeled objects. */
uint64_t _mpc_spare2; /* Spare. */
void *_mpc_spare3; /* Spare. */
LIST_ENTRY(mac_policy_conf) mpc_list; /* global list */
};
/* Flags for the mpc_loadtime_flags field. */
#define MPC_LOADTIME_FLAG_NOTLATE 0x00000001
#define MPC_LOADTIME_FLAG_UNLOADOK 0x00000002
#define MPC_LOADTIME_FLAG_LABELMBUFS 0x00000004
/* Flags for the mpc_runtime_flags field. */
#define MPC_RUNTIME_FLAG_REGISTERED 0x00000001
/*
* Flags for mpc_labeled declaring which objects should have labels allocated
* for them by the MAC Framework.
*/
#define MPC_OBJECT_CRED 0x0000000000000001
#define MPC_OBJECT_PROC 0x0000000000000002
#define MPC_OBJECT_VNODE 0x0000000000000004
#define MPC_OBJECT_INPCB 0x0000000000000008
#define MPC_OBJECT_SOCKET 0x0000000000000010
#define MPC_OBJECT_DEVFS 0x0000000000000020
#define MPC_OBJECT_MBUF 0x0000000000000040
#define MPC_OBJECT_IPQ 0x0000000000000080
#define MPC_OBJECT_IFNET 0x0000000000000100
#define MPC_OBJECT_BPFDESC 0x0000000000000200
#define MPC_OBJECT_PIPE 0x0000000000000400
#define MPC_OBJECT_MOUNT 0x0000000000000800
#define MPC_OBJECT_POSIXSEM 0x0000000000001000
#define MPC_OBJECT_POSIXSHM 0x0000000000002000
#define MPC_OBJECT_SYSVMSG 0x0000000000004000
#define MPC_OBJECT_SYSVMSQ 0x0000000000008000
#define MPC_OBJECT_SYSVSEM 0x0000000000010000
#define MPC_OBJECT_SYSVSHM 0x0000000000020000
#define MPC_OBJECT_SYNCACHE 0x0000000000040000
/*-
* The TrustedBSD MAC Framework has a major version number, MAC_VERSION,
* which defines the ABI of the Framework present in the kernel (and depended
@ -955,14 +983,15 @@ struct mac_policy_conf {
*/
#define MAC_VERSION 4
#define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted) \
#define MAC_POLICY_SET(mpops, mpname, mpfullname, mpflags, privdata_wanted, \
labeled) \
static struct mac_policy_conf mpname##_mac_policy_conf = { \
#mpname, \
mpfullname, \
mpops, \
mpflags, \
privdata_wanted, \
0, \
.mpc_name = #mpname, \
.mpc_fullname = mpfullname, \
.mpc_ops = mpops, \
.mpc_loadtime_flags = mpflags, \
.mpc_field_off = privdata_wanted, \
.mpc_labeled = labeled, \
}; \
static moduledata_t mpname##_mod = { \
#mpname, \

View File

@ -64,7 +64,10 @@ void
mac_posixsem_init(struct ksem *ks)
{
ks->ks_label = mac_posixsem_label_alloc();
if (mac_labeled & MPC_OBJECT_POSIXSEM)
ks->ks_label = mac_posixsem_label_alloc();
else
ks->ks_label = NULL;
}
static void
@ -79,8 +82,10 @@ void
mac_posixsem_destroy(struct ksem *ks)
{
mac_posixsem_label_free(ks->ks_label);
ks->ks_label = NULL;
if (ks->ks_label != NULL) {
mac_posixsem_label_free(ks->ks_label);
ks->ks_label = NULL;
}
}
void

View File

@ -63,7 +63,10 @@ void
mac_posixshm_init(struct shmfd *shmfd)
{
shmfd->shm_label = mac_posixshm_label_alloc();
if (mac_labeled & MPC_OBJECT_POSIXSHM)
shmfd->shm_label = mac_posixshm_label_alloc();
else
shmfd->shm_label = NULL;
}
static void
@ -78,8 +81,10 @@ void
mac_posixshm_destroy(struct shmfd *shmfd)
{
mac_posixshm_label_free(shmfd->shm_label);
shmfd->shm_label = NULL;
if (shmfd->shm_label != NULL) {
mac_posixshm_label_free(shmfd->shm_label);
shmfd->shm_label = NULL;
}
}
void

View File

@ -4,6 +4,7 @@
* Copyright (c) 2001-2003 Networks Associates Technology, Inc.
* Copyright (c) 2005 Samy Al Bahra
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -97,7 +98,10 @@ void
mac_cred_init(struct ucred *cred)
{
cred->cr_label = mac_cred_label_alloc();
if (mac_labeled & MPC_OBJECT_CRED)
cred->cr_label = mac_cred_label_alloc();
else
cred->cr_label = NULL;
}
static struct label *
@ -114,7 +118,10 @@ void
mac_proc_init(struct proc *p)
{
p->p_label = mac_proc_label_alloc();
if (mac_labeled & MPC_OBJECT_PROC)
p->p_label = mac_proc_label_alloc();
else
p->p_label = NULL;
}
void
@ -129,8 +136,10 @@ void
mac_cred_destroy(struct ucred *cred)
{
mac_cred_label_free(cred->cr_label);
cred->cr_label = NULL;
if (cred->cr_label != NULL) {
mac_cred_label_free(cred->cr_label);
cred->cr_label = NULL;
}
}
static void
@ -145,8 +154,10 @@ void
mac_proc_destroy(struct proc *p)
{
mac_proc_label_free(p->p_label);
p->p_label = NULL;
if (p->p_label != NULL) {
mac_proc_label_free(p->p_label);
p->p_label = NULL;
}
}
int
@ -238,6 +249,9 @@ mac_execve_enter(struct image_params *imgp, struct mac *mac_p)
if (mac_p == NULL)
return (0);
if (!(mac_labeled & MPC_OBJECT_CRED))
return (EINVAL);
error = copyin(mac_p, &mac, sizeof(mac));
if (error)
return (error);
@ -273,6 +287,26 @@ mac_execve_exit(struct image_params *imgp)
}
}
void
mac_execve_interpreter_enter(struct vnode *interpvp,
struct label **interpvplabel)
{
if (mac_labeled & MPC_OBJECT_VNODE) {
*interpvplabel = mac_vnode_label_alloc();
mac_vnode_copy_label(interpvp->v_label, *interpvplabel);
} else
*interpvplabel = NULL;
}
void
mac_execve_interpreter_exit(struct label *interpvplabel)
{
if (interpvplabel != NULL)
mac_vnode_label_free(interpvplabel);
}
/*
* When relabeling a process, call out to the policies for the maximum
* permission allowed for each object type we know about in its memory space,

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -126,14 +127,19 @@ int
mac_socket_init(struct socket *so, int flag)
{
so->so_label = mac_socket_label_alloc(flag);
if (so->so_label == NULL)
return (ENOMEM);
so->so_peerlabel = mac_socketpeer_label_alloc(flag);
if (so->so_peerlabel == NULL) {
mac_socket_label_free(so->so_label);
if (mac_labeled & MPC_OBJECT_SOCKET) {
so->so_label = mac_socket_label_alloc(flag);
if (so->so_label == NULL)
return (ENOMEM);
so->so_peerlabel = mac_socketpeer_label_alloc(flag);
if (so->so_peerlabel == NULL) {
mac_socket_label_free(so->so_label);
so->so_label = NULL;
return (ENOMEM);
}
} else {
so->so_label = NULL;
return (ENOMEM);
so->so_peerlabel = NULL;
}
return (0);
}
@ -158,10 +164,12 @@ void
mac_socket_destroy(struct socket *so)
{
mac_socket_label_free(so->so_label);
so->so_label = NULL;
mac_socketpeer_label_free(so->so_peerlabel);
so->so_peerlabel = NULL;
if (so->so_label != NULL) {
mac_socket_label_free(so->so_label);
so->so_label = NULL;
mac_socketpeer_label_free(so->so_peerlabel);
so->so_peerlabel = NULL;
}
}
void
@ -459,6 +467,9 @@ mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac)
char *buffer;
int error;
if (!(mac_labeled & MPC_OBJECT_SOCKET))
return (EINVAL);
error = mac_check_structmac_consistent(mac);
if (error)
return (error);
@ -489,6 +500,9 @@ mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac)
struct label *intlabel;
int error;
if (!(mac_labeled & MPC_OBJECT_SOCKET))
return (EINVAL);
error = mac_check_structmac_consistent(mac);
if (error)
return (error);
@ -525,6 +539,9 @@ mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so,
struct label *intlabel;
int error;
if (!(mac_labeled & MPC_OBJECT_SOCKET))
return (EINVAL);
error = mac_check_structmac_consistent(mac);
if (error)
return (error);

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2005 Networks Associates Technology, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -160,6 +161,9 @@ __mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
char *buffer;
int error;
if (!(mac_labeled & MPC_OBJECT_CRED))
return (EINVAL);
error = copyin(uap->mac_p, &mac, sizeof(mac));
if (error)
return (error);
@ -253,6 +257,8 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
switch (fp->f_type) {
case DTYPE_FIFO:
case DTYPE_VNODE:
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
vp = fp->f_vnode;
intlabel = mac_vnode_label_alloc();
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
@ -266,6 +272,8 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
break;
case DTYPE_PIPE:
if (!(mac_labeled & MPC_OBJECT_PIPE))
return (EINVAL);
pipe = fp->f_data;
intlabel = mac_pipe_label_alloc();
PIPE_LOCK(pipe);
@ -277,6 +285,8 @@ __mac_get_fd(struct thread *td, struct __mac_get_fd_args *uap)
break;
case DTYPE_SOCKET:
if (!(mac_labeled & MPC_OBJECT_SOCKET))
return (EINVAL);
so = fp->f_data;
intlabel = mac_socket_label_alloc(M_WAITOK);
SOCK_LOCK(so);
@ -309,6 +319,9 @@ __mac_get_file(struct thread *td, struct __mac_get_file_args *uap)
struct mac mac;
int vfslocked, error;
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
error = copyin(uap->mac_p, &mac, sizeof(mac));
if (error)
return (error);
@ -359,6 +372,9 @@ __mac_get_link(struct thread *td, struct __mac_get_link_args *uap)
struct mac mac;
int vfslocked, error;
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
error = copyin(uap->mac_p, &mac, sizeof(mac));
if (error)
return (error);
@ -435,6 +451,8 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
switch (fp->f_type) {
case DTYPE_FIFO:
case DTYPE_VNODE:
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
intlabel = mac_vnode_label_alloc();
error = mac_vnode_internalize_label(intlabel, buffer);
if (error) {
@ -458,6 +476,8 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
break;
case DTYPE_PIPE:
if (!(mac_labeled & MPC_OBJECT_PIPE))
return (EINVAL);
intlabel = mac_pipe_label_alloc();
error = mac_pipe_internalize_label(intlabel, buffer);
if (error == 0) {
@ -471,6 +491,8 @@ __mac_set_fd(struct thread *td, struct __mac_set_fd_args *uap)
break;
case DTYPE_SOCKET:
if (!(mac_labeled & MPC_OBJECT_SOCKET))
return (EINVAL);
intlabel = mac_socket_label_alloc(M_WAITOK);
error = mac_socket_internalize_label(intlabel, buffer);
if (error == 0) {
@ -500,6 +522,9 @@ __mac_set_file(struct thread *td, struct __mac_set_file_args *uap)
char *buffer;
int vfslocked, error;
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
error = copyin(uap->mac_p, &mac, sizeof(mac));
if (error)
return (error);
@ -551,6 +576,9 @@ __mac_set_link(struct thread *td, struct __mac_set_link_args *uap)
char *buffer;
int vfslocked, error;
if (!(mac_labeled & MPC_OBJECT_VNODE))
return (EINVAL);
error = copyin(uap->mac_p, &mac, sizeof(mac));
if (error)
return (error);

View File

@ -1,6 +1,7 @@
/*-
* Copyright (c) 2003-2004 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed for the FreeBSD Project in part by Network
@ -70,7 +71,10 @@ void
mac_sysvmsg_init(struct msg *msgptr)
{
msgptr->label = mac_sysv_msgmsg_label_alloc();
if (mac_labeled & MPC_OBJECT_SYSVMSG)
msgptr->label = mac_sysv_msgmsg_label_alloc();
else
msgptr->label = NULL;
}
static struct label *
@ -87,7 +91,10 @@ void
mac_sysvmsq_init(struct msqid_kernel *msqkptr)
{
msqkptr->label = mac_sysv_msgqueue_label_alloc();
if (mac_labeled & MPC_OBJECT_SYSVMSQ)
msqkptr->label = mac_sysv_msgqueue_label_alloc();
else
msqkptr->label = NULL;
}
static void
@ -102,8 +109,10 @@ void
mac_sysvmsg_destroy(struct msg *msgptr)
{
mac_sysv_msgmsg_label_free(msgptr->label);
msgptr->label = NULL;
if (msgptr->label != NULL) {
mac_sysv_msgmsg_label_free(msgptr->label);
msgptr->label = NULL;
}
}
static void
@ -118,8 +127,10 @@ void
mac_sysvmsq_destroy(struct msqid_kernel *msqkptr)
{
mac_sysv_msgqueue_label_free(msqkptr->label);
msqkptr->label = NULL;
if (msqkptr->label != NULL) {
mac_sysv_msgqueue_label_free(msqkptr->label);
msqkptr->label = NULL;
}
}
void

View File

@ -70,7 +70,10 @@ void
mac_sysvsem_init(struct semid_kernel *semakptr)
{
semakptr->label = mac_sysv_sem_label_alloc();
if (mac_labeled & MPC_OBJECT_SYSVSEM)
semakptr->label = mac_sysv_sem_label_alloc();
else
semakptr->label = NULL;
}
static void
@ -85,8 +88,10 @@ void
mac_sysvsem_destroy(struct semid_kernel *semakptr)
{
mac_sysv_sem_label_free(semakptr->label);
semakptr->label = NULL;
if (semakptr->label != NULL) {
mac_sysv_sem_label_free(semakptr->label);
semakptr->label = NULL;
}
}
void

View File

@ -70,7 +70,10 @@ void
mac_sysvshm_init(struct shmid_kernel *shmsegptr)
{
shmsegptr->label = mac_sysv_shm_label_alloc();
if (mac_labeled & MPC_OBJECT_SYSVSHM)
shmsegptr->label = mac_sysv_shm_label_alloc();
else
shmsegptr->label = NULL;
}
static void
@ -85,8 +88,10 @@ void
mac_sysvshm_destroy(struct shmid_kernel *shmsegptr)
{
mac_sysv_shm_label_free(shmsegptr->label);
shmsegptr->label = NULL;
if (shmsegptr->label != NULL) {
mac_sysv_shm_label_free(shmsegptr->label);
shmsegptr->label = NULL;
}
}
void

View File

@ -3,6 +3,7 @@
* Copyright (c) 2001 Ilmar S. Habibulin
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson and Ilmar Habibulin for the
@ -94,7 +95,10 @@ void
mac_devfs_init(struct devfs_dirent *de)
{
de->de_label = mac_devfs_label_alloc();
if (mac_labeled & MPC_OBJECT_DEVFS)
de->de_label = mac_devfs_label_alloc();
else
de->de_label = NULL;
}
static struct label *
@ -111,7 +115,10 @@ void
mac_mount_init(struct mount *mp)
{
mp->mnt_label = mac_mount_label_alloc();
if (mac_labeled & MPC_OBJECT_MOUNT)
mp->mnt_label = mac_mount_label_alloc();
else
mp->mnt_label = NULL;
}
struct label *
@ -128,7 +135,10 @@ void
mac_vnode_init(struct vnode *vp)
{
vp->v_label = mac_vnode_label_alloc();
if (mac_labeled & MPC_OBJECT_VNODE)
vp->v_label = mac_vnode_label_alloc();
else
vp->v_label = NULL;
}
static void
@ -143,8 +153,10 @@ void
mac_devfs_destroy(struct devfs_dirent *de)
{
mac_devfs_label_free(de->de_label);
de->de_label = NULL;
if (de->de_label != NULL) {
mac_devfs_label_free(de->de_label);
de->de_label = NULL;
}
}
static void
@ -159,8 +171,10 @@ void
mac_mount_destroy(struct mount *mp)
{
mac_mount_label_free(mp->mnt_label);
mp->mnt_label = NULL;
if (mp->mnt_label != NULL) {
mac_mount_label_free(mp->mnt_label);
mp->mnt_label = NULL;
}
}
void
@ -175,8 +189,10 @@ void
mac_vnode_destroy(struct vnode *vp)
{
mac_vnode_label_free(vp->v_label);
vp->v_label = NULL;
if (vp->v_label != NULL) {
mac_vnode_label_free(vp->v_label);
vp->v_label = NULL;
}
}
void

View File

@ -3474,5 +3474,25 @@ static struct mac_policy_ops mac_biba_ops =
.mpo_vnode_setlabel_extattr = biba_vnode_setlabel_extattr,
};
#define BIBA_OBJECTS (MPC_OBJECT_CRED | \
/* MPC_OBJECT_PROC | */ \
MPC_OBJECT_VNODE | \
MPC_OBJECT_INPCB | \
MPC_OBJECT_SOCKET | \
MPC_OBJECT_DEVFS | \
MPC_OBJECT_MBUF | \
MPC_OBJECT_IPQ | \
MPC_OBJECT_IFNET | \
MPC_OBJECT_BPFDESC | \
MPC_OBJECT_PIPE | \
MPC_OBJECT_MOUNT | \
MPC_OBJECT_POSIXSEM | \
/* MPC_OBJECT_POSIXSHM | */ \
MPC_OBJECT_SYSVMSG | \
MPC_OBJECT_SYSVMSQ | \
MPC_OBJECT_SYSVSEM | \
MPC_OBJECT_SYSVSHM | \
MPC_OBJECT_SYNCACHE)
MAC_POLICY_SET(&mac_biba_ops, mac_biba, "TrustedBSD MAC/Biba",
MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &biba_slot);
MPC_LOADTIME_FLAG_NOTLATE, &biba_slot, BIBA_OBJECTS);

View File

@ -748,4 +748,4 @@ static struct mac_policy_ops ugidfw_ops =
};
MAC_POLICY_SET(&ugidfw_ops, mac_bsdextended, "TrustedBSD MAC/BSD Extended",
MPC_LOADTIME_FLAG_UNLOADOK, NULL);
MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);

View File

@ -170,4 +170,4 @@ static struct mac_policy_ops ifoff_ops =
};
MAC_POLICY_SET(&ifoff_ops, mac_ifoff, "TrustedBSD MAC/ifoff",
MPC_LOADTIME_FLAG_UNLOADOK, NULL);
MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);

View File

@ -2981,5 +2981,25 @@ static struct mac_policy_ops lomac_ops =
.mpo_vnode_setlabel_extattr = lomac_vnode_setlabel_extattr,
};
#define LOMAC_OBJECTS (MPC_OBJECT_CRED | \
/* MPC_OBJECT_PROC | */ \
MPC_OBJECT_VNODE | \
MPC_OBJECT_INPCB | \
MPC_OBJECT_SOCKET | \
MPC_OBJECT_DEVFS | \
MPC_OBJECT_MBUF | \
MPC_OBJECT_IPQ | \
MPC_OBJECT_IFNET | \
MPC_OBJECT_BPFDESC | \
MPC_OBJECT_PIPE | \
MPC_OBJECT_MOUNT | \
/* MPC_OBJECT_POSIXSEM | */ \
/* MPC_OBJECT_POSIXSHM | */ \
/* MPC_OBJECT_SYSVMSG | */ \
/* MPC_OBJECT_SYSVMSQ | */ \
/* MPC_OBJECT_SYSVSEM | */ \
/* MPC_OBJECT_SYSVSHM | */ \
MPC_OBJECT_SYNCACHE)
MAC_POLICY_SET(&lomac_ops, mac_lomac, "TrustedBSD MAC/LOMAC",
MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &lomac_slot);
MPC_LOADTIME_FLAG_NOTLATE, &lomac_slot, LOMAC_OBJECTS);

View File

@ -3091,5 +3091,25 @@ static struct mac_policy_ops mls_ops =
.mpo_vnode_setlabel_extattr = mls_vnode_setlabel_extattr,
};
#define MLS_OBJECTS (MPC_OBJECT_CRED | \
/* MPC_OBJECT_PROC | */ \
MPC_OBJECT_VNODE | \
MPC_OBJECT_INPCB | \
MPC_OBJECT_SOCKET | \
MPC_OBJECT_DEVFS | \
MPC_OBJECT_MBUF | \
MPC_OBJECT_IPQ | \
MPC_OBJECT_IFNET | \
MPC_OBJECT_BPFDESC | \
MPC_OBJECT_PIPE | \
MPC_OBJECT_MOUNT | \
MPC_OBJECT_POSIXSEM | \
/* MPC_OBJECT_POSIXSHM | */ \
MPC_OBJECT_SYSVMSG | \
MPC_OBJECT_SYSVMSQ | \
MPC_OBJECT_SYSVSEM | \
MPC_OBJECT_SYSVSHM | \
MPC_OBJECT_SYNCACHE)
MAC_POLICY_SET(&mls_ops, mac_mls, "TrustedBSD MAC/MLS",
MPC_LOADTIME_FLAG_NOTLATE | MPC_LOADTIME_FLAG_LABELMBUFS, &mls_slot);
MPC_LOADTIME_FLAG_NOTLATE, &mls_slot, MLS_OBJECTS);

View File

@ -53,4 +53,4 @@ static struct mac_policy_ops none_ops =
};
MAC_POLICY_SET(&none_ops, mac_none, "TrustedBSD MAC/None",
MPC_LOADTIME_FLAG_UNLOADOK, NULL);
MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);

View File

@ -2,6 +2,7 @@
* Copyright (c) 1999-2002, 2007 Robert N. M. Watson
* Copyright (c) 2001-2002 Networks Associates Technology, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -76,9 +77,20 @@ label_on_label(struct label *subject, struct label *object)
if (partition_enabled == 0)
return (0);
if (subject == NULL)
return (0);
if (SLOT(subject) == 0)
return (0);
/*
* If the object label hasn't been allocated, then it's effectively
* not in a partition, and we know the subject is as it has a label
* and it's not 0, so reject.
*/
if (object == NULL)
return (EPERM);
if (SLOT(subject) == SLOT(object))
return (0);
@ -124,7 +136,10 @@ static void
partition_cred_copy_label(struct label *src, struct label *dest)
{
SLOT_SET(dest, SLOT(src));
if (src != NULL && dest != NULL)
SLOT_SET(dest, SLOT(src));
else if (dest != NULL)
SLOT_SET(dest, 0);
}
static void
@ -144,10 +159,14 @@ partition_cred_externalize_label(struct label *label, char *element_name,
(*claimed)++;
if (sbuf_printf(sb, "%jd", (intmax_t)SLOT(label)) == -1)
return (EINVAL);
else
return (0);
if (label != NULL) {
if (sbuf_printf(sb, "%jd", (intmax_t)SLOT(label)) == -1)
return (EINVAL);
} else {
if (sbuf_printf(sb, "0") == -1)
return (EINVAL);
}
return (0);
}
static void
@ -174,7 +193,7 @@ static void
partition_cred_relabel(struct ucred *cred, struct label *newlabel)
{
if (SLOT(newlabel) != 0)
if (newlabel != NULL && SLOT(newlabel) != 0)
SLOT_SET(cred->cr_label, SLOT(newlabel));
}
@ -273,4 +292,4 @@ static struct mac_policy_ops partition_ops =
};
MAC_POLICY_SET(&partition_ops, mac_partition, "TrustedBSD MAC/Partition",
MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot);
MPC_LOADTIME_FLAG_UNLOADOK, &partition_slot, MPC_OBJECT_CRED);

View File

@ -490,4 +490,4 @@ static struct mac_policy_ops portacl_ops =
};
MAC_POLICY_SET(&portacl_ops, mac_portacl, "TrustedBSD MAC/portacl",
MPC_LOADTIME_FLAG_UNLOADOK, NULL);
MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);

View File

@ -172,4 +172,4 @@ static struct mac_policy_ops seeotheruids_ops =
};
MAC_POLICY_SET(&seeotheruids_ops, mac_seeotheruids,
"TrustedBSD MAC/seeotheruids", MPC_LOADTIME_FLAG_UNLOADOK, NULL);
"TrustedBSD MAC/seeotheruids", MPC_LOADTIME_FLAG_UNLOADOK, NULL, 0);

View File

@ -2,6 +2,7 @@
* Copyright (c) 1999-2002, 2007 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2005-2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -1754,5 +1755,25 @@ static struct mac_policy_ops stub_ops =
.mpo_vnode_setlabel_extattr = stub_vnode_setlabel_extattr,
};
#define STUB_OBJECTS (MPC_OBJECT_CRED | \
/* XXX: MPC_OBJECT_PROC | */ \
MPC_OBJECT_VNODE | \
MPC_OBJECT_INPCB | \
MPC_OBJECT_SOCKET | \
MPC_OBJECT_DEVFS | \
MPC_OBJECT_MBUF | \
MPC_OBJECT_IPQ | \
MPC_OBJECT_IFNET | \
MPC_OBJECT_BPFDESC | \
MPC_OBJECT_PIPE | \
MPC_OBJECT_MOUNT | \
MPC_OBJECT_POSIXSEM | \
MPC_OBJECT_POSIXSHM | \
MPC_OBJECT_SYSVMSG | \
MPC_OBJECT_SYSVMSQ | \
MPC_OBJECT_SYSVSEM | \
MPC_OBJECT_SYSVSHM | \
MPC_OBJECT_SYNCACHE)
MAC_POLICY_SET(&stub_ops, mac_stub, "TrustedBSD MAC/Stub",
MPC_LOADTIME_FLAG_UNLOADOK, NULL);
MPC_LOADTIME_FLAG_UNLOADOK, NULL, STUB_OBJECTS);

View File

@ -2,6 +2,7 @@
* Copyright (c) 1999-2002, 2007 Robert N. M. Watson
* Copyright (c) 2001-2005 McAfee, Inc.
* Copyright (c) 2006 SPARTA, Inc.
* Copyright (c) 2008 Apple Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -3046,5 +3047,25 @@ static struct mac_policy_ops test_ops =
.mpo_vnode_setlabel_extattr = test_vnode_setlabel_extattr,
};
#define TEST_OBJECTS (MPC_OBJECT_CRED | \
MPC_OBJECT_PROC | \
MPC_OBJECT_VNODE | \
MPC_OBJECT_INPCB | \
MPC_OBJECT_SOCKET | \
MPC_OBJECT_DEVFS | \
MPC_OBJECT_MBUF | \
MPC_OBJECT_IPQ | \
MPC_OBJECT_IFNET | \
MPC_OBJECT_BPFDESC | \
MPC_OBJECT_PIPE | \
MPC_OBJECT_MOUNT | \
MPC_OBJECT_POSIXSEM | \
MPC_OBJECT_POSIXSHM | \
MPC_OBJECT_SYSVMSG | \
MPC_OBJECT_SYSVMSQ | \
MPC_OBJECT_SYSVSEM | \
MPC_OBJECT_SYSVSHM | \
MPC_OBJECT_SYNCACHE)
MAC_POLICY_SET(&test_ops, mac_test, "TrustedBSD MAC/Test",
MPC_LOADTIME_FLAG_UNLOADOK | MPC_LOADTIME_FLAG_LABELMBUFS, &test_slot);
MPC_LOADTIME_FLAG_UNLOADOK, &test_slot, TEST_OBJECTS);