summaryrefslogtreecommitdiffstats
path: root/sys/contrib/lomac/kernel_mediate.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/lomac/kernel_mediate.c')
-rw-r--r--sys/contrib/lomac/kernel_mediate.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/sys/contrib/lomac/kernel_mediate.c b/sys/contrib/lomac/kernel_mediate.c
new file mode 100644
index 0000000..c28ce00
--- /dev/null
+++ b/sys/contrib/lomac/kernel_mediate.c
@@ -0,0 +1,280 @@
+/*-
+ * Copyright (c) 2001 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: kernel_mediate.c,v 1.9 2001/10/17 15:19:40 bfeldman Exp $
+ */
+
+/*
+ * This file contains functions that make access control decisions
+ * concerning wether or not given system calls should be allowed
+ * or denied. This activity is called "mediation". These functions
+ * generally consider both the parameters passed to a system call
+ * and the current internal state of LOMAC in the course of making
+ * a decision. However, they do not modify these parameters or
+ * LOMAC's internal state. Functions for modifying LOMAC's internal
+ * state can be found in lomac_monitor.c.
+ *
+ */
+
+#include "kernel_interface.h"
+#include "kernel_mediate.h"
+#if 0
+#include "lomac_plm.h"
+#endif
+#include "kernel_log.h"
+
+/* mediate_subject_level_subject()
+ *
+ * in: op_s - name of operation to mediate
+ * p_subject_one - subject one (for informational purposes only)
+ * level_one - already-known level of the first subject
+ * p_subject_two - subject two
+ * out: nothing
+ * return: value condition
+ * ----- ---------
+ * 0 caller should deny operation
+ * 1 caller should allow operation
+ *
+ * This function returns 1 if `p_subject_one's level is at least
+ * as great as `p_subject_two's level. Otherwise, it logs a permission
+ * failure on operation `op_s' and returns 0.
+ *
+ * This function is used to mediate pgrp changes.
+ *
+ */
+
+int
+mediate_subject_level_subject(const char *op_s,
+ const lomac_subject_t *p_subject_one, level_t level_one,
+ lomac_subject_t *p_subject_two) {
+
+ lattr_t lattr_two; /* lattr of `p_subject_two' */
+ int ret_val; /* result to return to caller */
+
+#ifdef NO_MEDIATION
+ ret_val = 1; /* no denials, just logging */
+#else
+ ret_val = 0; /* pessimistically assume deny */
+#endif
+
+ get_subject_lattr(p_subject_two, &lattr_two);
+
+ if (lattr_two.level <= level_one) {
+ ret_val = 1; /* OK, allow */
+ } else if (lomac_verbose_demote_deny) {
+ lomac_log_t *logmsg = log_start();
+
+ log_append_string(logmsg, "LOMAC: denied level-");
+ log_append_int(logmsg, level_one);
+ log_append_string(logmsg, " proc ");
+ log_append_subject_id(logmsg, p_subject_one);
+ log_append_string(logmsg, " ");
+ log_append_string(logmsg, op_s);
+ log_append_string(logmsg, " to level-");
+ log_append_int(logmsg, lattr_two.level);
+ log_append_string(logmsg, " proc ");
+ log_append_subject_id(logmsg, p_subject_two);
+ log_print(logmsg);
+ }
+ return (ret_val);
+} /* mediate_subject_subject() */
+
+/* mediate_subject_object()
+ *
+ * in: op_s - string describing operation, like "write" or "writev"
+ * p_subject - subject trying to operate on `p_object'.
+ * p_object - object that `p_subject' is trying to operate on.
+ * out: nothing
+ * return: value condition
+ * ----- ---------
+ * 0 Caller should prevent operation
+ * 1 Caller should permit operation
+ *
+ * This function returns 1 if the level of `p_object' is less than or
+ * equal to the level of `p_subject'. Otherwise, it returns 0 and
+ * logs a permission denial on `op_s'.
+ *
+ * This function allows LOMAC to mediate write and writev system calls.
+ *
+ */
+
+int
+mediate_subject_object(const char *op_s, lomac_subject_t *p_subject,
+ const lomac_object_t *p_object) {
+ lattr_t subject_lattr; /* lattr of `p_subject' */
+ lattr_t object_lattr; /* lattr of `p_object' */
+ int ret_val; /* value to return to caller */
+
+#ifdef NO_MEDIATION
+ ret_val = 1; /* allow operation regardless of decision */
+#else
+ ret_val = 0; /* pessimistically assume deny */
+#endif
+
+ /* Get the lattrs of `p_subject' and `p_object' so we can compare them. */
+ get_subject_lattr(p_subject, &subject_lattr);
+ get_object_lattr(p_object, &object_lattr);
+
+ /*
+ * If `p_subject's level is less than `p_object's level,
+ * we indicate that the operation must not be allowed.
+ */
+
+ if (!lomac_must_deny(&subject_lattr, &object_lattr) ||
+ object_lattr.flags & LOMAC_ATTR_LOWWRITE) {
+ ret_val = 1; /* allow operation */
+ } else if (lomac_verbose_demote_deny) {
+ lomac_log_t *logmsg = log_start();
+ log_append_string(logmsg, "LOMAC: level-");
+ log_append_int(logmsg, subject_lattr.level);
+ log_append_string(logmsg, " proc ");
+ log_append_subject_id(logmsg, p_subject);
+ log_append_string(logmsg, " denied ");
+ log_append_string(logmsg, op_s);
+ log_append_string(logmsg, " to level-");
+ log_append_int(logmsg, object_lattr.level);
+ log_append_string(logmsg, " object ");
+ log_append_object_id(logmsg, p_object);
+ log_append_string(logmsg, "\n");
+ log_print(logmsg);
+ }
+ return (ret_val);
+} /* mediate_subject_object() */
+
+
+/* mediate_subject_object_open()
+ *
+ * in: p_subject - subject trying to operate on `p_object'.
+ * p_object - object that `p_subject' is trying to operate on.
+ * out: nothing
+ * return: value condition
+ * ----- ---------
+ * 0 Caller should prevent operation
+ * 1 Caller should permit operation
+ *
+ * This function returns 1 if the level of `p_object' is less than or
+ * equal to the level of `p_subject'. Otherwise, it returns 0 and
+ * logs a permission denial on `op_s'.
+ *
+ * This function allows LOMAC to mediate open system calls.
+ *
+ */
+
+int
+mediate_subject_object_open(lomac_subject_t *p_subject,
+ const lomac_object_t *p_object) {
+ lattr_t subject_lattr; /* lattr of `p_subject' */
+ lattr_t object_lattr; /* lattr of `p_object' */
+ int ret_val; /* value to return to caller */
+
+#ifdef NO_MEDIATION
+ ret_val = 1; /* allow operation regardless of decision */
+#else
+ ret_val = 0; /* pessimistically assume deny */
+#endif
+
+ /* Get the lattrs of `p_subject' and `p_object' so we can compare them. */
+ get_subject_lattr(p_subject, &subject_lattr);
+ get_object_lattr(p_object, &object_lattr);
+
+ /*
+ * If `p_subject's level is less than `p_object's level,
+ * we must indicate that the operation should not be allowed.
+ */
+ if (lomac_must_deny(&subject_lattr, &object_lattr) &&
+ object_lattr.flags & LOMAC_ATTR_LOWNOOPEN) {
+ if (lomac_verbose_demote_deny) {
+ lomac_log_t *logmsg = log_start();
+
+ log_append_string(logmsg, "LOMAC: level-");
+ log_append_int(logmsg, subject_lattr.level);
+ log_append_string(logmsg, " proc ");
+ log_append_subject_id(logmsg, p_subject);
+ log_append_string(logmsg, " denied open to level-");
+ log_append_int(logmsg, object_lattr.level);
+ log_append_string(logmsg, " object ");
+ log_append_object_id(logmsg, p_object);
+ log_append_string(logmsg, "\n");
+ log_print(logmsg);
+ }
+ } else {
+ ret_val = 1; /* allow operation */
+ } /* if/else allow/deny */
+ return (ret_val);
+} /* mediate_subject_object() */
+
+
+/* mediate_subject_at_level()
+ *
+ * in: op_s - name of operation being mediated
+ * p_subject - subject whose level we want to check
+ * target_level - level to compare to `p_subject's level
+ *
+ * out: nothing
+ * return: value condition
+ * ----- ---------
+ * 0 `p_subject' is not at `target_level'
+ * 1 `p_subject' is at `target_level'
+ *
+ * This function provides a predicate for determining whether or not
+ * `p_subject' is at the level specified by `target_level'. This
+ * function compares `p_subject's level to `target_level'. If the
+ * levels match, it retruns 1. Otherwise, it logs a permission denial
+ * on `op_s' and returns 0.
+ *
+ */
+
+int
+mediate_subject_at_level(const char *op_s, lomac_subject_t *p_subject,
+ const level_t target_level) {
+ lattr_t subject_lattr; /* lattr of `p_subject' */
+ int ret_val; /* value returned to caller */
+
+#ifdef NO_MEDIATION
+ ret_val = 1; /* allow operation regardless of decision */
+#else
+ ret_val = 0; /* pessimistically assume deny */
+#endif
+
+ /* Make `subject_lattr' the lattr of `p_subject'. */
+ get_subject_lattr(p_subject, &subject_lattr);
+
+ /* compare with `target_lattr */
+ if (subject_lattr.level == target_level) {
+ ret_val = 1; /* allow operation */
+ } else if (lomac_verbose_demote_deny) {
+ lomac_log_t *logmsg = log_start();
+
+ log_append_string(logmsg, "LOMAC: denied level-");
+ log_append_int(logmsg, subject_lattr.level);
+ log_append_string(logmsg, " proc ");
+ log_append_subject_id(logmsg, p_subject);
+ log_append_string(logmsg, "'s ");
+ log_append_string(logmsg, op_s);
+ log_append_string(logmsg, ".\n");
+ log_print(logmsg);
+ }
+ return (ret_val);
+} /* mediate_subject_at_level() */
OpenPOWER on IntegriCloud