summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpcraig <rpcraig@tycho.ncsc.mil>2012-08-01 15:35:37 -0400
committerrpcraig <rpcraig@tycho.ncsc.mil>2012-08-02 09:49:31 -0400
commitf1724a371be1678ebf79474ab9a390dd6a5c96c7 (patch)
treeff1df44a222d83c9c3dc27c8b225254e5d5395f1
parente8b0fd8c21a68fd0a7fcf656a7b6eae10e61c8e5 (diff)
downloadlibselinux-f1724a371be1678ebf79474ab9a390dd6a5c96c7.tar.gz
Add sepolicy loading functionality.
These changes reflect changes made to init. The sepolicy reload now happens in libselinux.
-rw-r--r--include/selinux/android.h4
-rw-r--r--src/android.c95
2 files changed, 95 insertions, 4 deletions
diff --git a/include/selinux/android.h b/include/selinux/android.h
index a019d74..2711655 100644
--- a/include/selinux/android.h
+++ b/include/selinux/android.h
@@ -12,6 +12,10 @@ extern "C" {
extern struct selabel_handle* selinux_android_file_context_handle(void);
+extern int selinux_android_load_policy(void);
+
+extern int selinux_android_reload_policy(void);
+
extern int selinux_android_setcontext(uid_t uid,
int isSystemServer,
const char *seinfo,
diff --git a/src/android.c b/src/android.c
index 5440f2a..1024e88 100644
--- a/src/android.c
+++ b/src/android.c
@@ -7,6 +7,8 @@
#include <errno.h>
#include <pwd.h>
#include <grp.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -34,6 +36,11 @@ static const struct selinux_opt seopts[] = {
{ SELABEL_OPT_PATH, "/file_contexts" },
{ 0, NULL } };
+static const char *const sepolicy_prefix[] = {
+ "/data/system/sepolicy",
+ "/sepolicy",
+ 0 };
+
struct seapp_context {
/* input selectors */
char isSystemServer;
@@ -582,7 +589,7 @@ static void file_context_init(void)
}
if (!sehandle)
- selinux_log(SELINUX_ERROR,"%s: Error getting sehandle label (%s)\n",
+ selinux_log(SELINUX_ERROR, "%s: Error getting sehandle label (%s)\n",
__FUNCTION__, strerror(errno));
}
@@ -635,9 +642,89 @@ bail:
}
-struct selabel_handle* selinux_android_file_context_handle(void) {
+struct selabel_handle* selinux_android_file_context_handle(void)
+{
+ __selinux_once(fc_once, file_context_init);
+
+ return sehandle;
+}
+
+int selinux_android_reload_policy(void)
+{
+ char path[PATH_MAX];
+ int fd = -1, rc, vers;
+ struct stat sb;
+ void *map = NULL;
+ int i = 0;
+
+ vers = security_policyvers();
+ if (vers <= 0) {
+ selinux_log(SELINUX_ERROR, "SELinux: Unable to read policy version\n");
+ return -1;
+ }
+ selinux_log(SELINUX_INFO, "SELinux: Maximum supported policy version: %d\n", vers);
+
+ while (fd < 0 && sepolicy_prefix[i]) {
+ snprintf(path, sizeof(path), "%s.%d",
+ sepolicy_prefix[i], vers);
+ fd = open(path, O_RDONLY);
+
+ int max_vers = vers;
+ while (fd < 0 && errno == ENOENT && --max_vers) {
+ snprintf(path, sizeof(path), "%s.%d",
+ sepolicy_prefix[i], max_vers);
+ fd = open(path, O_RDONLY);
+ }
+ i++;
+ }
+ if (fd < 0) {
+ selinux_log(SELINUX_ERROR, "SELinux: Could not open sepolicy: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ if (fstat(fd, &sb) < 0) {
+ selinux_log(SELINUX_ERROR, "SELinux: Could not stat %s: %s\n",
+ path, strerror(errno));
+ close(fd);
+ return -1;
+ }
+ map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (map == MAP_FAILED) {
+ selinux_log(SELINUX_ERROR, "SELinux: Could not map %s: %s\n",
+ path, strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ rc = security_load_policy(map, sb.st_size);
+ if (rc < 0) {
+ selinux_log(SELINUX_ERROR, "SELinux: Could not load policy: %s\n",
+ strerror(errno));
+ munmap(map, sb.st_size);
+ close(fd);
+ return -1;
+ }
+
+ munmap(map, sb.st_size);
+ close(fd);
+ selinux_log(SELINUX_INFO, "SELinux: Loaded policy from %s\n", path);
+
+ return 0;
+}
- __selinux_once(fc_once, file_context_init);
+int selinux_android_load_policy(void)
+{
+ mkdir(SELINUXMNT, 0755);
+ if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, NULL)) {
+ if (errno == ENODEV) {
+ /* SELinux not enabled in kernel */
+ return -1;
+ }
+ selinux_log(SELINUX_ERROR,"SELinux: Could not mount selinuxfs: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ set_selinuxmnt(SELINUXMNT);
- return sehandle;
+ return selinux_android_reload_policy();
}