xref: /linux/security/apparmor/match.c (revision c715f13bb30f9f4d1bd8888667ef32e43b6fedc1)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AppArmor security module
4  *
5  * This file contains AppArmor dfa based regular expression matching engine
6  *
7  * Copyright (C) 1998-2008 Novell/SUSE
8  * Copyright 2009-2012 Canonical Ltd.
9  */
10 
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/mm.h>
14 #include <linux/slab.h>
15 #include <linux/vmalloc.h>
16 #include <linux/err.h>
17 #include <linux/kref.h>
18 #include <linux/unaligned.h>
19 
20 #include "include/lib.h"
21 #include "include/match.h"
22 
23 #define base_idx(X) ((X) & 0xffffff)
24 
25 /**
26  * unpack_table - unpack a dfa table (one of accept, default, base, next check)
27  * @blob: data to unpack (NOT NULL)
28  * @bsize: size of blob
29  *
30  * Returns: pointer to table else NULL on failure
31  *
32  * NOTE: must be freed by kvfree (not kfree)
33  */
34 static struct table_header *unpack_table(char *blob, size_t bsize)
35 {
36 	struct table_header *table = NULL;
37 	struct table_header th;
38 	size_t tsize;
39 
40 	if (bsize < sizeof(struct table_header))
41 		goto out;
42 
43 	/* loaded td_id's start at 1, subtract 1 now to avoid doing
44 	 * it every time we use td_id as an index
45 	 */
46 	th.td_id = get_unaligned_be16(blob) - 1;
47 	if (th.td_id > YYTD_ID_MAX)
48 		goto out;
49 	th.td_flags = get_unaligned_be16(blob + 2);
50 	th.td_lolen = get_unaligned_be32(blob + 8);
51 	blob += sizeof(struct table_header);
52 
53 	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
54 	      th.td_flags == YYTD_DATA8))
55 		goto out;
56 
57 	/* if we have a table it must have some entries */
58 	if (th.td_lolen == 0)
59 		goto out;
60 	tsize = table_size(th.td_lolen, th.td_flags);
61 	if (bsize < tsize)
62 		goto out;
63 
64 	table = kvzalloc(tsize, GFP_KERNEL);
65 	if (table) {
66 		table->td_id = th.td_id;
67 		table->td_flags = th.td_flags;
68 		table->td_lolen = th.td_lolen;
69 		if (th.td_flags == YYTD_DATA8)
70 			memcpy(table->td_data, blob, th.td_lolen);
71 		else if (th.td_flags == YYTD_DATA16)
72 			UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
73 				     u16, __be16, get_unaligned_be16);
74 		else if (th.td_flags == YYTD_DATA32)
75 			UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
76 				     u32, __be32, get_unaligned_be32);
77 		else
78 			goto fail;
79 		/* if table was vmalloced make sure the page tables are synced
80 		 * before it is used, as it goes live to all cpus.
81 		 */
82 		if (is_vmalloc_addr(table))
83 			vm_unmap_aliases();
84 	}
85 
86 out:
87 	return table;
88 fail:
89 	kvfree(table);
90 	return NULL;
91 }
92 
93 /**
94  * verify_table_headers - verify that the tables headers are as expected
95  * @tables: array of dfa tables to check (NOT NULL)
96  * @flags: flags controlling what type of accept table are acceptable
97  *
98  * Assumes dfa has gone through the first pass verification done by unpacking
99  * NOTE: this does not valid accept table values
100  *
101  * Returns: %0 else error code on failure to verify
102  */
103 static int verify_table_headers(struct table_header **tables, int flags)
104 {
105 	size_t state_count, trans_count;
106 	int error = -EPROTO;
107 
108 	/* check that required tables exist */
109 	if (!(tables[YYTD_ID_DEF] && tables[YYTD_ID_BASE] &&
110 	      tables[YYTD_ID_NXT] && tables[YYTD_ID_CHK]))
111 		goto out;
112 
113 	/* accept.size == default.size == base.size */
114 	state_count = tables[YYTD_ID_BASE]->td_lolen;
115 	if (ACCEPT1_FLAGS(flags)) {
116 		if (!tables[YYTD_ID_ACCEPT])
117 			goto out;
118 		if (state_count != tables[YYTD_ID_ACCEPT]->td_lolen)
119 			goto out;
120 	}
121 	if (ACCEPT2_FLAGS(flags)) {
122 		if (!tables[YYTD_ID_ACCEPT2])
123 			goto out;
124 		if (state_count != tables[YYTD_ID_ACCEPT2]->td_lolen)
125 			goto out;
126 	}
127 	if (state_count != tables[YYTD_ID_DEF]->td_lolen)
128 		goto out;
129 
130 	/* next.size == chk.size */
131 	trans_count = tables[YYTD_ID_NXT]->td_lolen;
132 	if (trans_count != tables[YYTD_ID_CHK]->td_lolen)
133 		goto out;
134 
135 	/* if equivalence classes then its table size must be 256 */
136 	if (tables[YYTD_ID_EC] && tables[YYTD_ID_EC]->td_lolen != 256)
137 		goto out;
138 
139 	error = 0;
140 out:
141 	return error;
142 }
143 
144 /**
145  * verify_dfa - verify that transitions and states in the tables are in bounds.
146  * @dfa: dfa to test  (NOT NULL)
147  *
148  * Assumes dfa has gone through the first pass verification done by unpacking
149  * NOTE: this does not valid accept table values
150  *
151  * Returns: %0 else error code on failure to verify
152  */
153 static int verify_dfa(struct aa_dfa *dfa)
154 {
155 	size_t i, state_count, trans_count;
156 	int error = -EPROTO;
157 
158 	state_count = dfa->tables[YYTD_ID_BASE]->td_lolen;
159 	trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen;
160 	if (state_count == 0)
161 		goto out;
162 	for (i = 0; i < state_count; i++) {
163 		if (DEFAULT_TABLE(dfa)[i] >= state_count) {
164 			pr_err("AppArmor DFA default state out of bounds");
165 			goto out;
166 		}
167 		if (BASE_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) {
168 			pr_err("AppArmor DFA state with invalid match flags");
169 			goto out;
170 		}
171 		if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE)) {
172 			if (!(dfa->flags & YYTH_FLAG_DIFF_ENCODE)) {
173 				pr_err("AppArmor DFA diff encoded transition state without header flag");
174 				goto out;
175 			}
176 		}
177 		if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_OOB_TRANSITION)) {
178 			if (base_idx(BASE_TABLE(dfa)[i]) < dfa->max_oob) {
179 				pr_err("AppArmor DFA out of bad transition out of range");
180 				goto out;
181 			}
182 			if (!(dfa->flags & YYTH_FLAG_OOB_TRANS)) {
183 				pr_err("AppArmor DFA out of bad transition state without header flag");
184 				goto out;
185 			}
186 		}
187 		if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
188 			pr_err("AppArmor DFA next/check upper bounds error\n");
189 			goto out;
190 		}
191 	}
192 
193 	for (i = 0; i < trans_count; i++) {
194 		if (NEXT_TABLE(dfa)[i] >= state_count)
195 			goto out;
196 		if (CHECK_TABLE(dfa)[i] >= state_count)
197 			goto out;
198 	}
199 
200 	/* Now that all the other tables are verified, verify diffencoding */
201 	for (i = 0; i < state_count; i++) {
202 		size_t j, k;
203 
204 		for (j = i;
205 		     ((BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) &&
206 		      !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE_VERIFIED));
207 		     j = k) {
208 			if (BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE)
209 				/* loop in current chain */
210 				goto out;
211 			k = DEFAULT_TABLE(dfa)[j];
212 			if (j == k)
213 				/* self loop */
214 				goto out;
215 			BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE;
216 		}
217 		/* move mark to verified */
218 		for (j = i;
219 		     (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE);
220 		     j = k) {
221 			k = DEFAULT_TABLE(dfa)[j];
222 			if (j < i)
223 				/* jumps to state/chain that has been
224 				 * verified
225 				 */
226 				break;
227 			BASE_TABLE(dfa)[j] &= ~MARK_DIFF_ENCODE;
228 			BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE_VERIFIED;
229 		}
230 	}
231 	error = 0;
232 
233 out:
234 	return error;
235 }
236 
237 /**
238  * dfa_free - free a dfa allocated by aa_dfa_unpack
239  * @dfa: the dfa to free  (MAYBE NULL)
240  *
241  * Requires: reference count to dfa == 0
242  */
243 static void dfa_free(struct aa_dfa *dfa)
244 {
245 	if (dfa) {
246 		int i;
247 
248 		for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
249 			kvfree(dfa->tables[i]);
250 			dfa->tables[i] = NULL;
251 		}
252 		kfree(dfa);
253 	}
254 }
255 
256 /**
257  * aa_dfa_free_kref - free aa_dfa by kref (called by aa_put_dfa)
258  * @kref: kref callback for freeing of a dfa  (NOT NULL)
259  */
260 void aa_dfa_free_kref(struct kref *kref)
261 {
262 	struct aa_dfa *dfa = container_of(kref, struct aa_dfa, count);
263 	dfa_free(dfa);
264 }
265 
266 
267 
268 /**
269  * remap_data16_to_data32 - remap u16 @old table to a u32 based table
270  * @old: table to remap
271  *
272  * Returns: new table with u32 entries instead of u16.
273  *
274  * Note: will free @old so caller does not have to
275  */
276 static struct table_header *remap_data16_to_data32(struct table_header *old)
277 {
278 	struct table_header *new;
279 	size_t tsize;
280 	u32 i;
281 
282 	tsize = table_size(old->td_lolen, YYTD_DATA32);
283 	new = kvzalloc(tsize, GFP_KERNEL);
284 	if (!new) {
285 		kvfree(old);
286 		return NULL;
287 	}
288 	new->td_id = old->td_id;
289 	new->td_flags = YYTD_DATA32;
290 	new->td_lolen = old->td_lolen;
291 
292 	for (i = 0; i < old->td_lolen; i++)
293 		TABLE_DATAU32(new)[i] = (u32) TABLE_DATAU16(old)[i];
294 
295 	kvfree(old);
296 	if (is_vmalloc_addr(new))
297 		vm_unmap_aliases();
298 
299 	return new;
300 }
301 
302 /**
303  * aa_dfa_unpack - unpack the binary tables of a serialized dfa
304  * @blob: aligned serialized stream of data to unpack  (NOT NULL)
305  * @size: size of data to unpack
306  * @flags: flags controlling what type of accept tables are acceptable
307  *
308  * Unpack a dfa that has been serialized.  To find information on the dfa
309  * format look in Documentation/admin-guide/LSM/apparmor.rst
310  * Assumes the dfa @blob stream has been aligned on a 8 byte boundary
311  *
312  * Returns: an unpacked dfa ready for matching or ERR_PTR on failure
313  */
314 struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
315 {
316 	int hsize;
317 	int error = -ENOMEM;
318 	char *data = blob;
319 	struct table_header *table = NULL;
320 	struct aa_dfa *dfa = kzalloc_obj(struct aa_dfa);
321 	if (!dfa)
322 		goto fail;
323 
324 	kref_init(&dfa->count);
325 
326 	error = -EPROTO;
327 
328 	/* get dfa table set header */
329 	if (size < sizeof(struct table_set_header))
330 		goto fail;
331 
332 	if (get_unaligned_be32(data) != YYTH_MAGIC)
333 		goto fail;
334 
335 	hsize = get_unaligned_be32(data + 4);
336 	if (size < hsize)
337 		goto fail;
338 
339 	dfa->flags = get_unaligned_be16(data + 12);
340 	if (dfa->flags & ~(YYTH_FLAGS))
341 		goto fail;
342 
343 	/*
344 	 * TODO: needed for dfa to support more than 1 oob
345 	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
346 	 *	if (hsize < 16 + 4)
347 	 *		goto fail;
348 	 *	dfa->max_oob = get_unaligned_be32(data + 16);
349 	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
350 	 *		pr_err("AppArmor DFA OOB greater than supported\n");
351 	 *		goto fail;
352 	 *	}
353 	 * }
354 	 */
355 	dfa->max_oob = 1;
356 
357 	data += hsize;
358 	size -= hsize;
359 
360 	while (size > 0) {
361 		table = unpack_table(data, size);
362 		if (!table)
363 			goto fail;
364 
365 		switch (table->td_id) {
366 		case YYTD_ID_ACCEPT:
367 			if (!(table->td_flags & ACCEPT1_FLAGS(flags)))
368 				goto fail;
369 			break;
370 		case YYTD_ID_ACCEPT2:
371 			if (!(table->td_flags & ACCEPT2_FLAGS(flags)))
372 				goto fail;
373 			break;
374 		case YYTD_ID_BASE:
375 			if (table->td_flags != YYTD_DATA32)
376 				goto fail;
377 			break;
378 		case YYTD_ID_DEF:
379 		case YYTD_ID_NXT:
380 		case YYTD_ID_CHK:
381 			if (!(table->td_flags == YYTD_DATA16 ||
382 			      table->td_flags == YYTD_DATA32)) {
383 				goto fail;
384 			}
385 			break;
386 		case YYTD_ID_EC:
387 			if (table->td_flags != YYTD_DATA8)
388 				goto fail;
389 			break;
390 		default:
391 			goto fail;
392 		}
393 		/* check for duplicate table entry */
394 		if (dfa->tables[table->td_id])
395 			goto fail;
396 		dfa->tables[table->td_id] = table;
397 		data += table_size(table->td_lolen, table->td_flags);
398 		size -= table_size(table->td_lolen, table->td_flags);
399 
400 		/*
401 		 * this remapping has to be done after incrementing data above
402 		 * for now straight remap, later have dfa support both
403 		 */
404 		switch (table->td_id) {
405 		case YYTD_ID_DEF:
406 		case YYTD_ID_NXT:
407 		case YYTD_ID_CHK:
408 			if (table->td_flags == YYTD_DATA16) {
409 				table = remap_data16_to_data32(table);
410 				if (!table)
411 					goto fail;
412 			}
413 			dfa->tables[table->td_id] = table;
414 			break;
415 		}
416 		table = NULL;
417 	}
418 	error = verify_table_headers(dfa->tables, flags);
419 	if (error)
420 		goto fail;
421 
422 	if (flags & DFA_FLAG_VERIFY_STATES) {
423 		error = verify_dfa(dfa);
424 		if (error)
425 			goto fail;
426 	}
427 
428 	return dfa;
429 
430 fail:
431 	kvfree(table);
432 	dfa_free(dfa);
433 	return ERR_PTR(error);
434 }
435 
436 #define match_char(state, def, base, next, check, C)	\
437 do {							\
438 	u32 b = (base)[(state)];			\
439 	unsigned int pos = base_idx(b) + (C);		\
440 	if ((check)[pos] != (state)) {			\
441 		(state) = (def)[(state)];		\
442 		if (b & MATCH_FLAG_DIFF_ENCODE)		\
443 			continue;			\
444 		break;					\
445 	}						\
446 	(state) = (next)[pos];				\
447 	break;						\
448 } while (1)
449 
450 /**
451  * aa_dfa_match_len - traverse @dfa to find state @str stops at
452  * @dfa: the dfa to match @str against  (NOT NULL)
453  * @start: the state of the dfa to start matching in
454  * @str: the string of bytes to match against the dfa  (NOT NULL)
455  * @len: length of the string of bytes to match
456  *
457  * aa_dfa_match_len will match @str against the dfa and return the state it
458  * finished matching in. The final state can be used to look up the accepting
459  * label, or as the start state of a continuing match.
460  *
461  * This function will happily match again the 0 byte and only finishes
462  * when @len input is consumed.
463  *
464  * Returns: final state reached after input is consumed
465  */
466 aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start,
467 			    const char *str, int len)
468 {
469 	u32 *def = DEFAULT_TABLE(dfa);
470 	u32 *base = BASE_TABLE(dfa);
471 	u32 *next = NEXT_TABLE(dfa);
472 	u32 *check = CHECK_TABLE(dfa);
473 	aa_state_t state = start;
474 
475 	if (state == DFA_NOMATCH)
476 		return DFA_NOMATCH;
477 
478 	/* current state is <state>, matching character *str */
479 	if (dfa->tables[YYTD_ID_EC]) {
480 		/* Equivalence class table defined */
481 		u8 *equiv = EQUIV_TABLE(dfa);
482 		for (; len; len--) {
483 			u8 c = equiv[(u8) *str];
484 
485 			match_char(state, def, base, next, check, c);
486 			str++;
487 		}
488 	} else {
489 		/* default is direct to next state */
490 		for (; len; len--) {
491 			match_char(state, def, base, next, check, (u8) *str);
492 			str++;
493 		}
494 	}
495 
496 	return state;
497 }
498 
499 /**
500  * aa_dfa_match - traverse @dfa to find state @str stops at
501  * @dfa: the dfa to match @str against  (NOT NULL)
502  * @start: the state of the dfa to start matching in
503  * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
504  *
505  * aa_dfa_match will match @str against the dfa and return the state it
506  * finished matching in. The final state can be used to look up the accepting
507  * label, or as the start state of a continuing match.
508  *
509  * Returns: final state reached after input is consumed
510  */
511 aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start, const char *str)
512 {
513 	u32 *def = DEFAULT_TABLE(dfa);
514 	u32 *base = BASE_TABLE(dfa);
515 	u32 *next = NEXT_TABLE(dfa);
516 	u32 *check = CHECK_TABLE(dfa);
517 	aa_state_t state = start;
518 
519 	if (state == DFA_NOMATCH)
520 		return DFA_NOMATCH;
521 
522 	/* current state is <state>, matching character *str */
523 	if (dfa->tables[YYTD_ID_EC]) {
524 		/* Equivalence class table defined */
525 		u8 *equiv = EQUIV_TABLE(dfa);
526 		/* default is direct to next state */
527 		while (*str) {
528 			u8 c = equiv[(u8) *str];
529 
530 			match_char(state, def, base, next, check, c);
531 			str++;
532 		}
533 	} else {
534 		/* default is direct to next state */
535 		while (*str) {
536 			match_char(state, def, base, next, check, (u8) *str);
537 			str++;
538 		}
539 	}
540 
541 	return state;
542 }
543 
544 /**
545  * aa_dfa_next - step one character to the next state in the dfa
546  * @dfa: the dfa to traverse (NOT NULL)
547  * @state: the state to start in
548  * @c: the input character to transition on
549  *
550  * aa_dfa_match will step through the dfa by one input character @c
551  *
552  * Returns: state reach after input @c
553  */
554 aa_state_t aa_dfa_next(struct aa_dfa *dfa, aa_state_t state, const char c)
555 {
556 	u32 *def = DEFAULT_TABLE(dfa);
557 	u32 *base = BASE_TABLE(dfa);
558 	u32 *next = NEXT_TABLE(dfa);
559 	u32 *check = CHECK_TABLE(dfa);
560 
561 	/* current state is <state>, matching character *str */
562 	if (dfa->tables[YYTD_ID_EC]) {
563 		/* Equivalence class table defined */
564 		u8 *equiv = EQUIV_TABLE(dfa);
565 		match_char(state, def, base, next, check, equiv[(u8) c]);
566 	} else
567 		match_char(state, def, base, next, check, (u8) c);
568 
569 	return state;
570 }
571 
572 aa_state_t aa_dfa_outofband_transition(struct aa_dfa *dfa, aa_state_t state)
573 {
574 	u32 *def = DEFAULT_TABLE(dfa);
575 	u32 *base = BASE_TABLE(dfa);
576 	u32 *next = NEXT_TABLE(dfa);
577 	u32 *check = CHECK_TABLE(dfa);
578 	u32 b = (base)[(state)];
579 
580 	if (!(b & MATCH_FLAG_OOB_TRANSITION))
581 		return DFA_NOMATCH;
582 
583 	/* No Equivalence class remapping for outofband transitions */
584 	match_char(state, def, base, next, check, -1);
585 
586 	return state;
587 }
588 
589 /**
590  * aa_dfa_match_until - traverse @dfa until accept state or end of input
591  * @dfa: the dfa to match @str against  (NOT NULL)
592  * @start: the state of the dfa to start matching in
593  * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
594  * @retpos: first character in str after match OR end of string
595  *
596  * aa_dfa_match will match @str against the dfa and return the state it
597  * finished matching in. The final state can be used to look up the accepting
598  * label, or as the start state of a continuing match.
599  *
600  * Returns: final state reached after input is consumed
601  */
602 aa_state_t aa_dfa_match_until(struct aa_dfa *dfa, aa_state_t start,
603 				const char *str, const char **retpos)
604 {
605 	u32 *def = DEFAULT_TABLE(dfa);
606 	u32 *base = BASE_TABLE(dfa);
607 	u32 *next = NEXT_TABLE(dfa);
608 	u32 *check = CHECK_TABLE(dfa);
609 	u32 *accept = ACCEPT_TABLE(dfa);
610 	aa_state_t state = start, pos;
611 
612 	if (state == DFA_NOMATCH)
613 		return DFA_NOMATCH;
614 
615 	/* current state is <state>, matching character *str */
616 	if (dfa->tables[YYTD_ID_EC]) {
617 		/* Equivalence class table defined */
618 		u8 *equiv = EQUIV_TABLE(dfa);
619 		/* default is direct to next state */
620 		while (*str) {
621 			pos = base_idx(base[state]) + equiv[(u8) *str++];
622 			if (check[pos] == state)
623 				state = next[pos];
624 			else
625 				state = def[state];
626 			if (accept[state])
627 				break;
628 		}
629 	} else {
630 		/* default is direct to next state */
631 		while (*str) {
632 			pos = base_idx(base[state]) + (u8) *str++;
633 			if (check[pos] == state)
634 				state = next[pos];
635 			else
636 				state = def[state];
637 			if (accept[state])
638 				break;
639 		}
640 	}
641 
642 	*retpos = str;
643 	return state;
644 }
645 
646 /**
647  * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed
648  * @dfa: the dfa to match @str against  (NOT NULL)
649  * @start: the state of the dfa to start matching in
650  * @str: the string of bytes to match against the dfa  (NOT NULL)
651  * @n: length of the string of bytes to match
652  * @retpos: first character in str after match OR str + n
653  *
654  * aa_dfa_match_len will match @str against the dfa and return the state it
655  * finished matching in. The final state can be used to look up the accepting
656  * label, or as the start state of a continuing match.
657  *
658  * This function will happily match again the 0 byte and only finishes
659  * when @n input is consumed.
660  *
661  * Returns: final state reached after input is consumed
662  */
663 aa_state_t aa_dfa_matchn_until(struct aa_dfa *dfa, aa_state_t start,
664 				 const char *str, int n, const char **retpos)
665 {
666 	u32 *def = DEFAULT_TABLE(dfa);
667 	u32 *base = BASE_TABLE(dfa);
668 	u32 *next = NEXT_TABLE(dfa);
669 	u32 *check = CHECK_TABLE(dfa);
670 	u32 *accept = ACCEPT_TABLE(dfa);
671 	aa_state_t state = start, pos;
672 
673 	*retpos = NULL;
674 	if (state == DFA_NOMATCH)
675 		return DFA_NOMATCH;
676 
677 	/* current state is <state>, matching character *str */
678 	if (dfa->tables[YYTD_ID_EC]) {
679 		/* Equivalence class table defined */
680 		u8 *equiv = EQUIV_TABLE(dfa);
681 		/* default is direct to next state */
682 		for (; n; n--) {
683 			pos = base_idx(base[state]) + equiv[(u8) *str++];
684 			if (check[pos] == state)
685 				state = next[pos];
686 			else
687 				state = def[state];
688 			if (accept[state])
689 				break;
690 		}
691 	} else {
692 		/* default is direct to next state */
693 		for (; n; n--) {
694 			pos = base_idx(base[state]) + (u8) *str++;
695 			if (check[pos] == state)
696 				state = next[pos];
697 			else
698 				state = def[state];
699 			if (accept[state])
700 				break;
701 		}
702 	}
703 
704 	*retpos = str;
705 	return state;
706 }
707 
708 #define inc_wb_pos(wb)							\
709 do {									\
710 	BUILD_BUG_ON_NOT_POWER_OF_2(WB_HISTORY_SIZE);			\
711 	wb->pos = (wb->pos + 1) & (WB_HISTORY_SIZE - 1);		\
712 	wb->len = (wb->len + 1) > WB_HISTORY_SIZE ? WB_HISTORY_SIZE :	\
713 				wb->len + 1;				\
714 } while (0)
715 
716 /* For DFAs that don't support extended tagging of states */
717 /* adjust is only set if is_loop returns true */
718 static bool is_loop(struct match_workbuf *wb, aa_state_t state,
719 		    unsigned int *adjust)
720 {
721 	int pos = wb->pos;
722 	int i;
723 
724 	if (wb->history[pos] < state)
725 		return false;
726 
727 	for (i = 0; i < wb->len; i++) {
728 		if (wb->history[pos] == state) {
729 			*adjust = i;
730 			return true;
731 		}
732 		/* -1 wraps to WB_HISTORY_SIZE - 1 */
733 		pos = (pos - 1) & (WB_HISTORY_SIZE - 1);
734 	}
735 
736 	return false;
737 }
738 
739 static aa_state_t leftmatch_fb(struct aa_dfa *dfa, aa_state_t start,
740 				 const char *str, struct match_workbuf *wb,
741 				 unsigned int *count)
742 {
743 	u32 *def = DEFAULT_TABLE(dfa);
744 	u32 *base = BASE_TABLE(dfa);
745 	u32 *next = NEXT_TABLE(dfa);
746 	u32 *check = CHECK_TABLE(dfa);
747 	aa_state_t state = start, pos;
748 
749 	AA_BUG(!dfa);
750 	AA_BUG(!str);
751 	AA_BUG(!wb);
752 	AA_BUG(!count);
753 
754 	*count = 0;
755 	if (state == DFA_NOMATCH)
756 		return DFA_NOMATCH;
757 
758 	/* current state is <state>, matching character *str */
759 	if (dfa->tables[YYTD_ID_EC]) {
760 		/* Equivalence class table defined */
761 		u8 *equiv = EQUIV_TABLE(dfa);
762 		/* default is direct to next state */
763 		while (*str) {
764 			unsigned int adjust;
765 
766 			wb->history[wb->pos] = state;
767 			pos = base_idx(base[state]) + equiv[(u8) *str++];
768 			if (check[pos] == state)
769 				state = next[pos];
770 			else
771 				state = def[state];
772 			if (is_loop(wb, state, &adjust)) {
773 				state = aa_dfa_match(dfa, state, str);
774 				*count -= adjust;
775 				goto out;
776 			}
777 			inc_wb_pos(wb);
778 			(*count)++;
779 		}
780 	} else {
781 		/* default is direct to next state */
782 		while (*str) {
783 			unsigned int adjust;
784 
785 			wb->history[wb->pos] = state;
786 			pos = base_idx(base[state]) + (u8) *str++;
787 			if (check[pos] == state)
788 				state = next[pos];
789 			else
790 				state = def[state];
791 			if (is_loop(wb, state, &adjust)) {
792 				state = aa_dfa_match(dfa, state, str);
793 				*count -= adjust;
794 				goto out;
795 			}
796 			inc_wb_pos(wb);
797 			(*count)++;
798 		}
799 	}
800 
801 out:
802 	if (!state)
803 		*count = 0;
804 	return state;
805 }
806 
807 /**
808  * aa_dfa_leftmatch - traverse @dfa to find state @str stops at
809  * @dfa: the dfa to match @str against  (NOT NULL)
810  * @start: the state of the dfa to start matching in
811  * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
812  * @count: current count of longest left.
813  *
814  * aa_dfa_match will match @str against the dfa and return the state it
815  * finished matching in. The final state can be used to look up the accepting
816  * label, or as the start state of a continuing match.
817  *
818  * Returns: final state reached after input is consumed
819  */
820 aa_state_t aa_dfa_leftmatch(struct aa_dfa *dfa, aa_state_t start,
821 			    const char *str, unsigned int *count)
822 {
823 	DEFINE_MATCH_WB(wb);
824 
825 	/* TODO: match for extended state dfas */
826 
827 	return leftmatch_fb(dfa, start, str, &wb, count);
828 }
829