From 7645d0655dd569a3c573b0457bee87bb95094395 Mon Sep 17 00:00:00 2001
From: Dan Walsh <dwalsh@redhat.com>
Date: Wed, 9 Oct 2013 16:18:15 -0400
Subject: [PATCH 15/74] Add selinux_current_policy_path, which returns the a
 pointer to the loaded policy

Also change audit2why to look at the loaded policy rather then searching on disk for
the policy file.  It is more likely that you are examining the running policy.
---
 libselinux/include/selinux/selinux.h              |  1 +
 libselinux/man/man3/selinux_binary_policy_path.3  |  7 ++++++-
 libselinux/man/man3/selinux_current_policy_path.3 |  1 +
 libselinux/src/audit2why.c                        | 24 ++++------------------
 libselinux/src/selinux_config.c                   | 25 +++++++++++++++++++++++
 libselinux/src/selinux_internal.h                 |  1 +
 policycoreutils/audit2allow/sepolgen-ifgen        |  3 +++
 7 files changed, 41 insertions(+), 21 deletions(-)
 create mode 100644 libselinux/man/man3/selinux_current_policy_path.3

diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
index a359f7f..52d6700 100644
--- a/libselinux/include/selinux/selinux.h
+++ b/libselinux/include/selinux/selinux.h
@@ -505,6 +505,7 @@ extern int selinux_set_policy_root(const char *rootpath);
 
 /* These functions return the paths to specific files under the 
    policy root directory. */
+extern const char *selinux_current_policy_path(void);
 extern const char *selinux_binary_policy_path(void);
 extern const char *selinux_failsafe_context_path(void);
 extern const char *selinux_removable_context_path(void);
diff --git a/libselinux/man/man3/selinux_binary_policy_path.3 b/libselinux/man/man3/selinux_binary_policy_path.3
index ec97dcf..503c52c 100644
--- a/libselinux/man/man3/selinux_binary_policy_path.3
+++ b/libselinux/man/man3/selinux_binary_policy_path.3
@@ -1,6 +1,6 @@
 .TH "selinux_binary_policy_path" "3" "15 November 2004" "dwalsh@redhat.com" "SELinux API Documentation"
 .SH "NAME"
-selinux_path, selinux_policy_root, selinux_binary_policy_path,
+selinux_path, selinux_policy_root, selinux_binary_policy_path, selinux_current_policy_path,
 selinux_failsafe_context_path, selinux_removable_context_path,
 selinux_default_context_path, selinux_user_contexts_path,
 selinux_file_context_path, selinux_media_context_path,
@@ -17,6 +17,8 @@ directories and files
 .sp
 .B const char *selinux_binary_policy_path(void);
 .sp
+.B const char *selinux_current_policy_path(void);
+.sp
 .B const char *selinux_failsafe_context_path(void);
 .sp
 .B const char *selinux_removable_context_path(void);
@@ -55,6 +57,9 @@ returns the top-level policy directory.
 .BR selinux_binary_policy_path ()
 returns the binary policy file loaded into kernel.
 .sp
+.BR selinux_current_policy_path ()
+returns the currently loaded policy file from the kernel.
+.sp
 .BR selinux_default_type_path ()
 returns the context file mapping roles to default types.
 .sp
