[RFC PATCH] libsepol/cil: support parallel neverallow checks

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

 



Add support to check for neverallow assertions in parallel.  Since the
policy is not modified during those checks there needs to be no
extensive locking.

The checks are run by semodule(8) if the semanage.conf(5) setting
expand-check is set.

Implement the parallel procedure via OpenMP, to minimize code changes
and to allow users a simple way to enable or disable the functionality
at build time.  Currently the support opt-in.

Example benchmark:

    Benchmark 1: ./test_load_wip.sh (serial)
      Time (mean ± σ):      3.485 s ±  0.019 s    [User: 0.003 s, System: 0.002 s]
      Range (min … max):    3.455 s …  3.501 s    5 runs

    Benchmark 1: ./test_load_wip.sh (parallel)
      Time (mean ± σ):      2.443 s ±  0.035 s    [User: 0.004 s, System: 0.001 s]
      Range (min … max):    2.411 s …  2.500 s    5 runs

Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
---
 libsepol/cil/src/cil_binary.c | 60 ++++++++++++++++++++++++++++-------
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index c4ee2380..7f6212e3 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -4828,8 +4828,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
 
 		rc = check_assertion(pdb, rule);
 		if (rc == CIL_TRUE) {
-			*violation = CIL_TRUE;
-			rc = __cil_print_neverallow_failure(db, node);
+			#pragma omp critical (output)
+			{
+				*violation = CIL_TRUE;
+				rc = __cil_print_neverallow_failure(db, node);
+			}
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -4850,8 +4853,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
 			rule->xperms = item->data;
 			rc = check_assertion(pdb, rule);
 			if (rc == CIL_TRUE) {
-				*violation = CIL_TRUE;
-				rc = __cil_print_neverallow_failure(db, node);
+				#pragma omp critical (output)
+				{
+					*violation = CIL_TRUE;
+					rc = __cil_print_neverallow_failure(db, node);
+				}
 				if (rc != SEPOL_OK) {
 					goto exit;
 				}
@@ -4876,18 +4882,48 @@ exit:
 
 static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation)
 {
-	int rc = SEPOL_OK;
-	struct cil_list_item *item;
+	int rc_sync = SEPOL_OK;
+
+	#pragma omp parallel
+	{
+
+		#pragma omp single
+		{
+
+			struct cil_list_item *item;
+			cil_list_for_each(item, neverallows) {
+
+				struct cil_tree_node *node = item->data;
+				int rc_test;
+
+				#pragma omp task default(none) firstprivate(node, db, pdb, violation) shared(rc_sync) untied
+				{
+					int rc_task = cil_check_neverallow(
+						db,
+						pdb,
+						node,
+						violation);
+
+					if (rc_task != SEPOL_OK) {
+						#pragma omp atomic write
+						rc_sync = rc_task;
+					}
+				}
+
+				#pragma omp atomic read
+				rc_test = rc_sync;
+
+				if (rc_test != SEPOL_OK)
+					break;
+
+			}
 
-	cil_list_for_each(item, neverallows) {
-		rc = cil_check_neverallow(db, pdb, item->data, violation);
-		if (rc != SEPOL_OK) {
-			goto exit;
 		}
+
+		#pragma omp taskwait
 	}
 
-exit:
-	return rc;
+	return rc_sync;
 }
 
 static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
-- 
2.40.1




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

  Powered by Linux