Re: type bounds audit messages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The attached patch allows to generate audit messages on access violations
related to bounds types.

1. When a multithread process gives an unbounded domain to setcon(3)
   to change its domain dynamically, the current kernel denies it
   without any notification or audit messages.
   This patch adds an audit_log() in the security_bounded_transition()
   to generate an audit message, when the dynamic type transition is
   failed due to the bounds violation.

   Example:
   type=SELINUX_ERR msg=audit(1245046106.725:65): SELinux: bounds violation: \
       domain transition from httpd_t to guest_webapp_t

2. When a set of permissions are masked due to the bounds violations,
   it shall be reported on the type_attribute_bounds_av() invoked from
   context_struct_context_av(), but it keeps silent on any AVC denials.
   It may make unclear what permissions were in violation of the boundary.
   This patch adds the "masked" field on av_decision, and it reports
   violated permissions on AVC denials.

   Example:
   type=AVC msg=audit(1245046439.315:72): avc:  denied  { create }     \
     for pid=3080 comm="httpd" name="hoge"                             \
     scontext=unconfined_u:system_r:user_webapp_t:s0                   \
     tcontext=unconfined_u:object_r:httpd_sys_content_t:s0 tclass=file \
     bounds: { create }
     ^^^^^^^^^^^^^^^^^^

Signed-off-by: KaiGai Kohei <kaigai@xxxxxxxxxxxxx>
--
 security/selinux/avc.c              |    7 ++++-
 security/selinux/include/security.h |    1 +
 security/selinux/ss/services.c      |   47 ++++++++++++++--------------------
 3 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 7f9b5fa..c385e3b 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -536,7 +536,7 @@ void avc_audit(u32 ssid, u32 tsid,
 {
 	struct task_struct *tsk = current;
 	struct inode *inode = NULL;
-	u32 denied, audited;
+	u32 denied, audited, masked = 0;
 	struct audit_buffer *ab;

 	denied = requested & ~avd->allowed;
@@ -544,6 +544,7 @@ void avc_audit(u32 ssid, u32 tsid,
 		audited = denied;
 		if (!(audited & avd->auditdeny))
 			return;
+		masked = audited & avd->masked;
 	} else if (result) {
 		audited = denied = requested;
 	} else {
@@ -688,6 +689,10 @@ void avc_audit(u32 ssid, u32 tsid,
 	}
 	audit_log_format(ab, " ");
 	avc_dump_query(ab, ssid, tsid, tclass);
+	if (masked) {
+		audit_log_format(ab, " bounds:");
+		avc_dump_av(ab, tclass, masked);
+	}
 	audit_log_end(ab);
 }

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 5c3434f..07e7a01 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -91,6 +91,7 @@ struct av_decision {
 	u32 auditallow;
 	u32 auditdeny;
 	u32 seqno;
+	u32 masked;	/* masked by bounds types */
 };

 int security_permissive_sid(u32 sid);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index deeec6c..349bfb2 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -295,7 +295,6 @@ static void type_attribute_bounds_av(struct context *scontext,
 		= policydb.type_val_to_struct[scontext->type - 1];
 	struct type_datum *target
 		= policydb.type_val_to_struct[tcontext->type - 1];
-	u32 masked = 0;

 	if (source->bounds) {
 		memset(&lo_avd, 0, sizeof(lo_avd));
@@ -310,7 +309,7 @@ static void type_attribute_bounds_av(struct context *scontext,
 					  &lo_avd);
 		if ((lo_avd.allowed & avd->allowed) == avd->allowed)
 			return;		/* no masked permission */
-		masked = ~lo_avd.allowed & avd->allowed;
+		avd->masked = ~lo_avd.allowed & avd->allowed;
 	}

 	if (target->bounds) {
@@ -326,7 +325,7 @@ static void type_attribute_bounds_av(struct context *scontext,
 					  &lo_avd);
 		if ((lo_avd.allowed & avd->allowed) == avd->allowed)
 			return;		/* no masked permission */
-		masked = ~lo_avd.allowed & avd->allowed;
+		avd->masked = ~lo_avd.allowed & avd->allowed;
 	}

 	if (source->bounds && target->bounds) {
@@ -343,33 +342,12 @@ static void type_attribute_bounds_av(struct context *scontext,
 					  &lo_avd);
 		if ((lo_avd.allowed & avd->allowed) == avd->allowed)
 			return;		/* no masked permission */
-		masked = ~lo_avd.allowed & avd->allowed;
+		avd->masked = ~lo_avd.allowed & avd->allowed;
 	}

-	if (masked) {
-		struct audit_buffer *ab;
-		char *stype_name
-			= policydb.p_type_val_to_name[source->value - 1];
-		char *ttype_name
-			= policydb.p_type_val_to_name[target->value - 1];
-		char *tclass_name
-			= policydb.p_class_val_to_name[tclass - 1];
-
-		/* mask violated permissions */
-		avd->allowed &= ~masked;
-
-		/* notice to userspace via audit message */
-		ab = audit_log_start(current->audit_context,
-				     GFP_ATOMIC, AUDIT_SELINUX_ERR);
-		if (!ab)
-			return;
-
-		audit_log_format(ab, "av boundary violation: "
-				 "source=%s target=%s tclass=%s",
-				 stype_name, ttype_name, tclass_name);
-		avc_dump_av(ab, tclass, masked);
-		audit_log_end(ab);
-	}
+	/* mask violated permissions */
+	if (avd->masked)
+		avd->allowed &= ~avd->masked;
 }

 /*
@@ -410,6 +388,7 @@ static int context_struct_compute_av(struct context *scontext,
 	avd->auditallow = 0;
 	avd->auditdeny = 0xffffffff;
 	avd->seqno = latest_granting;
+	avd->masked = 0;

 	/*
 	 * Check for all the invalid cases.
@@ -711,6 +690,18 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
 		}
 		index = type->bounds;
 	}
+
+	if (rc) {
+		char *old_name
+			= policydb.p_type_val_to_name[old_context->type - 1];
+		char *new_name
+			= policydb.p_type_val_to_name[new_context->type - 1];
+
+		audit_log(current->audit_context,
+			  GFP_ATOMIC, AUDIT_SELINUX_ERR,
+			  "SELinux: bounds violation: domain transition "
+			  "from %s to %s", old_name, new_name);
+	}
 out:
 	read_unlock(&policy_rwlock);

-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@xxxxxxxxxxxxx>

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux