libselinux: android: fix lax service context lookup

We use the same lookup function for service contexts
that we use for property contexts. However, property
contexts are namespace based and only compare the
prefix. This may lead to service associations with
a wrong label.

This patch introduces a new back end for android
services with a stricter lookup function. Now the
service name must match the key of the service label
exactly.

Signed-off-by: Janis Danisevskis <jdanis@android.com>
This commit is contained in:
Janis Danisevskis 2016-09-29 12:39:18 +01:00 committed by Stephen Smalley
parent b3d9550bcd
commit 6dd85b9e0e
6 changed files with 62 additions and 2 deletions

View File

@ -34,6 +34,8 @@ struct selabel_handle;
#define SELABEL_CTX_DB 3
/* Android property service contexts */
#define SELABEL_CTX_ANDROID_PROP 4
/* Android service contexts */
#define SELABEL_CTX_ANDROID_SERVICE 5
/*
* Available options

View File

@ -45,6 +45,7 @@ static selabel_initfunc initfuncs[] = {
CONFIG_X_BACKEND(selabel_x_init),
CONFIG_DB_BACKEND(selabel_db_init),
&selabel_property_init,
&selabel_service_init,
};
static void selabel_subs_fini(struct selabel_sub *ptr)

View File

@ -244,7 +244,7 @@ static void closef(struct selabel_handle *rec)
free(data);
}
static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
static struct selabel_lookup_rec *property_lookup(struct selabel_handle *rec,
const char *key,
int __attribute__((unused)) type)
{
@ -279,6 +279,38 @@ finish:
return ret;
}
static struct selabel_lookup_rec *service_lookup(struct selabel_handle *rec,
const char *key, int __attribute__((unused)) type)
{
struct saved_data *data = (struct saved_data *)rec->data;
spec_t *spec_arr = data->spec_arr;
unsigned int i;
struct selabel_lookup_rec *ret = NULL;
if (!data->nspec) {
errno = ENOENT;
goto finish;
}
for (i = 0; i < data->nspec; i++) {
if (strcmp(spec_arr[i].property_key, key) == 0)
break;
if (strcmp(spec_arr[i].property_key, "*") == 0)
break;
}
if (i >= data->nspec) {
/* No matching specification. */
errno = ENOENT;
goto finish;
}
ret = &spec_arr[i].lr;
finish:
return ret;
}
static void stats(struct selabel_handle __attribute__((unused)) *rec)
{
selinux_log(SELINUX_WARNING, "'stats' functionality not implemented.\n");
@ -298,7 +330,25 @@ int selabel_property_init(struct selabel_handle *rec,
rec->data = data;
rec->func_close = &closef;
rec->func_stats = &stats;
rec->func_lookup = &lookup;
rec->func_lookup = &property_lookup;
return init(rec, opts, nopts);
}
int selabel_service_init(struct selabel_handle *rec,
const struct selinux_opt *opts, unsigned nopts)
{
struct saved_data *data;
data = (struct saved_data *)malloc(sizeof(*data));
if (!data)
return -1;
memset(data, 0, sizeof(*data));
rec->data = data;
rec->func_close = &closef;
rec->func_stats = &stats;
rec->func_lookup = &service_lookup;
return init(rec, opts, nopts);
}

View File

@ -39,6 +39,9 @@ int selabel_db_init(struct selabel_handle *rec,
int selabel_property_init(struct selabel_handle *rec,
const struct selinux_opt *opts,
unsigned nopts) hidden;
int selabel_service_init(struct selabel_handle *rec,
const struct selinux_opt *opts,
unsigned nopts) hidden;
/*
* Labeling internal structures

View File

@ -92,6 +92,8 @@ int main(int argc, char **argv)
backend = SELABEL_CTX_DB;
} else if (!strcmp(optarg, "prop")) {
backend = SELABEL_CTX_ANDROID_PROP;
} else if (!strcmp(optarg, "service")) {
backend = SELABEL_CTX_ANDROID_SERVICE;
} else {
fprintf(stderr, "Unknown backend: %s\n",
optarg);

View File

@ -57,6 +57,8 @@ int main(int argc, char **argv)
backend = SELABEL_CTX_DB;
} else if (!strcmp(optarg, "prop")) {
backend = SELABEL_CTX_ANDROID_PROP;
} else if (!strcmp(optarg, "service")) {
backend = SELABEL_CTX_ANDROID_SERVICE;
} else {
fprintf(stderr, "Unknown backend: %s\n",
optarg);