From 3a68bd169bc7e7701df79417f66af08fc7ce8718 Mon Sep 17 00:00:00 2001 From: Dan Cashman Date: Thu, 30 Mar 2017 14:51:51 -0700 Subject: [PATCH] Add reverse-attribute mapping to sepolicy-analyze. sepolicy-analyze allows users to see all types that have a given attribute, but not the reverse case: all attributes of a given type. Add a '--reverse' option which enables this, but keeps the previous interface. Usage: sepolicy-analyze sepolicy attribute -r init Bug: 36508258 Test: Build and run against current policy. (cherry picked from commit d444ebedac021e0468e8a1a3f3a699fbcc34b1f3) Change-Id: I9813ebf61d50fb5abbc8e52be4cf62751979bbd4 --- tools/sepolicy-analyze/README | 4 ++ tools/sepolicy-analyze/attribute.c | 76 +++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/tools/sepolicy-analyze/README b/tools/sepolicy-analyze/README index d18609a7c..fdee588e1 100644 --- a/tools/sepolicy-analyze/README +++ b/tools/sepolicy-analyze/README @@ -65,6 +65,10 @@ sepolicy-analyze Displays the types associated with the specified attribute name. + sepolicy-analyze out/target/product//root/sepolicy attribute -r + + Displays the attributes associated with the specified type name. + NEVERALLOW CHECKING (neverallow) sepolicy-analyze out/target/product//root/sepolicy neverallow \ [-w] [-d] [-f neverallows.conf] | [-n "neverallow string"] diff --git a/tools/sepolicy-analyze/attribute.c b/tools/sepolicy-analyze/attribute.c index 474bda2fd..ae98aa98c 100644 --- a/tools/sepolicy-analyze/attribute.c +++ b/tools/sepolicy-analyze/attribute.c @@ -1,39 +1,81 @@ +#include + #include "attribute.h" void attribute_usage() { - fprintf(stderr, "\tattribute \n"); + fprintf(stderr, "\tattribute [-r|--reverse]\n"); } -static int list_attribute(policydb_t * policydb, char *name) -{ - struct type_datum *attr; +static void retrieve_mapping(policydb_t *policydb, struct type_datum *dat, char *name, int reverse) { struct ebitmap_node *n; unsigned int bit; - attr = hashtab_search(policydb->p_types.table, name); - if (!attr) { + if (reverse) { + ebitmap_for_each_bit(&policydb->type_attr_map[dat->s.value - 1], n, bit) { + if (!ebitmap_node_get_bit(n, bit)) + continue; + if (!strcmp(policydb->p_type_val_to_name[bit], name)) + continue; + printf("%s\n", policydb->p_type_val_to_name[bit]); + } + } else { + ebitmap_for_each_bit(&policydb->attr_type_map[dat->s.value - 1], n, bit) { + if (!ebitmap_node_get_bit(n, bit)) + continue; + printf("%s\n", policydb->p_type_val_to_name[bit]); + } + } +} + +static int list_attribute(policydb_t *policydb, char *name, int reverse) +{ + struct type_datum *dat; + + dat = hashtab_search(policydb->p_types.table, name); + if (!dat) { fprintf(stderr, "%s is not defined in this policy.\n", name); return -1; } - if (attr->flavor != TYPE_ATTRIB) { - fprintf(stderr, "%s is a type not an attribute in this policy.\n", name); - return -1; - } - - ebitmap_for_each_bit(&policydb->attr_type_map[attr->s.value - 1], n, bit) { - if (!ebitmap_node_get_bit(n, bit)) - continue; - printf("%s\n", policydb->p_type_val_to_name[bit]); + if (reverse) { + if (dat->flavor != TYPE_TYPE) { + fprintf(stderr, "%s is an attribute not a type in this policy.\n", name); + return -1; + } + } else { + if (dat->flavor != TYPE_ATTRIB) { + fprintf(stderr, "%s is a type not an attribute in this policy.\n", name); + return -1; + } } + retrieve_mapping(policydb, dat, name, reverse); return 0; } int attribute_func (int argc, char **argv, policydb_t *policydb) { - if (argc != 2) { + int reverse = 0; + char ch; + + struct option attribute_options[] = { + {"reverse", no_argument, NULL, 'r'}, + {NULL, 0, NULL, 0} + }; + + while ((ch = getopt_long(argc, argv, "r", attribute_options, NULL)) != -1) { + switch (ch) { + case 'r': + reverse = 1; + break; + default: + USAGE_ERROR = true; + return -1; + } + } + + if (argc != 2 && !(reverse && argc == 3)) { USAGE_ERROR = true; return -1; } - return list_attribute(policydb, argv[1]); + return list_attribute(policydb, argv[optind], reverse); }