Sync internal master and AOSP sepolicy.

Bug: 37916906
Test: Builds 'n' boots.
Change-Id: Ia1d86264446ebecc1ca79f32f11354921bc77668
Merged-In: I208ec6a864127a059fb389417a9c6b259d7474cb
diff --git a/tests/sepol_wrap.cpp b/tests/sepol_wrap.cpp
index a12d438..d537b7e 100644
--- a/tests/sepol_wrap.cpp
+++ b/tests/sepol_wrap.cpp
@@ -17,8 +17,11 @@
 #include <android-base/strings.h>
 #include <sepol_wrap.h>
 
-
+#define TYPE_ITER_LOOKUP   0
+#define TYPE_ITER_ALLTYPES 1
+#define TYPE_ITER_ALLATTRS 2
 struct type_iter {
+    unsigned int alltypes;
     type_datum *d;
     ebitmap_node *n;
     unsigned int length;
@@ -36,23 +39,33 @@
         return NULL;
     }
 
-    out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
-    if (is_attr && out->d->flavor != TYPE_ATTRIB) {
-        std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
-        free(out);
-        return NULL;
-    } else if (!is_attr && out->d->flavor !=TYPE_TYPE) {
-        std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
-        free(out);
-        return NULL;
-    }
-
-    if (is_attr) {
-        out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
-        out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
+    if (type == NULL) {
+        out->length = db->p_types.nprim;
+        out->bit = 0;
+        if (is_attr)
+            out->alltypes = TYPE_ITER_ALLATTRS;
+        else
+            out->alltypes = TYPE_ITER_ALLTYPES;
     } else {
-        out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
-        out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
+        out->alltypes = TYPE_ITER_LOOKUP;
+        out->d = static_cast<type_datum *>(hashtab_search(db->p_types.table, type));
+        if (is_attr && out->d->flavor != TYPE_ATTRIB) {
+            std::cerr << "\"" << type << "\" MUST be an attribute in the policy" << std::endl;
+            free(out);
+            return NULL;
+        } else if (!is_attr && out->d->flavor !=TYPE_TYPE) {
+            std::cerr << "\"" << type << "\" MUST be a type in the policy" << std::endl;
+            free(out);
+            return NULL;
+        }
+
+        if (is_attr) {
+            out->bit = ebitmap_start(&db->attr_type_map[out->d->s.value - 1], &out->n);
+            out->length = ebitmap_length(&db->attr_type_map[out->d->s.value - 1]);
+        } else {
+            out->bit = ebitmap_start(&db->type_attr_map[out->d->s.value - 1], &out->n);
+            out->length = ebitmap_length(&db->type_attr_map[out->d->s.value - 1]);
+        }
     }
 
     return static_cast<void *>(out);
@@ -65,7 +78,7 @@
 }
 
 /*
- * print allow rule into *out buffer.
+ * print type into *out buffer.
  *
  * Returns -1 on error.
  * Returns 0 on successfully reading an avtab entry.
@@ -77,20 +90,30 @@
     policydb_t *db = static_cast<policydb_t *>(policydbp);
     struct type_iter *i = static_cast<struct type_iter *>(type_iterp);
 
-    for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
-        if (!ebitmap_node_get_bit(i->n, i->bit)) {
-            continue;
+    if (!i->alltypes) {
+        for (; i->bit < i->length; i->bit = ebitmap_next(&i->n, i->bit)) {
+            if (!ebitmap_node_get_bit(i->n, i->bit)) {
+                continue;
+            }
+            break;
         }
-        len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
-        if (len >= max_size) {
-               std::cerr << "type name exceeds buffer size." << std::endl;
-               return -1;
-        }
-        i->bit = ebitmap_next(&i->n, i->bit);
-        return 0;
     }
-
-    return 1;
+    while (i->bit < i->length &&
+           ((i->alltypes == TYPE_ITER_ALLATTRS
+            && db->type_val_to_struct[i->bit]->flavor != TYPE_ATTRIB)
+            || (i->alltypes == TYPE_ITER_ALLTYPES
+            && db->type_val_to_struct[i->bit]->flavor != TYPE_TYPE))) {
+        i->bit++;
+    }
+    if (i->bit >= i->length)
+        return 1;
+    len = snprintf(out, max_size, "%s", db->p_type_val_to_name[i->bit]);
+    if (len >= max_size) {
+        std::cerr << "type name exceeds buffer size." << std::endl;
+        return -1;
+    }
+    i->alltypes ? i->bit++ : i->bit = ebitmap_next(&i->n, i->bit);
+    return 0;
 }
 
 void *load_policy(const char *policy_path)
@@ -158,7 +181,7 @@
 
 /* items needed to iterate over the avtab */
 struct avtab_iter {
-    avtab_t avtab;
+    avtab_t *avtab;
     uint32_t i;
     avtab_ptr_t cur;
 };
