Loading security/apparmor/match.c +68 −48 Original line number Diff line number Diff line Loading @@ -136,8 +136,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize) } /** * verify_dfa - verify that transitions and states in the tables are in bounds. * @dfa: dfa to test (NOT NULL) * verify_table_headers - verify that the tables headers are as expected * @tables - array of dfa tables to check (NOT NULL) * @flags: flags controlling what type of accept table are acceptable * * Assumes dfa has gone through the first pass verification done by unpacking Loading @@ -145,52 +145,69 @@ static struct table_header *unpack_table(char *blob, size_t bsize) * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa, int flags) static int verify_table_headers(struct table_header **tables, int flags) { size_t i, state_count, trans_count; size_t state_count, trans_count; int error = -EPROTO; /* check that required tables exist */ if (!(dfa->tables[YYTD_ID_DEF] && dfa->tables[YYTD_ID_BASE] && dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) if (!(tables[YYTD_ID_DEF] && tables[YYTD_ID_BASE] && tables[YYTD_ID_NXT] && tables[YYTD_ID_CHK])) goto out; /* accept.size == default.size == base.size */ state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; state_count = tables[YYTD_ID_BASE]->td_lolen; if (ACCEPT1_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT]) if (!tables[YYTD_ID_ACCEPT]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) if (state_count != tables[YYTD_ID_ACCEPT]->td_lolen) goto out; } if (ACCEPT2_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT2]) if (!tables[YYTD_ID_ACCEPT2]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) if (state_count != tables[YYTD_ID_ACCEPT2]->td_lolen) goto out; } if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) if (state_count != tables[YYTD_ID_DEF]->td_lolen) goto out; /* next.size == chk.size */ trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) trans_count = tables[YYTD_ID_NXT]->td_lolen; if (trans_count != tables[YYTD_ID_CHK]->td_lolen) goto out; /* if equivalence classes then its table size must be 256 */ if (dfa->tables[YYTD_ID_EC] && dfa->tables[YYTD_ID_EC]->td_lolen != 256) if (tables[YYTD_ID_EC] && tables[YYTD_ID_EC]->td_lolen != 256) goto out; if (flags & DFA_FLAG_VERIFY_STATES) { error = 0; out: return error; } /** * verify_dfa - verify that transitions and states in the tables are in bounds. * @dfa: dfa to test (NOT NULL) * * Assumes dfa has gone through the first pass verification done by unpacking * NOTE: this does not valid accept table values * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa) { size_t i, state_count, trans_count; int error = EPROTO; state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; for (i = 0; i < state_count; i++) { if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && (DEFAULT_TABLE(dfa)[i] >= state_count)) goto out; if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { printk(KERN_ERR "AppArmor DFA next/check upper " "bounds error\n"); pr_err("AppArmor DFA next/check upper bounds error\n"); goto out; } } Loading @@ -201,13 +218,11 @@ static int verify_dfa(struct aa_dfa *dfa, int flags) if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } } /* Now that all the other tables are verified, verify diffencoding */ if (flags & DFA_FLAG_VERIFY_STATES) { for (i = 0; i < state_count; i++) { size_t j, k; for (i = 0; i < state_count; i++) { for (j = i; (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE); Loading @@ -220,8 +235,8 @@ static int verify_dfa(struct aa_dfa *dfa, int flags) BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE; } } } error = 0; out: return error; } Loading Loading @@ -338,10 +353,15 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) size -= table_size(table->td_lolen, table->td_flags); table = NULL; } error = verify_table_headers(dfa->tables, flags); if (error) goto fail; error = verify_dfa(dfa, flags); if (flags & DFA_FLAG_VERIFY_STATES) { error = verify_dfa(dfa); if (error) goto fail; } return dfa; Loading Loading
security/apparmor/match.c +68 −48 Original line number Diff line number Diff line Loading @@ -136,8 +136,8 @@ static struct table_header *unpack_table(char *blob, size_t bsize) } /** * verify_dfa - verify that transitions and states in the tables are in bounds. * @dfa: dfa to test (NOT NULL) * verify_table_headers - verify that the tables headers are as expected * @tables - array of dfa tables to check (NOT NULL) * @flags: flags controlling what type of accept table are acceptable * * Assumes dfa has gone through the first pass verification done by unpacking Loading @@ -145,52 +145,69 @@ static struct table_header *unpack_table(char *blob, size_t bsize) * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa, int flags) static int verify_table_headers(struct table_header **tables, int flags) { size_t i, state_count, trans_count; size_t state_count, trans_count; int error = -EPROTO; /* check that required tables exist */ if (!(dfa->tables[YYTD_ID_DEF] && dfa->tables[YYTD_ID_BASE] && dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) if (!(tables[YYTD_ID_DEF] && tables[YYTD_ID_BASE] && tables[YYTD_ID_NXT] && tables[YYTD_ID_CHK])) goto out; /* accept.size == default.size == base.size */ state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; state_count = tables[YYTD_ID_BASE]->td_lolen; if (ACCEPT1_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT]) if (!tables[YYTD_ID_ACCEPT]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) if (state_count != tables[YYTD_ID_ACCEPT]->td_lolen) goto out; } if (ACCEPT2_FLAGS(flags)) { if (!dfa->tables[YYTD_ID_ACCEPT2]) if (!tables[YYTD_ID_ACCEPT2]) goto out; if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) if (state_count != tables[YYTD_ID_ACCEPT2]->td_lolen) goto out; } if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) if (state_count != tables[YYTD_ID_DEF]->td_lolen) goto out; /* next.size == chk.size */ trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) trans_count = tables[YYTD_ID_NXT]->td_lolen; if (trans_count != tables[YYTD_ID_CHK]->td_lolen) goto out; /* if equivalence classes then its table size must be 256 */ if (dfa->tables[YYTD_ID_EC] && dfa->tables[YYTD_ID_EC]->td_lolen != 256) if (tables[YYTD_ID_EC] && tables[YYTD_ID_EC]->td_lolen != 256) goto out; if (flags & DFA_FLAG_VERIFY_STATES) { error = 0; out: return error; } /** * verify_dfa - verify that transitions and states in the tables are in bounds. * @dfa: dfa to test (NOT NULL) * * Assumes dfa has gone through the first pass verification done by unpacking * NOTE: this does not valid accept table values * * Returns: %0 else error code on failure to verify */ static int verify_dfa(struct aa_dfa *dfa) { size_t i, state_count, trans_count; int error = EPROTO; state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; for (i = 0; i < state_count; i++) { if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && (DEFAULT_TABLE(dfa)[i] >= state_count)) goto out; if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { printk(KERN_ERR "AppArmor DFA next/check upper " "bounds error\n"); pr_err("AppArmor DFA next/check upper bounds error\n"); goto out; } } Loading @@ -201,13 +218,11 @@ static int verify_dfa(struct aa_dfa *dfa, int flags) if (CHECK_TABLE(dfa)[i] >= state_count) goto out; } } /* Now that all the other tables are verified, verify diffencoding */ if (flags & DFA_FLAG_VERIFY_STATES) { for (i = 0; i < state_count; i++) { size_t j, k; for (i = 0; i < state_count; i++) { for (j = i; (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE); Loading @@ -220,8 +235,8 @@ static int verify_dfa(struct aa_dfa *dfa, int flags) BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE; } } } error = 0; out: return error; } Loading Loading @@ -338,10 +353,15 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) size -= table_size(table->td_lolen, table->td_flags); table = NULL; } error = verify_table_headers(dfa->tables, flags); if (error) goto fail; error = verify_dfa(dfa, flags); if (flags & DFA_FLAG_VERIFY_STATES) { error = verify_dfa(dfa); if (error) goto fail; } return dfa; Loading