linux/security/apparmor/match.c
<<
>>
Prefs
   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
  24static char nulldfa_src[] = {
  25        #include "nulldfa.in"
  26};
  27struct aa_dfa *nulldfa;
  28
  29static char stacksplitdfa_src[] = {
  30        #include "stacksplitdfa.in"
  31};
  32struct aa_dfa *stacksplitdfa;
  33
  34int 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
  62void 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 */
  77static 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
 127out:
 128        return table;
 129fail:
 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 */
 144static 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;
 181out:
 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 */
 194static 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_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
 206                        pr_err("AppArmor DFA next/check upper bounds error\n");
 207                        goto out;
 208                }
 209        }
 210
 211        for (i = 0; i < trans_count; i++) {
 212                if (NEXT_TABLE(dfa)[i] >= state_count)
 213                        goto out;
 214                if (CHECK_TABLE(dfa)[i] >= state_count)
 215                        goto out;
 216        }
 217
 218        /* Now that all the other tables are verified, verify diffencoding */
 219        for (i = 0; i < state_count; i++) {
 220                size_t j, k;
 221
 222                for (j = i;
 223                     (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) &&
 224                     !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE);
 225                     j = k) {
 226                        k = DEFAULT_TABLE(dfa)[j];
 227                        if (j == k)
 228                                goto out;
 229                        if (k < j)
 230                                break;          /* already verified */
 231                        BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE;
 232                }
 233        }
 234        error = 0;
 235
 236out:
 237        return error;
 238}
 239
 240/**
 241 * dfa_free - free a dfa allocated by aa_dfa_unpack
 242 * @dfa: the dfa to free  (MAYBE NULL)
 243 *
 244 * Requires: reference count to dfa == 0
 245 */
 246static void dfa_free(struct aa_dfa *dfa)
 247{
 248        if (dfa) {
 249                int i;
 250
 251                for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) {
 252                        kvfree(dfa->tables[i]);
 253                        dfa->tables[i] = NULL;
 254                }
 255                kfree(dfa);
 256        }
 257}
 258
 259/**
 260 * aa_dfa_free_kref - free aa_dfa by kref (called by aa_put_dfa)
 261 * @kr: kref callback for freeing of a dfa  (NOT NULL)
 262 */
 263void aa_dfa_free_kref(struct kref *kref)
 264{
 265        struct aa_dfa *dfa = container_of(kref, struct aa_dfa, count);
 266        dfa_free(dfa);
 267}
 268
 269/**
 270 * aa_dfa_unpack - unpack the binary tables of a serialized dfa
 271 * @blob: aligned serialized stream of data to unpack  (NOT NULL)
 272 * @size: size of data to unpack
 273 * @flags: flags controlling what type of accept tables are acceptable
 274 *
 275 * Unpack a dfa that has been serialized.  To find information on the dfa
 276 * format look in Documentation/admin-guide/LSM/apparmor.rst
 277 * Assumes the dfa @blob stream has been aligned on a 8 byte boundary
 278 *
 279 * Returns: an unpacked dfa ready for matching or ERR_PTR on failure
 280 */
 281struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
 282{
 283        int hsize;
 284        int error = -ENOMEM;
 285        char *data = blob;
 286        struct table_header *table = NULL;
 287        struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
 288        if (!dfa)
 289                goto fail;
 290
 291        kref_init(&dfa->count);
 292
 293        error = -EPROTO;
 294
 295        /* get dfa table set header */
 296        if (size < sizeof(struct table_set_header))
 297                goto fail;
 298
 299        if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
 300                goto fail;
 301
 302        hsize = ntohl(*(__be32 *) (data + 4));
 303        if (size < hsize)
 304                goto fail;
 305
 306        dfa->flags = ntohs(*(__be16 *) (data + 12));
 307        if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE)
 308                goto fail;
 309
 310        data += hsize;
 311        size -= hsize;
 312
 313        while (size > 0) {
 314                table = unpack_table(data, size);
 315                if (!table)
 316                        goto fail;
 317
 318                switch (table->td_id) {
 319                case YYTD_ID_ACCEPT:
 320                        if (!(table->td_flags & ACCEPT1_FLAGS(flags)))
 321                                goto fail;
 322                        break;
 323                case YYTD_ID_ACCEPT2:
 324                        if (!(table->td_flags & ACCEPT2_FLAGS(flags)))
 325                                goto fail;
 326                        break;
 327                case YYTD_ID_BASE:
 328                        if (table->td_flags != YYTD_DATA32)
 329                                goto fail;
 330                        break;
 331                case YYTD_ID_DEF:
 332                case YYTD_ID_NXT:
 333                case YYTD_ID_CHK:
 334                        if (table->td_flags != YYTD_DATA16)
 335                                goto fail;
 336                        break;
 337                case YYTD_ID_EC:
 338                        if (table->td_flags != YYTD_DATA8)
 339                                goto fail;
 340                        break;
 341                default:
 342                        goto fail;
 343                }
 344                /* check for duplicate table entry */
 345                if (dfa->tables[table->td_id])
 346                        goto fail;
 347                dfa->tables[table->td_id] = table;
 348                data += table_size(table->td_lolen, table->td_flags);
 349                size -= table_size(table->td_lolen, table->td_flags);
 350                table = NULL;
 351        }
 352        error = verify_table_headers(dfa->tables, flags);
 353        if (error)
 354                goto fail;
 355
 356        if (flags & DFA_FLAG_VERIFY_STATES) {
 357                error = verify_dfa(dfa);
 358                if (error)
 359                        goto fail;
 360        }
 361
 362        return dfa;
 363
 364fail:
 365        kvfree(table);
 366        dfa_free(dfa);
 367        return ERR_PTR(error);
 368}
 369
 370#define match_char(state, def, base, next, check, C)    \
 371do {                                                    \
 372        u32 b = (base)[(state)];                        \
 373        unsigned int pos = base_idx(b) + (C);           \
 374        if ((check)[pos] != (state)) {                  \
 375                (state) = (def)[(state)];               \
 376                if (b & MATCH_FLAG_DIFF_ENCODE)         \
 377                        continue;                       \
 378                break;                                  \
 379        }                                               \
 380        (state) = (next)[pos];                          \
 381        break;                                          \
 382} while (1)
 383
 384/**
 385 * aa_dfa_match_len - traverse @dfa to find state @str stops at
 386 * @dfa: the dfa to match @str against  (NOT NULL)
 387 * @start: the state of the dfa to start matching in
 388 * @str: the string of bytes to match against the dfa  (NOT NULL)
 389 * @len: length of the string of bytes to match
 390 *
 391 * aa_dfa_match_len will match @str against the dfa and return the state it
 392 * finished matching in. The final state can be used to look up the accepting
 393 * label, or as the start state of a continuing match.
 394 *
 395 * This function will happily match again the 0 byte and only finishes
 396 * when @len input is consumed.
 397 *
 398 * Returns: final state reached after input is consumed
 399 */
 400unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
 401                              const char *str, int len)
 402{
 403        u16 *def = DEFAULT_TABLE(dfa);
 404        u32 *base = BASE_TABLE(dfa);
 405        u16 *next = NEXT_TABLE(dfa);
 406        u16 *check = CHECK_TABLE(dfa);
 407        unsigned int state = start;
 408
 409        if (state == 0)
 410                return 0;
 411
 412        /* current state is <state>, matching character *str */
 413        if (dfa->tables[YYTD_ID_EC]) {
 414                /* Equivalence class table defined */
 415                u8 *equiv = EQUIV_TABLE(dfa);
 416                for (; len; len--)
 417                        match_char(state, def, base, next, check,
 418                                   equiv[(u8) *str++]);
 419        } else {
 420                /* default is direct to next state */
 421                for (; len; len--)
 422                        match_char(state, def, base, next, check, (u8) *str++);
 423        }
 424
 425        return state;
 426}
 427
 428/**
 429 * aa_dfa_match - traverse @dfa to find state @str stops at
 430 * @dfa: the dfa to match @str against  (NOT NULL)
 431 * @start: the state of the dfa to start matching in
 432 * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
 433 *
 434 * aa_dfa_match will match @str against the dfa and return the state it
 435 * finished matching in. The final state can be used to look up the accepting
 436 * label, or as the start state of a continuing match.
 437 *
 438 * Returns: final state reached after input is consumed
 439 */
 440unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
 441                          const char *str)
 442{
 443        u16 *def = DEFAULT_TABLE(dfa);
 444        u32 *base = BASE_TABLE(dfa);
 445        u16 *next = NEXT_TABLE(dfa);
 446        u16 *check = CHECK_TABLE(dfa);
 447        unsigned int state = start;
 448
 449        if (state == 0)
 450                return 0;
 451
 452        /* current state is <state>, matching character *str */
 453        if (dfa->tables[YYTD_ID_EC]) {
 454                /* Equivalence class table defined */
 455                u8 *equiv = EQUIV_TABLE(dfa);
 456                /* default is direct to next state */
 457                while (*str)
 458                        match_char(state, def, base, next, check,
 459                                   equiv[(u8) *str++]);
 460        } else {
 461                /* default is direct to next state */
 462                while (*str)
 463                        match_char(state, def, base, next, check, (u8) *str++);
 464        }
 465
 466        return state;
 467}
 468
 469/**
 470 * aa_dfa_next - step one character to the next state in the dfa
 471 * @dfa: the dfa to traverse (NOT NULL)
 472 * @state: the state to start in
 473 * @c: the input character to transition on
 474 *
 475 * aa_dfa_match will step through the dfa by one input character @c
 476 *
 477 * Returns: state reach after input @c
 478 */
 479unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
 480                          const char c)
 481{
 482        u16 *def = DEFAULT_TABLE(dfa);
 483        u32 *base = BASE_TABLE(dfa);
 484        u16 *next = NEXT_TABLE(dfa);
 485        u16 *check = CHECK_TABLE(dfa);
 486
 487        /* current state is <state>, matching character *str */
 488        if (dfa->tables[YYTD_ID_EC]) {
 489                /* Equivalence class table defined */
 490                u8 *equiv = EQUIV_TABLE(dfa);
 491                match_char(state, def, base, next, check, equiv[(u8) c]);
 492        } else
 493                match_char(state, def, base, next, check, (u8) c);
 494
 495        return state;
 496}
 497
 498/**
 499 * aa_dfa_match_until - traverse @dfa until accept state or end of input
 500 * @dfa: the dfa to match @str against  (NOT NULL)
 501 * @start: the state of the dfa to start matching in
 502 * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
 503 * @retpos: first character in str after match OR end of string
 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 */
 511unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start,
 512                                const char *str, const char **retpos)
 513{
 514        u16 *def = DEFAULT_TABLE(dfa);
 515        u32 *base = BASE_TABLE(dfa);
 516        u16 *next = NEXT_TABLE(dfa);
 517        u16 *check = CHECK_TABLE(dfa);
 518        u32 *accept = ACCEPT_TABLE(dfa);
 519        unsigned int state = start, pos;
 520
 521        if (state == 0)
 522                return 0;
 523
 524        /* current state is <state>, matching character *str */
 525        if (dfa->tables[YYTD_ID_EC]) {
 526                /* Equivalence class table defined */
 527                u8 *equiv = EQUIV_TABLE(dfa);
 528                /* default is direct to next state */
 529                while (*str) {
 530                        pos = base_idx(base[state]) + equiv[(u8) *str++];
 531                        if (check[pos] == state)
 532                                state = next[pos];
 533                        else
 534                                state = def[state];
 535                        if (accept[state])
 536                                break;
 537                }
 538        } else {
 539                /* default is direct to next state */
 540                while (*str) {
 541                        pos = base_idx(base[state]) + (u8) *str++;
 542                        if (check[pos] == state)
 543                                state = next[pos];
 544                        else
 545                                state = def[state];
 546                        if (accept[state])
 547                                break;
 548                }
 549        }
 550
 551        *retpos = str;
 552        return state;
 553}
 554
 555/**
 556 * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed
 557 * @dfa: the dfa to match @str against  (NOT NULL)
 558 * @start: the state of the dfa to start matching in
 559 * @str: the string of bytes to match against the dfa  (NOT NULL)
 560 * @n: length of the string of bytes to match
 561 * @retpos: first character in str after match OR str + n
 562 *
 563 * aa_dfa_match_len will match @str against the dfa and return the state it
 564 * finished matching in. The final state can be used to look up the accepting
 565 * label, or as the start state of a continuing match.
 566 *
 567 * This function will happily match again the 0 byte and only finishes
 568 * when @n input is consumed.
 569 *
 570 * Returns: final state reached after input is consumed
 571 */
 572unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
 573                                 const char *str, int n, const char **retpos)
 574{
 575        u16 *def = DEFAULT_TABLE(dfa);
 576        u32 *base = BASE_TABLE(dfa);
 577        u16 *next = NEXT_TABLE(dfa);
 578        u16 *check = CHECK_TABLE(dfa);
 579        u32 *accept = ACCEPT_TABLE(dfa);
 580        unsigned int state = start, pos;
 581
 582        *retpos = NULL;
 583        if (state == 0)
 584                return 0;
 585
 586        /* current state is <state>, matching character *str */
 587        if (dfa->tables[YYTD_ID_EC]) {
 588                /* Equivalence class table defined */
 589                u8 *equiv = EQUIV_TABLE(dfa);
 590                /* default is direct to next state */
 591                for (; n; n--) {
 592                        pos = base_idx(base[state]) + equiv[(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        } else {
 601                /* default is direct to next state */
 602                for (; n; n--) {
 603                        pos = base_idx(base[state]) + (u8) *str++;
 604                        if (check[pos] == state)
 605                                state = next[pos];
 606                        else
 607                                state = def[state];
 608                        if (accept[state])
 609                                break;
 610                }
 611        }
 612
 613        *retpos = str;
 614        return state;
 615}
 616
 617#define inc_wb_pos(wb)                                          \
 618do {                                                            \
 619        wb->pos = (wb->pos + 1) & (wb->size - 1);               \
 620        wb->len = (wb->len + 1) & (wb->size - 1);               \
 621} while (0)
 622
 623/* For DFAs that don't support extended tagging of states */
 624static bool is_loop(struct match_workbuf *wb, unsigned int state,
 625                    unsigned int *adjust)
 626{
 627        unsigned int pos = wb->pos;
 628        unsigned int i;
 629
 630        if (wb->history[pos] < state)
 631                return false;
 632
 633        for (i = 0; i <= wb->len; i++) {
 634                if (wb->history[pos] == state) {
 635                        *adjust = i;
 636                        return true;
 637                }
 638                if (pos == 0)
 639                        pos = wb->size;
 640                pos--;
 641        }
 642
 643        *adjust = i;
 644        return true;
 645}
 646
 647static unsigned int leftmatch_fb(struct aa_dfa *dfa, unsigned int start,
 648                                 const char *str, struct match_workbuf *wb,
 649                                 unsigned int *count)
 650{
 651        u16 *def = DEFAULT_TABLE(dfa);
 652        u32 *base = BASE_TABLE(dfa);
 653        u16 *next = NEXT_TABLE(dfa);
 654        u16 *check = CHECK_TABLE(dfa);
 655        unsigned int state = start, pos;
 656
 657        AA_BUG(!dfa);
 658        AA_BUG(!str);
 659        AA_BUG(!wb);
 660        AA_BUG(!count);
 661
 662        *count = 0;
 663        if (state == 0)
 664                return 0;
 665
 666        /* current state is <state>, matching character *str */
 667        if (dfa->tables[YYTD_ID_EC]) {
 668                /* Equivalence class table defined */
 669                u8 *equiv = EQUIV_TABLE(dfa);
 670                /* default is direct to next state */
 671                while (*str) {
 672                        unsigned int adjust;
 673
 674                        wb->history[wb->pos] = state;
 675                        pos = base_idx(base[state]) + equiv[(u8) *str++];
 676                        if (check[pos] == state)
 677                                state = next[pos];
 678                        else
 679                                state = def[state];
 680                        if (is_loop(wb, state, &adjust)) {
 681                                state = aa_dfa_match(dfa, state, str);
 682                                *count -= adjust;
 683                                goto out;
 684                        }
 685                        inc_wb_pos(wb);
 686                        (*count)++;
 687                }
 688        } else {
 689                /* default is direct to next state */
 690                while (*str) {
 691                        unsigned int adjust;
 692
 693                        wb->history[wb->pos] = state;
 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 (is_loop(wb, state, &adjust)) {
 700                                state = aa_dfa_match(dfa, state, str);
 701                                *count -= adjust;
 702                                goto out;
 703                        }
 704                        inc_wb_pos(wb);
 705                        (*count)++;
 706                }
 707        }
 708
 709out:
 710        if (!state)
 711                *count = 0;
 712        return state;
 713}
 714
 715/**
 716 * aa_dfa_leftmatch - traverse @dfa to find state @str stops at
 717 * @dfa: the dfa to match @str against  (NOT NULL)
 718 * @start: the state of the dfa to start matching in
 719 * @str: the null terminated string of bytes to match against the dfa (NOT NULL)
 720 * @count: current count of longest left.
 721 *
 722 * aa_dfa_match will match @str against the dfa and return the state it
 723 * finished matching in. The final state can be used to look up the accepting
 724 * label, or as the start state of a continuing match.
 725 *
 726 * Returns: final state reached after input is consumed
 727 */
 728unsigned int aa_dfa_leftmatch(struct aa_dfa *dfa, unsigned int start,
 729                              const char *str, unsigned int *count)
 730{
 731        DEFINE_MATCH_WB(wb);
 732
 733        /* TODO: match for extended state dfas */
 734
 735        return leftmatch_fb(dfa, start, str, &wb, count);
 736}
 737