@@ -175,9 +198,9 @@
 {
     size_t len;
 
-    for (; avtab_i->i < avtab_i->avtab.nslot; (avtab_i->i)++) {
+    for (; avtab_i->i < avtab_i->avtab->nslot; (avtab_i->i)++) {
         if (avtab_i->cur == NULL) {
-            avtab_i->cur = avtab_i->avtab.htable[avtab_i->i];
+            avtab_i->cur = avtab_i->avtab->htable[avtab_i->i];
         }
         for (; avtab_i->cur; avtab_i->cur = (avtab_i->cur)->next) {
             if (!((avtab_i->cur)->key.specified & AVTAB_ALLOWED)) continue;
@@ -210,6 +233,37 @@
     return get_avtab_allow_rule(out, len, db, avtab_i);
 }
 
+static avtab_iter *init_avtab_common(avtab_t *in)
+{
+    struct avtab_iter *out = (struct avtab_iter *)
+                            calloc(1, sizeof(struct avtab_iter));
+    if (!out) {
+        std::cerr << "Failed to allocate avtab iterator" << std::endl;
+        return NULL;
+    }
+
+    out->avtab = in;
+    return out;
+}
+
+void *init_avtab(void *policydbp)
+{
+    policydb_t *p = static_cast<policydb_t *>(policydbp);
+    return static_cast<void *>(init_avtab_common(&p->te_avtab));
+}
+
+void *init_cond_avtab(void *policydbp)
+{
+    policydb_t *p = static_cast<policydb_t *>(policydbp);
+    return static_cast<void *>(init_avtab_common(&p->te_cond_avtab));
+}
+
+void destroy_avtab(void *avtab_iterp)
+{
+    struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
+    free(avtab_i);
+}
+
 /*
  * <sepol/policydb/expand.h->conditional.h> uses 'bool' as a variable name
  * inside extern "C" { .. } construct, which clang doesn't like.
@@ -217,45 +271,57 @@
  */
 extern "C" int expand_avtab(policydb_t *p, avtab_t *a, avtab_t *expa);
 
-static avtab_iter *init_avtab_common(avtab_t *in, policydb_t *p)
+static avtab_iter *init_expanded_avtab_common(avtab_t *in, policydb_t *p)
 {
     struct avtab_iter *out = (struct avtab_iter *)
                             calloc(1, sizeof(struct avtab_iter));
     if (!out) {
-        std::cerr << "Failed to allocate avtab" << std::endl;
+        std::cerr << "Failed to allocate avtab iterator" << std::endl;
         return NULL;
     }
 
-    if (avtab_init(&out->avtab)) {
-        std::cerr << "Failed to initialize avtab" << std::endl;
+    avtab_t *avtab = (avtab_t *) calloc(1, sizeof(avtab_t));
+
+    if (!avtab) {
+        std::cerr << "Failed to allocate avtab" << std::endl;
         free(out);
         return NULL;
     }
 
-    if (expand_avtab(p, in, &out->avtab)) {
+    out->avtab = avtab;
+    if (avtab_init(out->avtab)) {
+        std::cerr << "Failed to initialize avtab" << std::endl;
+        free(avtab);
+        free(out);
+        return NULL;
+    }
+
+    if (expand_avtab(p, in, out->avtab)) {
         std::cerr << "Failed to expand avtab" << std::endl;
+        free(avtab);
         free(out);
         return NULL;
     }
     return out;
 }
 
-void *init_avtab(void *policydbp)
+void *init_expanded_avtab(void *policydbp)
 {
     policydb_t *p = static_cast<policydb_t *>(policydbp);
-    return static_cast<void *>(init_avtab_common(&p->te_avtab, p));
+    return static_cast<void *>(init_expanded_avtab_common(&p->te_avtab, p));
 }
 
-void *init_cond_avtab(void *policydbp)
+void *init_expanded_cond_avtab(void *policydbp)
 {
     policydb_t *p = static_cast<policydb_t *>(policydbp);
-    return static_cast<void *>(init_avtab_common(&p->te_cond_avtab, p));
+    return static_cast<void *>(init_expanded_avtab_common(&p->te_cond_avtab, p));
 }
 
-void destroy_avtab(void *avtab_iterp)
+void destroy_expanded_avtab(void *avtab_iterp)
 {
     struct avtab_iter *avtab_i = static_cast<struct avtab_iter *>(avtab_iterp);
-    avtab_destroy(&avtab_i->avtab);
+    avtab_destroy(avtab_i->avtab);
+    free(avtab_i->avtab);
     free(avtab_i);
 }