diff --git a/libselinux/include/selinux/label.h b/libselinux/include/selinux/label.h index f0b1e10d..277287ed 100644 --- a/libselinux/include/selinux/label.h +++ b/libselinux/include/selinux/label.h @@ -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 diff --git a/libselinux/src/label.c b/libselinux/src/label.c index 96a4ff11..eb0e7665 100644 --- a/libselinux/src/label.c +++ b/libselinux/src/label.c @@ -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) diff --git a/libselinux/src/label_backends_android.c b/libselinux/src/label_backends_android.c index 290b4382..4d6ec86e 100644 --- a/libselinux/src/label_backends_android.c +++ b/libselinux/src/label_backends_android.c @@ -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); } diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h index 7c555315..6a9481af 100644 --- a/libselinux/src/label_internal.h +++ b/libselinux/src/label_internal.h @@ -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 diff --git a/libselinux/utils/selabel_digest.c b/libselinux/utils/selabel_digest.c index 38162a5b..e4d84a5a 100644 --- a/libselinux/utils/selabel_digest.c +++ b/libselinux/utils/selabel_digest.c @@ -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); diff --git a/libselinux/utils/selabel_lookup.c b/libselinux/utils/selabel_lookup.c index d0b14572..b678a895 100644 --- a/libselinux/utils/selabel_lookup.c +++ b/libselinux/utils/selabel_lookup.c @@ -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);