resolve merge conflicts of e931bdd67b to nyc-dev-plus-aosp.

Change-Id: I34916857283324ea68438b6e358a511e08ec37a0
This commit is contained in:
Jeff Vander Stoep 2016-02-10 10:28:01 -08:00
commit 21ca82658f

View File

@ -80,14 +80,6 @@ enum key_dir {
dir_in, dir_out
};
/**
* The expected "type" of data the value in the key
* value pair should be.
*/
enum data_type {
dt_bool, dt_string
};
struct list_element {
list_element *next;
};
@ -110,9 +102,9 @@ struct key_map_regex {
struct key_map {
char *name;
key_dir dir;
data_type type;
char *data;
key_map_regex regex;
bool (*fn_validate)(char *value, char **errmsg);
};
/**
@ -197,26 +189,32 @@ static list line_order_list = list_init(line_order_list_freefn);
*/
static list nallow_list = list_init(line_order_list_freefn);
/* validation call backs */
static bool validate_bool(char *value, char **errmsg);
static bool validate_levelFrom(char *value, char **errmsg);
static bool validate_selinux_type(char *value, char **errmsg);
static bool validate_selinux_level(char *value, char **errmsg);
/**
* The heart of the mapping process, this must be updated if a new key value pair is added
* to a rule.
*/
key_map rules[] = {
/*Inputs*/
{ .name = "isSystemServer", .type = dt_bool, .dir = dir_in, .data = NULL },
{ .name = "isAutoPlayApp", .type = dt_bool, .dir = dir_in, .data = NULL },
{ .name = "isOwner", .type = dt_bool, .dir = dir_in, .data = NULL },
{ .name = "user", .type = dt_string, .dir = dir_in, .data = NULL },
{ .name = "seinfo", .type = dt_string, .dir = dir_in, .data = NULL },
{ .name = "name", .type = dt_string, .dir = dir_in, .data = NULL },
{ .name = "path", .type = dt_string, .dir = dir_in, .data = NULL },
{ .name = "isPrivApp", .type = dt_bool, .dir = dir_in, .data = NULL },
{ .name = "isSystemServer", .dir = dir_in, .fn_validate = validate_bool },
{ .name = "isAutoPlayApp", .dir = dir_in, .fn_validate = validate_bool },
{ .name = "isOwner", .dir = dir_in, .fn_validate = validate_bool },
{ .name = "user", .dir = dir_in, },
{ .name = "seinfo", .dir = dir_in, },
{ .name = "name", .dir = dir_in, },
{ .name = "path", .dir = dir_in, },
{ .name = "isPrivApp", .dir = dir_in, .fn_validate = validate_bool },
/*Outputs*/
{ .name = "domain", .type = dt_string, .dir = dir_out, .data = NULL },
{ .name = "type", .type = dt_string, .dir = dir_out, .data = NULL },
{ .name = "levelFromUid", .type = dt_bool, .dir = dir_out, .data = NULL },
{ .name = "levelFrom", .type = dt_string, .dir = dir_out, .data = NULL },
{ .name = "level", .type = dt_string, .dir = dir_out, .data = NULL },
{ .name = "domain", .dir = dir_out, .fn_validate = validate_selinux_type },
{ .name = "type", .dir = dir_out, .fn_validate = validate_selinux_type },
{ .name = "levelFromUid", .dir = dir_out, .fn_validate = validate_bool },
{ .name = "levelFrom", .dir = dir_out, .fn_validate = validate_levelFrom },
{ .name = "level", .dir = dir_out, .fn_validate = validate_selinux_level },
};
/**
@ -306,7 +304,7 @@ log_msg(FILE *out, const char *prefix, const char *fmt, ...) {
* statically to this executable and LINK_SEPOL_STATIC is not
* defined.
*/
int check_type(sepol_policydb_t *db, char *type) {
static int check_type(sepol_policydb_t *db, char *type) {
int rc = 1;
#if defined(LINK_SEPOL_STATIC)
@ -353,6 +351,63 @@ static bool compile_regex(key_map *km, const char **errbuf, int *erroff) {
return true;
}
static bool validate_bool(char *value, char **errmsg) {
if (!strcmp("true", value) || !strcmp("false", value)) {
return true;
}
*errmsg = "Expecting \"true\" or \"false\"";
return false;
}
static bool validate_levelFrom(char *value, char **errmsg) {
if(strcasecmp(value, "none") && strcasecmp(value, "all") &&
strcasecmp(value, "app") && strcasecmp(value, "user")) {
*errmsg = "Expecting one of: \"none\", \"all\", \"app\" or \"user\"";
return false;
}
return true;
}
static bool validate_selinux_type(char *value, char **errmsg) {
/*
* No policy file present means we cannot check
* SE Linux types
*/
if (!pol.policy_file) {
return true;
}
if(!check_type(pol.db, value)) {
*errmsg = "Expecting a valid SELinux type";
return false;
}
return true;
}
static bool validate_selinux_level(char *value, char **errmsg) {
/*
* No policy file present means we cannot check
* SE Linux MLS
*/
if (!pol.policy_file) {
return true;
}
int ret = sepol_mls_check(pol.handle, pol.db, value);
if (ret < 0) {
*errmsg = "Expecting a valid SELinux MLS value";
return false;
}
return true;
}
/**
* Validates a key_map against a set of enforcement rules, this
* function exits the application on a type that cannot be properly
@ -371,10 +426,9 @@ static bool key_map_validate(key_map *m, const char *filename, int lineno,
int erroff;
const char *errbuf;
bool rc = true;
int ret = 1;
char *key = m->name;
char *value = m->data;
data_type type = m->type;
char *errmsg = NULL;
log_info("Validating %s=%s\n", key, value);
@ -393,51 +447,13 @@ static bool key_map_validate(key_map *m, const char *filename, int lineno,
goto out;
}
/* Booleans can always be checked for sanity */
if (type == dt_bool && (!strcmp("true", value) || !strcmp("false", value))) {
goto out;
}
else if (type == dt_bool) {
log_error("Expected boolean value got: %s=%s on line: %d in file: %s\n",
key, value, lineno, filename);
rc = false;
goto out;
}
/* If the key has a validation routine, call it */
if (m->fn_validate) {
rc = m->fn_validate(value, &errmsg);
if (!strcasecmp(key, "levelFrom") &&
(strcasecmp(value, "none") && strcasecmp(value, "all") &&
strcasecmp(value, "app") && strcasecmp(value, "user"))) {
log_error("Unknown levelFrom=%s on line: %d in file: %s\n",
value, lineno, filename);
rc = false;
goto out;
}
/*
* If there is no policy file present,
* then it is not going to enforce the types against the policy so just return.
* User and name cannot really be checked.
*/
if (!pol.policy_file) {
goto out;
}
else if (!strcasecmp(key, "type") || !strcasecmp(key, "domain")) {
if(!check_type(pol.db, value)) {
log_error("Could not find selinux type \"%s\" on line: %d in file: %s\n", value,
lineno, filename);
rc = false;
}
goto out;
}
else if (!strcasecmp(key, "level")) {
ret = sepol_mls_check(pol.handle, pol.db, value);
if (ret < 0) {
log_error("Could not find selinux level \"%s\", on line: %d in file: %s\n", value,
lineno, filename);
rc = false;
goto out;
if (!rc) {
log_error("Could not validate key \"%s\" for value \"%s\" on line: %d in file: \"%s\": %s\n", key, value,
lineno, filename, errmsg);
}
}
@ -494,9 +510,6 @@ static map_match rule_map_cmp(rule_map *rmA, rule_map *rmB) {
mB = &(rmB->m[j]);
input_mode = 0;
if (mA->type != mB->type)
continue;
if (strcmp(mA->name, mB->name))
continue;
@ -1096,7 +1109,7 @@ static void parse_file(file_info *in_file) {
return;
err:
log_error("reading %s, line %zu, name %s, value %s\n",
log_error("Reading file: \"%s\" line: %zu name: \"%s\" value: \"%s\"\n",
in_file->name, lineno, name, value);
if(found_whitespace && name && !strcasecmp(name, "neverallow")) {
log_error("perhaps whitespace before neverallow\n");