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