| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AppArmor security module |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Copyright (C) 1998-2008 Novell/SUSE |
|---|
| 7 | 8 | * Copyright 2009-2012 Canonical Ltd. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or |
|---|
| 10 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 11 | | - * published by the Free Software Foundation, version 2 of the |
|---|
| 12 | | - * License. |
|---|
| 13 | 9 | */ |
|---|
| 14 | 10 | |
|---|
| 15 | 11 | #include <linux/errno.h> |
|---|
| .. | .. |
|---|
| 211 | 207 | if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && |
|---|
| 212 | 208 | (DEFAULT_TABLE(dfa)[i] >= state_count)) |
|---|
| 213 | 209 | goto out; |
|---|
| 210 | + if (BASE_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) { |
|---|
| 211 | + pr_err("AppArmor DFA state with invalid match flags"); |
|---|
| 212 | + goto out; |
|---|
| 213 | + } |
|---|
| 214 | + if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE)) { |
|---|
| 215 | + if (!(dfa->flags & YYTH_FLAG_DIFF_ENCODE)) { |
|---|
| 216 | + pr_err("AppArmor DFA diff encoded transition state without header flag"); |
|---|
| 217 | + goto out; |
|---|
| 218 | + } |
|---|
| 219 | + } |
|---|
| 220 | + if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_OOB_TRANSITION)) { |
|---|
| 221 | + if (base_idx(BASE_TABLE(dfa)[i]) < dfa->max_oob) { |
|---|
| 222 | + pr_err("AppArmor DFA out of bad transition out of range"); |
|---|
| 223 | + goto out; |
|---|
| 224 | + } |
|---|
| 225 | + if (!(dfa->flags & YYTH_FLAG_OOB_TRANS)) { |
|---|
| 226 | + pr_err("AppArmor DFA out of bad transition state without header flag"); |
|---|
| 227 | + goto out; |
|---|
| 228 | + } |
|---|
| 229 | + } |
|---|
| 214 | 230 | if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { |
|---|
| 215 | 231 | pr_err("AppArmor DFA next/check upper bounds error\n"); |
|---|
| 216 | 232 | goto out; |
|---|
| .. | .. |
|---|
| 313 | 329 | goto fail; |
|---|
| 314 | 330 | |
|---|
| 315 | 331 | dfa->flags = ntohs(*(__be16 *) (data + 12)); |
|---|
| 316 | | - if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE) |
|---|
| 332 | + if (dfa->flags & ~(YYTH_FLAGS)) |
|---|
| 317 | 333 | goto fail; |
|---|
| 334 | + |
|---|
| 335 | + /* |
|---|
| 336 | + * TODO: needed for dfa to support more than 1 oob |
|---|
| 337 | + * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) { |
|---|
| 338 | + * if (hsize < 16 + 4) |
|---|
| 339 | + * goto fail; |
|---|
| 340 | + * dfa->max_oob = ntol(*(__be32 *) (data + 16)); |
|---|
| 341 | + * if (dfa->max <= MAX_OOB_SUPPORTED) { |
|---|
| 342 | + * pr_err("AppArmor DFA OOB greater than supported\n"); |
|---|
| 343 | + * goto fail; |
|---|
| 344 | + * } |
|---|
| 345 | + * } |
|---|
| 346 | + */ |
|---|
| 347 | + dfa->max_oob = 1; |
|---|
| 318 | 348 | |
|---|
| 319 | 349 | data += hsize; |
|---|
| 320 | 350 | size -= hsize; |
|---|
| .. | .. |
|---|
| 504 | 534 | return state; |
|---|
| 505 | 535 | } |
|---|
| 506 | 536 | |
|---|
| 537 | +unsigned int aa_dfa_outofband_transition(struct aa_dfa *dfa, unsigned int state) |
|---|
| 538 | +{ |
|---|
| 539 | + u16 *def = DEFAULT_TABLE(dfa); |
|---|
| 540 | + u32 *base = BASE_TABLE(dfa); |
|---|
| 541 | + u16 *next = NEXT_TABLE(dfa); |
|---|
| 542 | + u16 *check = CHECK_TABLE(dfa); |
|---|
| 543 | + u32 b = (base)[(state)]; |
|---|
| 544 | + |
|---|
| 545 | + if (!(b & MATCH_FLAG_OOB_TRANSITION)) |
|---|
| 546 | + return DFA_NOMATCH; |
|---|
| 547 | + |
|---|
| 548 | + /* No Equivalence class remapping for outofband transitions */ |
|---|
| 549 | + match_char(state, def, base, next, check, -1); |
|---|
| 550 | + |
|---|
| 551 | + return state; |
|---|
| 552 | +} |
|---|
| 553 | + |
|---|
| 507 | 554 | /** |
|---|
| 508 | 555 | * aa_dfa_match_until - traverse @dfa until accept state or end of input |
|---|
| 509 | 556 | * @dfa: the dfa to match @str against (NOT NULL) |
|---|
| .. | .. |
|---|
| 625 | 672 | |
|---|
| 626 | 673 | #define inc_wb_pos(wb) \ |
|---|
| 627 | 674 | do { \ |
|---|
| 628 | | - wb->pos = (wb->pos + 1) & (wb->size - 1); \ |
|---|
| 629 | | - wb->len = (wb->len + 1) & (wb->size - 1); \ |
|---|
| 675 | + wb->pos = (wb->pos + 1) & (WB_HISTORY_SIZE - 1); \ |
|---|
| 676 | + wb->len = (wb->len + 1) & (WB_HISTORY_SIZE - 1); \ |
|---|
| 630 | 677 | } while (0) |
|---|
| 631 | 678 | |
|---|
| 632 | 679 | /* For DFAs that don't support extended tagging of states */ |
|---|
| .. | .. |
|---|
| 645 | 692 | return true; |
|---|
| 646 | 693 | } |
|---|
| 647 | 694 | if (pos == 0) |
|---|
| 648 | | - pos = wb->size; |
|---|
| 695 | + pos = WB_HISTORY_SIZE; |
|---|
| 649 | 696 | pos--; |
|---|
| 650 | 697 | } |
|---|
| 651 | 698 | |
|---|