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