*
  * Returns: remapped perm table
  */
-static struct aa_perms *compute_fperms(struct aa_dfa *dfa)
+static struct aa_perms *compute_fperms(struct aa_dfa *dfa,
+                                      u32 *size)
 {
        aa_state_t state;
        unsigned int state_count;
        table = kvcalloc(state_count * 2, sizeof(struct aa_perms), GFP_KERNEL);
        if (!table)
                return NULL;
+       *size = state_count * 2;
 
        /* zero init so skip the trap state (state == 0) */
        for (state = 1; state < state_count; state++) {
        return table;
 }
 
-static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch)
+static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch,
+                                     u32 *size)
 {
        struct aa_perms *perms;
        int state;
        perms = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL);
        if (!perms)
                return NULL;
+       *size = state_count;
 
        /* zero init so skip the trap state (state == 0) */
        for (state = 1; state < state_count; state++)
        return perms;
 }
 
-static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version)
+static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version,
+                                     u32 *size)
 {
        unsigned int state;
        unsigned int state_count;
        table = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL);
        if (!table)
                return NULL;
+       *size = state_count;
 
        /* zero init so skip the trap state (state == 0) */
        for (state = 1; state < state_count; state++)
 /* TODO: merge different dfa mappings into single map_policy fn */
 int aa_compat_map_xmatch(struct aa_policydb *policy)
 {
-       policy->perms = compute_xmatch_perms(policy->dfa);
+       policy->perms = compute_xmatch_perms(policy->dfa, &policy->size);
        if (!policy->perms)
                return -ENOMEM;
 
 
 int aa_compat_map_policy(struct aa_policydb *policy, u32 version)
 {
-       policy->perms = compute_perms(policy->dfa, version);
+       policy->perms = compute_perms(policy->dfa, version, &policy->size);
        if (!policy->perms)
                return -ENOMEM;
 
 
 int aa_compat_map_file(struct aa_policydb *policy)
 {
-       policy->perms = compute_fperms(policy->dfa);
+       policy->perms = compute_fperms(policy->dfa, &policy->size);
        if (!policy->perms)
                return -ENOMEM;
 
 
        return 0;
 }
 
-static bool verify_xindex(int xindex, int table_size)
-{
-       int index, xtype;
-       xtype = xindex & AA_X_TYPE_MASK;
-       index = xindex & AA_X_INDEX_MASK;
-       if (xtype == AA_X_TABLE && index >= table_size)
-               return false;
-       return true;
-}
-
-/* verify dfa xindexes are in range of transition tables */
-static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
+/**
+ * verify_dfa_accept_xindex - verify accept indexes are in range of perms table
+ * @dfa: the dfa to check accept indexes are in range
+ * table_size: the permission table size the indexes should be within
+ */
+static bool verify_dfa_accept_index(struct aa_dfa *dfa, int table_size)
 {
        int i;
        for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
-               if (!verify_xindex(ACCEPT_TABLE(dfa)[i], table_size))
+               if (ACCEPT_TABLE(dfa)[i] >= table_size)
                        return false;
        }
        return true;
                if (!verify_perm(&pdb->perms[i]))
                        return false;
                /* verify indexes into str table */
-               if (pdb->perms[i].xindex >= pdb->trans.size)
+               if ((pdb->perms[i].xindex & AA_X_TYPE_MASK) == AA_X_TABLE &&
+                   (pdb->perms[i].xindex & AA_X_INDEX_MASK) >= pdb->trans.size)
                        return false;
-               if (pdb->perms[i].tag >= pdb->trans.size)
+               if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size)
                        return false;
-               if (pdb->perms[i].label >= pdb->trans.size)
+               if (pdb->perms[i].label &&
+                   pdb->perms[i].label >= pdb->trans.size)
                        return false;
        }
 
        if (!rules)
                return 0;
 
-       if ((rules->file.dfa && !verify_dfa_xindex(rules->file.dfa,
-                                                 rules->file.trans.size)) ||
+       if ((rules->file.dfa && !verify_dfa_accept_index(rules->file.dfa,
+                                                        rules->file.size)) ||
            (rules->policy.dfa &&
-            !verify_dfa_xindex(rules->policy.dfa, rules->policy.trans.size))) {
+            !verify_dfa_accept_index(rules->policy.dfa, rules->policy.size))) {
                audit_iface(profile, NULL, NULL,
                            "Unpack: Invalid named transition", NULL, -EPROTO);
                return -EPROTO;