/* if we have a table it must have some entries */ if (th.td_lolen == 0) goto out;
tsize = table_size(th.td_lolen, th.td_flags); if (bsize < tsize) goto out;
table = kvzalloc(tsize, GFP_KERNEL); if (table) {
table->td_id = th.td_id;
table->td_flags = th.td_flags;
table->td_lolen = th.td_lolen; if (th.td_flags == YYTD_DATA8)
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
u8, u8, byte_to_byte); elseif (th.td_flags == YYTD_DATA16)
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
u16, __be16, be16_to_cpu); elseif (th.td_flags == YYTD_DATA32)
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
u32, __be32, be32_to_cpu); else goto fail; /* if table was vmalloced make sure the page tables are synced *beforeitisused,asitgoeslivetoallcpus.
*/ if (is_vmalloc_addr(table))
vm_unmap_aliases();
}
state_count = dfa->tables[YYTD_ID_BASE]->td_lolen;
trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; if (state_count == 0) goto out; 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_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) {
pr_err("AppArmor DFA state with invalid match flags"); goto out;
} if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE)) { if (!(dfa->flags & YYTH_FLAG_DIFF_ENCODE)) {
pr_err("AppArmor DFA diff encoded transition state without header flag"); goto out;
}
} if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_OOB_TRANSITION)) { if (base_idx(BASE_TABLE(dfa)[i]) < dfa->max_oob) {
pr_err("AppArmor DFA out of bad transition out of range"); goto out;
} if (!(dfa->flags & YYTH_FLAG_OOB_TRANS)) {
pr_err("AppArmor DFA out of bad transition state without header flag"); goto out;
}
} if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
pr_err("AppArmor DFA next/check upper bounds error\n"); goto out;
}
}
for (i = 0; i < trans_count; i++) { if (NEXT_TABLE(dfa)[i] >= state_count) goto out; if (CHECK_TABLE(dfa)[i] >= state_count) goto out;
}
/* Now that all the other tables are verified, verify diffencoding */ for (i = 0; i < state_count; i++) {
size_t j, k;
/* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */
u8 *equiv = EQUIV_TABLE(dfa); for (; len; len--)
match_char(state, def, base, next, check,
equiv[(u8) *str++]);
} else { /* default is direct to next state */ for (; len; len--)
match_char(state, def, base, next, check, (u8) *str++);
}
/* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */
u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str)
match_char(state, def, base, next, check,
equiv[(u8) *str++]);
} else { /* default is direct to next state */ while (*str)
match_char(state, def, base, next, check, (u8) *str++);
}
/* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */
u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) {
pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (accept[state]) break;
}
} else { /* default is direct to next state */ while (*str) {
pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (accept[state]) break;
}
}
*retpos = NULL; if (state == DFA_NOMATCH) return DFA_NOMATCH;
/* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */
u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ for (; n; n--) {
pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (accept[state]) break;
}
} else { /* default is direct to next state */ for (; n; n--) {
pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (accept[state]) break;
}
}
/* For DFAs that don't support extended tagging of states */ /* adjust is only set if is_loop returns true */ staticbool is_loop(struct match_workbuf *wb, aa_state_t state, unsignedint *adjust)
{ int pos = wb->pos; int i;
if (wb->history[pos] < state) returnfalse;
for (i = 0; i < wb->len; i++) { if (wb->history[pos] == state) {
*adjust = i; returntrue;
} /* -1 wraps to WB_HISTORY_SIZE - 1 */
pos = (pos - 1) & (WB_HISTORY_SIZE - 1);
}
*count = 0; if (state == DFA_NOMATCH) return DFA_NOMATCH;
/* current state is <state>, matching character *str */ if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */
u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ while (*str) { unsignedint adjust;
wb->history[wb->pos] = state;
pos = base_idx(base[state]) + equiv[(u8) *str++]; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (is_loop(wb, state, &adjust)) {
state = aa_dfa_match(dfa, state, str);
*count -= adjust; goto out;
}
inc_wb_pos(wb);
(*count)++;
}
} else { /* default is direct to next state */ while (*str) { unsignedint adjust;
wb->history[wb->pos] = state;
pos = base_idx(base[state]) + (u8) *str++; if (check[pos] == state)
state = next[pos]; else
state = def[state]; if (is_loop(wb, state, &adjust)) {
state = aa_dfa_match(dfa, state, str);
*count -= adjust; goto out;
}
inc_wb_pos(wb);
(*count)++;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.