Exemple #1
0
/**
 * verify_dfa - verify that all the transitions and states in the dfa tables
 *              are in bounds.
 * @dfa: dfa to test
 *
 * assumes dfa has gone through the verification done by unpacking
 */
int verify_dfa(struct aa_dfa *dfa)
{
	size_t i, state_count, trans_count;
	int error = -EPROTO;

	/* check that required tables exist */
	if (!(dfa->tables[YYTD_ID_ACCEPT -1 ] &&
	      dfa->tables[YYTD_ID_DEF - 1] &&
	      dfa->tables[YYTD_ID_BASE - 1] &&
	      dfa->tables[YYTD_ID_NXT - 1] &&
	      dfa->tables[YYTD_ID_CHK - 1]))
		goto out;

	/* accept.size == default.size == base.size */
	state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen;
	if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen &&
	      state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen))
		goto out;

	/* next.size == chk.size */
	trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen;
	if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
		goto out;

	/* if equivalence classes then its table size must be 256 */
	if (dfa->tables[YYTD_ID_EC - 1] &&
	    dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
		goto out;

	for (i = 0; i < state_count; i++) {
		if (DEFAULT_TABLE(dfa)[i] >= state_count)
			goto out;
		if (BASE_TABLE(dfa)[i] >= trans_count + 256)
			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;
	}

	/* verify accept permissions */
	for (i = 0; i < state_count; i++) {
		int mode = ACCEPT_TABLE(dfa)[i];

		if (mode & ~AA_VALID_PERM_MASK) {
			goto out;
		}
	}

	error = 0;
out:
	return error;
}
Exemple #2
0
/**
 * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed
 * @dfa: the dfa to match @str against  (NOT NULL)
 * @start: the state of the dfa to start matching in
 * @str: the string of bytes to match against the dfa  (NOT NULL)
 * @n: length of the string of bytes to match
 * @retpos: first character in str after match OR str + n
 *
 * aa_dfa_match_len will match @str against the dfa and return the state it
 * finished matching in. The final state can be used to look up the accepting
 * label, or as the start state of a continuing match.
 *
 * This function will happily match again the 0 byte and only finishes
 * when @n input is consumed.
 *
 * Returns: final state reached after input is consumed
 */
unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
				 const char *str, int n, const char **retpos)
{
	u16 *def = DEFAULT_TABLE(dfa);
	u32 *base = BASE_TABLE(dfa);
	u16 *next = NEXT_TABLE(dfa);
	u16 *check = CHECK_TABLE(dfa);
	u32 *accept = ACCEPT_TABLE(dfa);
	unsigned int state = start, pos;

	*retpos = NULL;
	if (state == 0)
		return 0;

	/* 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;
		}
	}

	*retpos = str;
	return state;
}
Exemple #3
0
/**
 * aa_dfa_match - find accept perm for @str in @dfa
 * @dfa: the dfa to match @str against
 * @str: the string to match against the dfa
 *
 * aa_dfa_match will match @str and return the accept perms for the
 * final state.
 */
unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str)
{
	return ACCEPT_TABLE(dfa)[aa_dfa_next_state(dfa, DFA_START, str)];
}