PERFORCE change 107187 for review
Todd Miller
millert at FreeBSD.org
Tue Oct 3 08:17:28 PDT 2006
http://perforce.freebsd.org/chv.cgi?CH=107187
Change 107187 by millert at millert_macbook on 2006/10/03 15:16:58
Add iokit access control driver and corresponding MAC entrypoint
Panic if audit cannot be initialized
Export mac_vnop_removexattr to kexts
Better color policy
Affected files ...
.. //depot/projects/trustedbsd/sedarwin8/darwin/Makefile#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControl.xcode/project.pbxproj#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlFireWire.cpp#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlFireWire.h#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlUSB.cpp#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/DeviceAccessControlUSB.h#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/English.lproj/InfoPlist.strings#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/Info.plist#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/DeviceAccessControl/README#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/drivers/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_audit.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/vnode.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_xattr.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#5 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOCatalogue.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOService.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/libsa/kext.cpp#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#2 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#8 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#13 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#10 edit
.. //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs_subr.c#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/Makefile#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/color_util.c#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#5 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.h#2 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/device_access/Makefile#1 add
.. //depot/projects/trustedbsd/sedarwin8/policies/device_access/mac_device_access.c#1 add
Differences ...
==== //depot/projects/trustedbsd/sedarwin8/darwin/Makefile#3 (text+ko) ====
@@ -8,6 +8,7 @@
$(MAKE) -C cctools
$(MAKE) -C kext_tools
$(MAKE) -C $(XNU)
+ $(MAKE) -C drivers
$(MAKE) -C bootstrap_cmds
$(MAKE) -C libmac
$(MAKE) -C mac_cmds
@@ -28,6 +29,7 @@
$(DESTDIR)/$(SYSTEM_PLUGINS)/
install -m 644 $(XNU)/BUILD/dst/mach_kernel $(DESTDIR)/
tar -C $(XNU)/BUILD/dst -cf - usr/include | tar -C $(DESTDIR) -xf -
+ $(MAKE) -C drivers DSTROOT=$(DESTDIR) install
$(MAKE) -C libmac install
$(MAKE) -C mac_cmds install
$(MAKE) -C osx_cmds install
@@ -47,6 +49,7 @@
$(MAKE) -C bootstrap_cmds clean
$(MAKE) -C cctools clean
$(MAKE) -C kext_tools clean
+ $(MAKE) -C drivers clean
$(MAKE) -C libmac clean
$(MAKE) -C mac_cmds clean
$(MAKE) -C osx_cmds clean
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/kern/kern_audit.c#5 (text+ko) ====
@@ -671,9 +671,8 @@
* size as the system call table.
*/
if (nsys_au_event != nsysent) {
- printf("Security auditing service initialization failed, ");
- printf("audit event table doesn't match syscall table.\n");
- return;
+ panic("Security auditing service initialization failed, "
+ "audit event table doesn't match syscall table.");
}
printf("Security auditing service present\n");
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/sys/vnode.h#3 (text+ko) ====
@@ -645,6 +645,8 @@
int default_setxattr(vnode_t vp, const char *name, uio_t uio,
int options, vfs_context_t context);
+int default_removexattr(vnode_t vp, const char *name, int options,
+ vfs_context_t context);
__END_DECLS
#endif /* KERNEL */
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/bsd/vfs/vfs_xattr.c#5 (text+ko) ====
@@ -53,7 +53,6 @@
/*
* Default xattr support routines.
*/
-static int default_removexattr(vnode_t vp, const char *name, int options, vfs_context_t context);
static int default_listxattr(vnode_t vp, uio_t uio, size_t *size, int options,
vfs_context_t context);
@@ -989,7 +988,7 @@
/*
* Remove an extended attribute.
*/
-static int
+int
default_removexattr(vnode_t vp, const char *name, __unused int options, vfs_context_t context)
{
vnode_t xvp = NULL;
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/config/MACFramework.exports#5 (text+ko) ====
@@ -5,6 +5,7 @@
_mac_vnop_getxattr
_mac_vnop_setxattr
+_mac_vnop_removexattr
_kau_will_audit
_mac_audit_text
@@ -35,3 +36,8 @@
_mac_zfree
_mac_find_module_data
+
+_mac_iokit_check_device_allowed
+
+# This should really go in IOKit.exports.
+__Z13osdict_encodeP12OSDictionary
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOCatalogue.cpp#2 (text+ko) ====
@@ -123,14 +123,12 @@
extern "C" kern_return_t kmod_release(kmod_t id);
/*********************************************************************
-* This function takes a plist and looks for an OSModuleData dictionary.
-* If it is found, an encoded copy is returned.
+* This function takes an OSDictionary and returns a struct mac_module_data
+* list.
*********************************************************************/
-kmod_args_t
-get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen)
+struct mac_module_data *
+osdict_encode(OSDictionary *dict)
{
-
- OSDictionary * kextModuleData = 0; // don't release
const OSMetaClass * typeID; // don't release
OSString * key = NULL; // don't release
OSCollectionIterator * keyIterator = 0; // must release
@@ -138,16 +136,11 @@
struct mac_module_data_element * element;
unsigned int strtabsize = 0;
unsigned int nkeys = 0;
+ unsigned int datalen;
char * strtab = 0;
vm_offset_t data_addr;
- vm_map_copy_t copy = 0;
- kextModuleData = OSDynamicCast(OSDictionary,
- kextPlist->getObject("OSModuleData"));
- if (!kextModuleData)
- goto finish;
-
- keyIterator = OSCollectionIterator::withCollection(kextModuleData);
+ keyIterator = OSCollectionIterator::withCollection(dict);
if (!keyIterator)
goto finish;
@@ -155,7 +148,7 @@
while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
// Get the key's value and determine its type
- OSObject * value = kextModuleData->getObject(key);
+ OSObject * value = dict->getObject(key);
if (!value)
continue;
@@ -183,12 +176,12 @@
/*
* Allocate and fill in the module data structures.
*/
- *datalen = sizeof(struct mac_module_data) +
+ datalen = sizeof(struct mac_module_data) +
sizeof(mac_module_data_element) * (nkeys - 1) + strtabsize;
- if (kmem_alloc(kernel_map, &data_addr, *datalen) != KERN_SUCCESS)
+ if (kmem_alloc(kernel_map, &data_addr, datalen) != KERN_SUCCESS)
goto finish;
module_data = (mac_module_data *)data_addr;
- module_data->size = *datalen;
+ module_data->size = datalen;
module_data->count = nkeys;
strtab = (char *)&module_data->data[nkeys];
@@ -197,7 +190,7 @@
while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
// Get the key's value and determine its type
- OSObject * value = kextModuleData->getObject(key);
+ OSObject * value = dict->getObject(key);
if (!value)
continue;
@@ -239,18 +232,41 @@
strtab += element->key_size + element->value_size;
element++;
}
+finish:
+ if (keyIterator)
+ keyIterator->release();
+ return(module_data);
+}
+
+/*********************************************************************
+* This function takes a plist and looks for an OSModuleData dictionary.
+* If it is found, an encoded copy is returned.
+*********************************************************************/
+kmod_args_t
+get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen)
+{
+
+ OSDictionary * kextModuleData = 0; // don't release
+ struct mac_module_data * module_data = 0;
+ vm_map_copy_t copy = 0;
+ kextModuleData = OSDynamicCast(OSDictionary,
+ kextPlist->getObject("OSModuleData"));
+ if (!kextModuleData)
+ goto finish;
+
+ module_data = osdict_encode(kextModuleData);
+ if (!module_data)
+ goto finish;
+ *datalen = module_data->size;
/*
* Make a CoW copy of data and free the original. The copy is
* consumed by a call to vm_map_copyout() in kmod_start_or_stop().
*/
- vm_map_copyin(kernel_map, (vm_offset_t)data_addr, *datalen, FALSE, ©);
- kmem_free(kernel_map, data_addr, *datalen);
+ vm_map_copyin(kernel_map, (vm_offset_t)module_data, *datalen, FALSE, ©);
+ kmem_free(kernel_map, (vm_offset_t)module_data, *datalen);
finish:
- if (keyIterator)
- keyIterator->release();
-
return (kmod_args_t)copy;
}
@@ -1427,4 +1443,3 @@
IOLockUnlock(gIOKLDLock);
}
-
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/iokit/Kernel/IOService.cpp#2 (text+ko) ====
@@ -2320,6 +2320,8 @@
OSObject * nextMatch = 0;
bool started;
bool needReloc = false;
+ OSBoolean * isSandbox = 0;
+ bool useSandbox = false;
#if IOMATCHDEBUG
SInt64 debugFlags;
#endif
@@ -2428,6 +2430,8 @@
if( !symbol)
continue;
+ IOLog("%s alloc (symbol %p props %p)\n", symbol->getCStringNoCopy(), symbol, props);
+
// alloc the driver instance
inst = (IOService *) OSMetaClass::allocClassWithName( symbol);
@@ -2454,7 +2458,10 @@
if( 0 == category)
category = gIODefaultMatchCategoryKey;
inst->setProperty( gIOMatchCategoryKey, (OSObject *) category );
-
+
+ isSandbox = OSDynamicCast(OSBoolean,
+ props->getObject("IOKitForceMatch"));
+
// attach driver instance
if( !(inst->attach( this )))
continue;
@@ -2471,6 +2478,19 @@
newInst = inst->probe( this, &score );
inst->detach( this );
+ /*
+ * If this is the Sandbox driver and it matched, this is a
+ * disallowed device; toss any drivers that were already
+ * matched.
+ */
+ if (isSandbox && isSandbox->isTrue() && newInst != 0) {
+ if (startDict != 0) {
+ startDict->flushCollection();
+ startDict->release();
+ startDict = 0;
+ }
+ useSandbox = true;
+ }
if( 0 == newInst) {
#if IOMATCHDEBUG
if( debugFlags & kIOLogProbe)
@@ -2509,6 +2529,11 @@
props->release();
if( inst)
inst->release();
+ /*
+ * If we're forcing the sandbox, drop out of the loop.
+ */
+ if (isSandbox && isSandbox->isTrue() && useSandbox)
+ break;
}
familyMatches->release();
familyMatches = 0;
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/libsa/kext.cpp#2 (text+ko) ====
@@ -77,6 +77,8 @@
extern kmod_args_t
get_module_data(OSDictionary * kextPlist, mach_msg_type_number_t * datalen);
+extern struct mac_module_data *osdict_encode(OSDictionary *dict);
+
#define DEBUG
#ifdef DEBUG
#define LOG_DELAY(x) IODelay((x) * 1000000)
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/conf/files#2 (text+ko) ====
@@ -23,3 +23,4 @@
security/mac_socket.c optional mac
security/mac_net.c optional mac
security/mac_pipe.c optional mac
+security/mac_iokit.c optional mac
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac.h#8 (text+ko) ====
@@ -67,6 +67,12 @@
typedef struct mac *mac_t;
+/*
+ * Device types for mac_iokit_check_device_allowed()
+ */
+#define MAC_DEVICE_USB 0
+#define MAC_DEVICE_FIREWIRE 1
+
#ifndef KERNEL
/*
* Location of the userland MAC framework configuration file. mac.conf
@@ -107,6 +113,11 @@
int mac_set_proc(const mac_t _label);
int mac_syscall(const char *_policyname, int _call, void *_arg);
int mac_to_text(mac_t mac, char **_text);
+/*
+ * I/O Kit device access control.
+ * Note that this routine is called from a C++ I/O Kit driver.
+ */
+int mac_iokit_check_device_allowed(int devtype, struct module_data *mdata);
__END_DECLS
#endif
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_base.c#13 (text+ko) ====
@@ -1947,15 +1947,22 @@
}
int
-mac_vnop_setxattr (struct vnode *vp, const char *name, char *buf, size_t len)
+mac_vnop_setxattr(struct vnode *vp, const char *name, char *buf, size_t len)
+{
+
+ return (ENOENT);
+}
+
+int
+mac_vnop_getxattr(struct vnode *vp, const char *name, char *buf, size_t len,
+ size_t *attrlen)
{
return (ENOENT);
}
int
-mac_vnop_getxattr (struct vnode *vp, const char *name, char *buf, size_t len,
- size_t *attrlen)
+mac_vnop_removexattr(struct vnode *vp, const char *name)
{
return (ENOENT);
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_policy.h#10 (text+ko) ====
@@ -4924,8 +4924,33 @@
int error,
int retval
);
+
+/**
+ @brief Device hardware access control
+ @param devtype Type of device connected
+ @param properties XML-formatted property list
+ @param proplen Length of the property list
+
+ This is the MAC Framework device access control, which is called by the I/O
+ Kit when a new device is connected to the system to determine whether that
+ device should be trusted. A list of properties associated with the device
+ is passed as an XML-formatted string. The routine should examine these
+ properties to determine the trustworthiness of the device. A return value
+ of EPERM forces the device to be claimed by a special device driver that
+ will prevent its operation.
+
+ @warning This is an experimental interface and may change in the future.
+
+ @return Return EPERM to indicate that the device is untrusted and should
+ not be allowed to operate. Return zero to indicate that the device is
+ trusted and should be allowed to operate normally.
+
+*/
+typedef int mpo_iokit_check_device_allowed_t(
+ int devtype,
+ struct mac_module_data *mdata
+);
/*@}*/
-
/*!
\struct mac_policy_ops
*/
@@ -5232,6 +5257,7 @@
mpo_pipe_check_select_t *mpo_pipe_check_select;
mpo_pipe_check_stat_t *mpo_pipe_check_stat;
mpo_pipe_check_write_t *mpo_pipe_check_write;
+ mpo_iokit_check_device_allowed_t *mpo_iokit_check_device_allowed;
};
/**
@@ -5309,6 +5335,7 @@
int mac_vnop_setxattr(struct vnode *, const char *, char *, size_t);
int mac_vnop_getxattr(struct vnode *, const char *, char *, size_t,
size_t *);
+int mac_vnop_removexattr(struct vnode *, const char *);
/*
* Arbitrary limit on how much data will be logged by the audit
==== //depot/projects/trustedbsd/sedarwin8/darwin/xnu/security/mac_vfs_subr.c#3 (text+ko) ====
@@ -124,3 +124,19 @@
return (error);
}
+
+int
+mac_vnop_removexattr (struct vnode *vp, const char *name)
+{
+ struct vfs_context context;
+ int error;
+
+ context.vc_proc = current_proc();
+ context.vc_ucred = kauth_cred_get();
+
+ error = VNOP_REMOVEXATTR(vp, name, 0, &context);
+ if (error == ENOTSUP || error == EPERM)
+ error = default_removexattr(vp, name, 0, &context);
+
+ return (error);
+}
==== //depot/projects/trustedbsd/sedarwin8/policies/Makefile#3 (text+ko) ====
@@ -1,5 +1,6 @@
-SUBDIR= basetest color console count fwinteg ipctrace mls none \
- readonly stacktrace stub test vanity xattr extattr_test
+SUBDIR= basetest color console count device_access extattr_test \
+ fwinteg ipctrace mls multilabel none readonly stacktrace \
+ stub test vanity xattr
SUBDIR+= sedarwin
include mk/subdir.mk
==== //depot/projects/trustedbsd/sedarwin8/policies/color/color_util.c#2 (text+ko) ====
@@ -96,14 +96,13 @@
LIST_REMOVE(mc, list);
free_count--;
mc->refs = 0;
- mc->valid = 0;
}
- mc->refs++;
+ mc->refs = 1;
used_count++;
mc->color = &colors[0];
LIST_INSERT_HEAD(&mc_list_used, mc, list);
-// printf("mc_alloc, mc=%p, refs=%d\n", mc, mc->refs);
+ MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
return (mc);
}
@@ -114,7 +113,7 @@
if (mc == NULL)
return;
-// printf("mc_free, mc=%p, refs=%d\n", mc, mc->refs);
+ MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
LIST_REMOVE(mc, list);
used_count--;
@@ -146,7 +145,10 @@
if (mc == NULL)
return;
- if (--mc->refs <= 0)
+ mc->refs--;
+ MCPRINTF("%s:: mc=%p, refs=%d\n", __func__, mc, mc->refs);
+
+ if (mc->refs <= 0)
mc_free(mc);
co_setreflabel(label, NULL);
@@ -205,15 +207,17 @@
if (SLOTREF(dst) != NULL) {
/* Already has a reference. */
if (SLOTREF(dst) == mc) {
-// printf("co_reference_label: already has matching reference\n");
+ MCPRINTF("%s:: already has matching reference\n",
+ __func__);
return;
} else {
-// printf("co_reference_label: already has a reference\n");
+ MCPRINTF("%s:: already has a reference\n", __func__);
}
co_destroy_reflabel(dst);
}
- printf("co_reference_label: copying reference, mc=%p, refs=%d\n", mc, mc->refs);
mc->refs++;
+ MCPRINTF("%s:: copying reference, mc=%p, refs=%d\n", __func__, mc,
+ mc->refs);
co_setreflabel(dst, mc);
return;
@@ -234,6 +238,33 @@
}
+int
+co_maybe_promote_process(struct ucred *subject, struct label *object)
+{
+ struct color *filecolor, *credcolor;
+
+ filecolor = co_getlabel(object);
+ credcolor = co_getreflabel(subject->cr_label)->color;
+
+ /*
+ * If the file doesn't have a label or they are the same
+ */
+ if ((filecolor == NULL) || (filecolor == credcolor))
+ return (0);
+
+ MCPRINTF("%s:: checking file label %s(%d) with cred %s(%d)\n",
+ __func__, filecolor->name, filecolor->level,
+ credcolor->name, credcolor->level);
+
+ if (filecolor->level > credcolor->level) {
+ printf("%s:: promoting label from %s to %s\n",
+ __func__, credcolor->name, filecolor->name);
+ co_getreflabel(subject->cr_label)->color = filecolor;
+ }
+
+ return (0);
+}
+
void
color_policy_init(struct mac_policy_conf *conf)
{
==== //depot/projects/trustedbsd/sedarwin8/policies/color/mac_color.c#5 (text+ko) ====
@@ -24,6 +24,28 @@
* SUCH DAMAGE.
*/
+/*
+ * The MAC Color policy.
+ *
+ * This policy demonstrates the potential of using login context
+ * labels to share privilege amongst a group of processes. It also
+ * demonstrates the use of floating labels.
+ *
+ * The policy has a small number of "rules":
+ * 1) All processes have a color. Files may optionally have a color.
+ * 2) Colors are ranked low to high by their position in the
+ * spectrum (red to violet).
+ * 3) A subject takes on the color of the highest object it is accessing.
+ * 4) Objects created by a subject will have the higher of the color
+ * of the subject at the time of creation or the enclosing directory.
+ * 5) Objects created will only have a label if the parent directory
+ * has a label.
+ *
+ * Note that this is an example policy, not all entry points are
+ * imlemented and not all subject access considered.
+ */
+
+
#include <sys/types.h>
#include <sys/param.h>
#include <sys/conf.h>
@@ -33,6 +55,7 @@
#include <sys/sbuf.h>
#include <sys/systm.h>
#include <sys/vnode.h>
+#include <sys/vnode_internal.h> /* struct vfs_context */
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/kauth.h>
@@ -46,7 +69,7 @@
static const char *labelnamespaces[MAC_COLOR_LABEL_COUNT] =
{ MAC_COLOR_POLICY_NAME };
-static int color_slot; /* Per-policy label storage */
+int color_slot; /* Per-policy label storage */
static mac_policy_handle_t mac_color_handle;
@@ -77,7 +100,13 @@
{
struct color *color;
+ if (strncmp(string, "unlabeled", 9) == 0) {
+ co_setreflabel(label, NULL);
+ return (0);
+ }
+
co_setlabelstring(label, string);
+
color = co_getlabel(label);
if (color == NULL) {
printf("%s: No matching color for %s\n", __func__, string);
@@ -126,7 +155,6 @@
color_cred_create(struct ucred *parent_cred, struct ucred *child_cred)
{
-// co_copylabel(parent_cred->cr_label, child_cred->cr_label);
co_reference_label(parent_cred->cr_label, child_cred->cr_label);
}
@@ -134,38 +162,52 @@
color_create_kernel_proc(struct ucred *cred)
{
- //co_setlabel(cred->cr_label, &colors[0]);
+ /* Nothing to do here */
}
-/* ================================================================= *
- * login context entry points
- * ================================================================= */
+static int
+color_cred_check_setlabel(struct ucred *cred, struct label *newlabel)
+{
-#if 0
-static void
-color_lctx_init_label(struct label *label)
-{
+ return (EPERM);
}
-static void
-color_lctx_destroy_label(struct label *label)
+static int
+color_proc_check_signal(struct ucred *cred, struct proc *proc, int signum)
{
+
+ struct color *subjectcolor, *objectcolor;
+
+ subjectcolor = co_getreflabel(cred->cr_label)->color;
+ objectcolor = co_getreflabel(proc_ucred(proc)->cr_label)->color;
+
+ if (objectcolor->level > subjectcolor->level) {
+ printf("%s:: promoting label from %s to %s\n",
+ __func__, subjectcolor->name, objectcolor->name);
+ co_getreflabel(cred->cr_label)->color = objectcolor;
+ }
+
+ return (0);
}
-#endif
+
+/* ================================================================= *
+ * login context entry points
+ * ================================================================= */
static void
color_proc_create_lctx(struct proc *p, struct lctx *l)
{
-// co_copylabel(proc_ucred(p)->cr_label, l->lc_label);
-// co_reference_label(proc_ucred(p)->cr_label, l->lc_label);
- printf("create_lctx:: process(%s) color %s(%d) creating lctx (which was color %s(%d))\n",
- p->p_comm,
- co_getreflabel(proc_ucred(p)->cr_label)->color->name,
- co_getreflabel(proc_ucred(p)->cr_label)->refs,
- co_getreflabel(l->lc_label)->color->name,
- co_getreflabel(l->lc_label)->refs);
- co_getreflabel(l->lc_label)->color = co_getreflabel(proc_ucred(p)->cr_label)->color;
+ printf("%s: process(%s) color %s(%d) create lctx (was color %s(%d))\n",
+ __func__, p->p_comm,
+ co_getreflabel(proc_ucred(p)->cr_label)->color->name,
+ co_getreflabel(proc_ucred(p)->cr_label)->refs,
+ co_getreflabel(l->lc_label)->color->name,
+ co_getreflabel(l->lc_label)->refs);
+
+ /* copy process label to lctx */
+ co_getreflabel(l->lc_label)->color =
+ co_getreflabel(proc_ucred(p)->cr_label)->color;
}
static void
@@ -173,37 +215,56 @@
{
co_reference_label(l->lc_label, proc_ucred(p)->cr_label);
- printf("join_lctx:: process(%s) color %s to join lctx color %s\n",
- p->p_comm,
- co_getreflabel(p->p_ucred->cr_label)->color->name,
- co_getreflabel(l->lc_label)->color->name);
+ MCPRINTF("%s:: process(%s) pid(%d) '%s' to join lctx '%s'\n",
+ __func__, p->p_comm, p->p_pid,
+ co_getreflabel(p->p_ucred->cr_label)->color->name,
+ co_getreflabel(l->lc_label)->color->name);
}
static void
color_proc_leave_lctx(struct proc *p, struct lctx *l)
{
- printf("leave_lctx:: process(%s) color %s to join lctx color %s\n",
- p->p_comm,
- co_getreflabel(p->p_ucred->cr_label)->color->name,
- co_getreflabel(l->lc_label)->color->name);
+ MCPRINTF("%s:: process(%s) pid(%d) '%s' to leave lctx '%s'\n",
+ __func__, p->p_comm, p->p_pid,
+ co_getreflabel(p->p_ucred->cr_label)->color->name,
+ co_getreflabel(l->lc_label)->color->name);
}
static void
color_lctx_setlabel(struct lctx *l, struct label *newlabel)
{
- printf("lctx_setlabel:: newlabel color %s for lctx color %s\n",
- co_getreflabel(newlabel)->color->name,
- co_getreflabel(l->lc_label)->color->name);
+ printf("%s:: newlabel color %s for lctx color %s\n",
+ __func__, co_getreflabel(newlabel)->color->name,
+ co_getreflabel(l->lc_label)->color->name);
}
/* ================================================================= *
* vnode entry points
* ================================================================= */
+static void
+color_mount_create(struct ucred *cred, struct mount *mp,
+ struct label *mntlabel)
+{
+ struct color *credcolor;
+
+ credcolor = co_getreflabel(cred->cr_label)->color;
+ co_setlabel(mntlabel, credcolor);
+}
+
static int
-color_vnode_associate_extattr(struct mount *mp, struct label *fslabel,
+color_mount_check_setlabel(struct ucred *cred, struct mount *mp,
+ struct label *mntlabel)
+{
+
+ return (EPERM);
+}
+
+
+static int
+color_vnode_associate_extattr(struct mount *mp, struct label *mntlabel,
struct vnode *vp, struct label *vlabel)
{
int error;
@@ -214,6 +275,7 @@
error = mac_vnop_getxattr(vp, MAC_COLOR_XATTR_NAME, buf,
sizeof(buf), &buflen);
+ /* If there's no attribute, the label is NULL */
if (error == ENOATTR || error == EOPNOTSUPP)
return (0);
@@ -227,11 +289,20 @@
}
static void
-color_vnode_associate_singlelabel(struct mount *mp, struct label *fslabel,
+color_devfs_vnode_associate(struct mount *mp, struct label *mntlabel,
+ struct devnode *de, struct label *delabel, struct vnode *vp,
+ struct label *vlabel)
+{
+
+ co_copylabel(mntlabel, vlabel);
+}
+
+static void
+color_vnode_associate_singlelabel(struct mount *mp, struct label *mntlabel,
struct vnode *vp, struct label *vlabel)
{
- co_setlabel(vlabel, NULL);
+ co_copylabel(mntlabel, vlabel);
}
static void
@@ -251,30 +322,39 @@
static int
color_vnode_create_extattr(struct ucred *cred, struct mount *mp,
- struct label *fslabel, struct vnode *dvp, struct label *dlabel,
+ struct label *mntlabel, struct vnode *dvp, struct label *dlabel,
struct vnode *vp, struct label *vlabel, struct componentname *cnp)
{
- int error;
- struct color *color;
+ int error = 0;
+ struct color *dircolor, *credcolor, *newcolor;
- /* For now, just inherit the parent directory label */
- color = co_getlabel(dlabel);
- if (color == NULL)
- return (0);
+ dircolor = co_getlabel(dlabel);
+ credcolor = co_getreflabel(cred->cr_label)->color;
- error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
- color->name, sizeof(color->name));
+ /*
+ * Process credentials always have labels, but files may not.
+ * If the parent directory has no label, the new file will have
+ * no label. Otherwise, the new file gets the higher of the
+ * parent label or the process label.
+ */
+ if ((dircolor == NULL) || (dircolor->level > credcolor->level))
+ newcolor = dircolor;
+ else
+ newcolor = credcolor;
- if (error)
- co_setlabel(vlabel, NULL);
- else
- co_copylabel(dlabel, vlabel);
+ co_setlabel(vlabel, newcolor);
+ if (newcolor != NULL) {
+ error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
+ newcolor->name, sizeof(newcolor->name));
+ if (error)
+ printf("%s:: Couldn't set file label \n", __func__);
+ }
return (error);
}
static void
-color_vnode_update_extattr(struct mount *mp, struct label *fslabel,
+color_vnode_update_extattr(struct mount *mp, struct label *mntlabel,
struct vnode *vp, struct label *vlabel, char *name)
{
int error;
@@ -285,6 +365,7 @@
error = mac_vnop_getxattr(vp, MAC_COLOR_XATTR_NAME, buf,
sizeof(buf), &buflen);
+ /* It's ok to have a NULL file label */
if (error)
return;
@@ -300,10 +381,11 @@
{
int error;
struct color *color;
+ struct vfs_context context;
color = co_getlabel(intlabel);
if (color == NULL)
- return (0);
+ return (mac_vnop_removexattr(vp, MAC_COLOR_XATTR_NAME));
error = mac_vnop_setxattr(vp, MAC_COLOR_XATTR_NAME,
color->name, sizeof(color->name));
@@ -312,90 +394,357 @@
}
static int
+color_vnode_check_access(struct ucred *cred, struct vnode *vp,
+ struct label *label, int acc_mode)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_chdir(struct ucred *cred, struct vnode *dvp,
+ struct label *label)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_chroot(struct ucred *cred, struct vnode *dvp,
+ struct label *label)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_create(struct ucred *cred, struct vnode *dvp,
+ struct label *label, struct componentname *cnp, struct vnode_attr *vap)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_unlink(struct ucred *cred, struct vnode *dvp,
+ struct label *dlabel, struct vnode *vp, struct label *label,
+ struct componentname *cnp)
+{
+
+ (void)co_maybe_promote_process(cred, dlabel);
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_deleteextattr(struct ucred *cred, struct vnode *vp,
+ struct label *label, const char *name)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+
+color_vnode_check_exchangedata(struct ucred *cred, struct vnode *v1,
+ struct label *vl1, struct vnode *v2, struct label *vl2)
+{
+
+ (void)co_maybe_promote_process(cred, vl1);
+ return (co_maybe_promote_process(cred, vl2));
+}
+
+static int
+color_vnode_check_exec(struct ucred *cred, struct vnode *vp,
+ struct label *label, struct label *execlabel)
+{
+
+ if (execlabel != NULL)
+ (void)co_maybe_promote_process(cred, execlabel);
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_getattrlist(struct ucred *cred, struct vnode *vp,
+ struct label *label, struct attrlist *alist)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_getextattr(struct ucred *cred, struct vnode *vp,
+ struct label *label, const char *name, struct uio *uio)
+{
+
+ return (co_maybe_promote_process(cred, label));
+}
+
+static int
+color_vnode_check_kqfilter(struct ucred *cred, struct ucred *file_cred,
+ struct knote *kn, struct vnode *vp, struct label *label)
+{
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the trustedbsd-cvs
mailing list