Skip to content

Commit

Permalink
Support Android/M and official v30 sepolicy format
Browse files Browse the repository at this point in the history
Some Android M devices use a slightly different format for the sepolicy
file.  Compatibility for this is not present in SELinuxProject/selinux
master.  Google does provide a patch for the kernel itself to be able to
handle both formats - https://android-review.googlesource.com/#/c/179568/ -
but not for libsepol. This patch is a port of the kernel patch to
libsepol.

Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
  • Loading branch information
Chainfire authored and stephensmalley committed Dec 13, 2016
1 parent 7179fd8 commit dc80339
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 10 deletions.
13 changes: 13 additions & 0 deletions libsepol/src/android_m_compat.c
@@ -0,0 +1,13 @@
#include <stdio.h>

#include "android_m_compat.h"

unsigned int avtab_android_m_compat;

void avtab_android_m_compat_set(void)
{
if (!avtab_android_m_compat) {
fprintf(stderr, "(Android M policy compatibility mode)\n");
avtab_android_m_compat = 1;
}
}
18 changes: 18 additions & 0 deletions libsepol/src/android_m_compat.h
@@ -0,0 +1,18 @@
/*
* extended permissions compatibility. Make ToT Android kernels compatible
* with Android M releases
*/
#define AVTAB_OPTYPE_ALLOWED 0x1000
#define AVTAB_OPTYPE_AUDITALLOW 0x2000
#define AVTAB_OPTYPE_DONTAUDIT 0x4000
#define AVTAB_OPTYPE (AVTAB_OPTYPE_ALLOWED | \
AVTAB_OPTYPE_AUDITALLOW | \
AVTAB_OPTYPE_DONTAUDIT)
#define AVTAB_XPERMS_OPTYPE 4

#define avtab_xperms_to_optype(x) (x << AVTAB_XPERMS_OPTYPE)
#define avtab_optype_to_xperms(x) (x >> AVTAB_XPERMS_OPTYPE)

extern unsigned int avtab_android_m_compat;

void avtab_android_m_compat_set(void);
31 changes: 26 additions & 5 deletions libsepol/src/avtab.c
Expand Up @@ -48,6 +48,7 @@

#include "debug.h"
#include "private.h"
#include "android_m_compat.h"

/* Based on MurmurHash3, written by Austin Appleby and placed in the
* public domain.
Expand Down Expand Up @@ -440,6 +441,7 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
avtab_key_t key;
avtab_datum_t datum;
avtab_extended_perms_t xperms;
unsigned int android_m_compat_optype = 0;
unsigned set;
unsigned int i;
int rc;
Expand Down Expand Up @@ -529,6 +531,13 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
key.target_class = le16_to_cpu(buf16[items++]);
key.specified = le16_to_cpu(buf16[items++]);

if ((key.specified & AVTAB_OPTYPE) &&
(vers == POLICYDB_VERSION_XPERMS_IOCTL)) {
key.specified = avtab_optype_to_xperms(key.specified);
android_m_compat_optype = 1;
avtab_android_m_compat_set();
}

set = 0;
for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
if (key.specified & spec_order[i])
Expand All @@ -551,12 +560,24 @@ int avtab_read_item(struct policy_file *fp, uint32_t vers, avtab_t * a,
return -1;
}
xperms.specified = buf8;
rc = next_entry(&buf8, fp, sizeof(uint8_t));
if (rc < 0) {
ERR(fp->handle, "truncated entry");
return -1;
if (avtab_android_m_compat ||
((xperms.specified != AVTAB_XPERMS_IOCTLFUNCTION) &&
(xperms.specified != AVTAB_XPERMS_IOCTLDRIVER) &&
(vers == POLICYDB_VERSION_XPERMS_IOCTL))) {
xperms.driver = xperms.specified;
if (android_m_compat_optype)
xperms.specified = AVTAB_XPERMS_IOCTLDRIVER;
else
xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION;
avtab_android_m_compat_set();
} else {
rc = next_entry(&buf8, fp, sizeof(uint8_t));
if (rc < 0) {
ERR(fp->handle, "truncated entry");
return -1;
}
xperms.driver = buf8;
}
xperms.driver = buf8;
rc = next_entry(buf32, fp, sizeof(uint32_t)*8);
if (rc < 0) {
ERR(fp->handle, "truncated entry");
Expand Down
17 changes: 12 additions & 5 deletions libsepol/src/write.c
Expand Up @@ -44,6 +44,7 @@
#include "debug.h"
#include "private.h"
#include "mls.h"
#include "android_m_compat.h"

struct policy_data {
struct policy_file *fp;
Expand Down Expand Up @@ -217,7 +218,11 @@ static int avtab_write_item(policydb_t * p,
buf16[0] = cpu_to_le16(cur->key.source_type);
buf16[1] = cpu_to_le16(cur->key.target_type);
buf16[2] = cpu_to_le16(cur->key.target_class);
buf16[3] = cpu_to_le16(cur->key.specified);
if (avtab_android_m_compat && (cur->key.specified & AVTAB_XPERMS) &&
(cur->datum.xperms->specified == AVTAB_XPERMS_IOCTLDRIVER))
buf16[3] = cpu_to_le16(avtab_xperms_to_optype(cur->key.specified));
else
buf16[3] = cpu_to_le16(cur->key.specified);
items = put_entry(buf16, sizeof(uint16_t), 4, fp);
if (items != 4)
return POLICYDB_ERROR;
Expand All @@ -237,10 +242,12 @@ static int avtab_write_item(policydb_t * p,
}

if (cur->key.specified & AVTAB_XPERMS) {
buf8 = cur->datum.xperms->specified;
items = put_entry(&buf8, sizeof(uint8_t),1,fp);
if (items != 1)
return POLICYDB_ERROR;
if (avtab_android_m_compat == 0) {
buf8 = cur->datum.xperms->specified;
items = put_entry(&buf8, sizeof(uint8_t),1,fp);
if (items != 1)
return POLICYDB_ERROR;
}
buf8 = cur->datum.xperms->driver;
items = put_entry(&buf8, sizeof(uint8_t),1,fp);
if (items != 1)
Expand Down

0 comments on commit dc80339

Please sign in to comment.