diff --git a/libselinux/man/man3/selinux_current_policy_path.3 b/libselinux/man/man3/selinux_current_policy_path.3
new file mode 100644
index 0000000..175a611
--- /dev/null
+++ b/libselinux/man/man3/selinux_current_policy_path.3
@@ -0,0 +1 @@
+.so man3/selinux_binary_policy_path.3
diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c
index 2d68482..f1086a9 100644
--- a/libselinux/src/audit2why.c
+++ b/libselinux/src/audit2why.c
@@ -191,7 +191,6 @@ static PyObject *finish(PyObject *self __attribute__((unused)), PyObject *args)
 static int __policy_init(const char *init_path)
 {
 	FILE *fp;
-	int vers = 0;
 	char path[PATH_MAX];
 	char errormsg[PATH_MAX];
 	struct sepol_policy_file *pf = NULL;
@@ -210,27 +209,12 @@ static int __policy_init(const char *init_path)
 			return 1;
 		}
 	} else {
-		vers = sepol_policy_kern_vers_max();
-		if (vers < 0) {
-			snprintf(errormsg, sizeof(errormsg), 
-				 "Could not get policy version:  %s\n",
-				 strerror(errno));
-			PyErr_SetString( PyExc_ValueError, errormsg);
-			return 1;
-		}
-		snprintf(path, PATH_MAX, "%s.%d",
-			 selinux_binary_policy_path(), vers);
-		fp = fopen(path, "r");
-		while (!fp && errno == ENOENT && --vers) {
-			snprintf(path, PATH_MAX, "%s.%d",
-				 selinux_binary_policy_path(), vers);
-			fp = fopen(path, "r");
-		}
+		fp = fopen(selinux_current_policy_path(), "r");
 		if (!fp) {
 			snprintf(errormsg, sizeof(errormsg), 
-				 "unable to open %s.%d:  %s\n",
-				 selinux_binary_policy_path(),
-				 security_policyvers(), strerror(errno));
+				 "unable to open %s:  %s\n",
+				 selinux_current_policy_path(),
+				 strerror(errno));
 			PyErr_SetString( PyExc_ValueError, errormsg);
 			return 1;
 		}
diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c
index 020d57a..2cd6d54 100644
--- a/libselinux/src/selinux_config.c
+++ b/libselinux/src/selinux_config.c
@@ -344,6 +344,31 @@ const char *selinux_binary_policy_path(void)
 
 hidden_def(selinux_binary_policy_path)
 
+const char *selinux_current_policy_path(void)
+{
+	int rc = 0;
+	int vers = 0;
+	static char policy_path[PATH_MAX];
+
+	if (selinux_mnt) {
+		snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt);
+		if (access(policy_path, F_OK) == 0 ) {
+			return policy_path;
+		}
+	}
+	vers = security_policyvers();
+	do {
+		/* Check prior versions to see if old policy is available */
+		snprintf(policy_path, sizeof(policy_path), "%s.%d",
+			 selinux_binary_policy_path(), vers);
+	} while ((rc = access(policy_path, F_OK)) && --vers > 0);
+	
+	if (rc) return NULL;
+	return policy_path;
+}
+
+hidden_def(selinux_current_policy_path)
+
 const char *selinux_file_context_path(void)
 {
 	return get_path(FILE_CONTEXTS);
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
index 7c930e5..afb2170 100644
--- a/libselinux/src/selinux_internal.h
+++ b/libselinux/src/selinux_internal.h
@@ -60,6 +60,7 @@ hidden_proto(selinux_mkload_policy)
     hidden_proto(security_setenforce)
     hidden_proto(security_deny_unknown)
     hidden_proto(selinux_boolean_sub)
+    hidden_proto(selinux_current_policy_path)
     hidden_proto(selinux_binary_policy_path)
     hidden_proto(selinux_booleans_subs_path)
     hidden_proto(selinux_default_context_path)
diff --git a/policycoreutils/audit2allow/sepolgen-ifgen b/policycoreutils/audit2allow/sepolgen-ifgen
index ef4bec3..3967ba5 100644
--- a/policycoreutils/audit2allow/sepolgen-ifgen
+++ b/policycoreutils/audit2allow/sepolgen-ifgen
@@ -62,6 +62,9 @@ def parse_options():
     return options
 
 def get_policy():
+    p = selinux.selinux_current_policy_path()
+    if os.path.exists(p):
+        return p
     i = selinux.security_policyvers()
     p = selinux.selinux_binary_policy_path() + "." + str(i)
     while i > 0 and not os.path.exists(p):
-- 
1.8.3.1

