summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2015-02-19 09:42:58 -0500
committerStephen Smalley <sds@tycho.nsa.gov>2015-02-19 15:34:11 -0500
commit1e9d2765137f7623ea590efdbb8b521ca5d7e416 (patch)
tree7f2731251bfd7c8333a8b08849c77cf029850f3e
parent818815ed55b3b0c118964db65339d230b1493d87 (diff)
downloadlibselinux-1e9d2765137f7623ea590efdbb8b521ca5d7e416.tar.gz
libselinux: Only use /data/security policy if all files are present.
Otherwise if we have a matching selinux_version but only a subset of the expected policy files (sepolicy, *_contexts) under /data/security, then we'll fail when attempting to open the missing files. This does not check that mac_permissions.xml is present as that is only opened and used by SELinuxMMAC, not by libselinux, but we should likely change SELinuxMMAC to do the same. The alternative would be to change the logic for opening each policy file to fall back to the / policy if the /data/security policy is missing, as we used to do before the /data/security support was first disabled and then reworked to check selinux_version. Then it would be valid once again to merely push a sepolicy file or any other individual file with a selinux_version file to /data/security/current without needing to copy the rest of the files if they were unchanged. That is how we used to support pushing a policy with dontaudit rules stripped, http://seandroid.bitbucket.org/AddressingHiddenDenials.html I have updated those instructions to specify that all files must be copied but it is a bit more cumbersome to do so. Change-Id: I60f7ac1f6fa714c0b827a1edd008da172ef1c991 Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
-rw-r--r--src/android.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/src/android.c b/src/android.c
index 3ae2791..4f6a465 100644
--- a/src/android.c
+++ b/src/android.c
@@ -85,52 +85,56 @@ static void set_policy_index(void)
if (fd_base < 0)
return;
- if (fstat(fd_base, &sb_base) < 0) {
- close(fd_base);
- return;
- }
+ if (fstat(fd_base, &sb_base) < 0)
+ goto close_base;
fd_override = open(POLICY_OVERRIDE_VERSION, O_RDONLY | O_NOFOLLOW);
- if (fd_override < 0) {
- close(fd_base);
- return;
- }
+ if (fd_override < 0)
+ goto close_base;
- if (fstat(fd_override, &sb_override) < 0) {
- close(fd_base);
- close(fd_override);
- return;
- }
+ if (fstat(fd_override, &sb_override) < 0)
+ goto close_override;
- if (sb_base.st_size != sb_override.st_size) {
- close(fd_base);
- close(fd_override);
- return;
- }
+ if (sb_base.st_size != sb_override.st_size)
+ goto close_override;
map_base = mmap(NULL, sb_base.st_size, PROT_READ, MAP_PRIVATE, fd_base, 0);
- if (map_base == MAP_FAILED) {
- close(fd_base);
- close(fd_override);
- return;
- }
+ if (map_base == MAP_FAILED)
+ goto close_override;
map_override = mmap(NULL, sb_override.st_size, PROT_READ, MAP_PRIVATE, fd_override, 0);
- if (map_override == MAP_FAILED) {
- munmap(map_base, sb_base.st_size);
- close(fd_base);
- close(fd_override);
- return;
- }
+ if (map_override == MAP_FAILED)
+ goto unmap_base;
- if (memcmp(map_base, map_override, sb_base.st_size) == 0)
- policy_index = 1;
+ if (memcmp(map_base, map_override, sb_base.st_size) != 0)
+ goto unmap_override;
+ if (access(sepolicy_file[1], R_OK) != 0)
+ goto unmap_override;
- close(fd_base);
- close(fd_override);
- munmap(map_base, sb_base.st_size);
+ if (access(seopts[1].value, R_OK) != 0)
+ goto unmap_override;
+
+ if (access(seopts_prop[1].value, R_OK) != 0)
+ goto unmap_override;
+
+ if (access(seopts_service[1].value, R_OK) != 0)
+ goto unmap_override;
+
+ if (access(seapp_contexts_file[1], R_OK) != 0)
+ goto unmap_override;
+
+ policy_index = 1;
+
+unmap_override:
munmap(map_override, sb_override.st_size);
+unmap_base:
+ munmap(map_base, sb_base.st_size);
+close_override:
+ close(fd_override);
+close_base:
+ close(fd_base);
+ return;
}
#if DEBUG