1 /* 2 * AppArmor security module 3 * 4 * This file contains AppArmor dfa based regular expression matching engine 5 * 6 * Copyright (C) 1998-2008 Novell/SUSE 7 * 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 */ 14 15 #include <linux/errno.h> 16 #include <linux/kernel.h> 17 #include <linux/mm.h> 18 #include <linux/slab.h> 19 #include <linux/vmalloc.h> 20 #include <linux/err.h> 21 #include <linux/kref.h> 22 23 #include "include/lib.h" 24 #include "include/match.h" 25 26 #define base_idx(X) ((X) & 0xffffff) 27 28 static char nulldfa_src[] = { 29 #include "nulldfa.in" 30 }; 31 struct aa_dfa *nulldfa; 32 33 static char stacksplitdfa_src[] = { 34 #include "stacksplitdfa.in" 35 }; 36 struct aa_dfa *stacksplitdfa; 37 38 int aa_setup_dfa_engine(void) 39 { 40 int error; 41 42 nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src), 43 TO_ACCEPT1_FLAG(YYTD_DATA32) | 44 TO_ACCEPT2_FLAG(YYTD_DATA32)); 45 if (IS_ERR(nulldfa)) { 46 error = PTR_ERR(nulldfa); 47 nulldfa = NULL; 48 return error; 49 } 50 51 stacksplitdfa = aa_dfa_unpack(stacksplitdfa_src, 52 sizeof(stacksplitdfa_src), 53 TO_ACCEPT1_FLAG(YYTD_DATA32) | 54 TO_ACCEPT2_FLAG(YYTD_DATA32)); 55 if (IS_ERR(stacksplitdfa)) { 56 aa_put_dfa(nulldfa); 57 nulldfa = NULL; 58 error = PTR_ERR(stacksplitdfa); 59 stacksplitdfa = NULL; 60 return error; 61 } 62 63 return 0; 64 } 65 66 void aa_teardown_dfa_engine(void) 67 { 68 aa_put_dfa(stacksplitdfa); 69 aa_put_dfa(nulldfa); 70 } 71 72 /** 73 * unpack_table - unpack a dfa table (one of accept, default, base, next check) 74 * @blob: data to unpack (NOT NULL) 75 * @bsize: size of blob 76 * 77 * Returns: pointer to table else NULL on failure 78 * 79 * NOTE: must be freed by kvfree (not kfree) 80 */ 81 static struct table_header *unpack_table(char *blob, size_t bsize) 82 { 83 struct table_header *table = NULL; 84 struct table_header th; 85 size_t tsize; 86 87 if (bsize < sizeof(struct table_header)) 88 goto out; 89 90 /* loaded td_id's start at 1, subtract 1 now to avoid doing 91 * it every time we use td_id as an index 92 */ 93 th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1; 94 if (th.td_id > YYTD_ID_MAX) 95 goto out; 96 th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2)); 97 th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8)); 98 blob += sizeof(struct table_header); 99 100 if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || 101 th.td_flags == YYTD_DATA8)) 102 goto out; 103 104 tsize = table_size(th.td_lolen, th.td_flags); 105 if (bsize < tsize) 106 goto out; 107 108 table = kvzalloc(tsize, GFP_KERNEL); 109 if (table) { 110 table->td_id = th.td_id; 111 table->td_flags = th.td_flags; 112 table->td_lolen = th.td_lolen; 113 if (th.td_flags == YYTD_DATA8) 114 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 115 u8, u8, byte_to_byte); 116 else if (th.td_flags == YYTD_DATA16) 117 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 118 u16, __be16, be16_to_cpu); 119 else if (th.td_flags == YYTD_DATA32) 120 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 121 u32, __be32, be32_to_cpu); 122 else 123 goto fail; 124 /* if table was vmalloced make sure the page tables are synced 125 * before it is used, as it goes live to all cpus. 126 */ 127 if (is_vmalloc_addr(table)) 128 vm_unmap_aliases(); 129 } 130 131 out: 132 return table; 133 fail: 134 kvfree(table); 135 return NULL; 136 } 137 138 /** 139 * verify_dfa - verify that transitions and states in the tables are in bounds. 140 * @dfa: dfa to test (NOT NULL) 141 * @flags: flags controlling what type of accept table are acceptable 142 * 143 * Assumes dfa has gone through the first pass verification done by unpacking 144 * NOTE: this does not valid accept table values 145 * 146 * Returns: %0 else error code on failure to verify 147 */ 148 static int verify_dfa(struct aa_dfa *dfa, int flags) 149 { 150 size_t i, state_count, trans_count; 151 int error = -EPROTO; 152 153 /* check that required tables exist */ 154 if (!(dfa->tables[YYTD_ID_DEF] && 155 dfa->tables[YYTD_ID_BASE] && 156 dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) 157 goto out; 158 159 /* accept.size == default.size == base.size */ 160 state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; 161 if (ACCEPT1_FLAGS(flags)) { 162 if (!dfa->tables[YYTD_ID_ACCEPT]) 163 goto out; 164 if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) 165 goto out; 166 } 167 if (ACCEPT2_FLAGS(flags)) { 168 if (!dfa->tables[YYTD_ID_ACCEPT2]) 169 goto out; 170 if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) 171 goto out; 172 } 173 if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) 174 goto out; 175 176 /* next.size == chk.size */ 177 trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; 178 if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) 179 goto out; 180 181 /* if equivalence classes then its table size must be 256 */ 182 if (dfa->tables[YYTD_ID_EC] && 183 dfa->tables[YYTD_ID_EC]->td_lolen != 256) 184 goto out; 185 186 if (flags & DFA_FLAG_VERIFY_STATES) { 187 for (i = 0; i < state_count; i++) { 188 if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && 189 (DEFAULT_TABLE(dfa)[i] >= state_count)) 190 goto out; 191 if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { 192 printk(KERN_ERR "AppArmor DFA next/check upper " 193 "bounds error\n"); 194 goto out; 195 } 196 } 197 198 for (i = 0; i < trans_count; i++) { 199 if (NEXT_TABLE(dfa)[i] >= state_count) 200 goto out; 201 if (CHECK_TABLE(dfa)[i] >= state_count) 202 goto out; 203 } 204 } 205 206 /* Now that all the other tables are verified, verify diffencoding */ 207 if (flags & DFA_FLAG_VERIFY_STATES) { 208 size_t j, k; 209 210 for (i = 0; i < state_count; i++) { 211 for (j = i; 212 (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && 213 !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE); 214 j = k) { 215 k = DEFAULT_TABLE(dfa)[j]; 216 if (j == k) 217 goto out; 218 if (k < j) 219 break; /* already verified */ 220 BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE; 221 } 222 } 223 } 224 error = 0; 225 out: 226 return error; 227 } 228 229 /** 230 * dfa_free - free a dfa allocated by aa_dfa_unpack 231 * @dfa: the dfa to free (MAYBE NULL) 232 * 233 * Requires: reference count to dfa == 0 234 */ 235 static void dfa_free(struct aa_dfa *dfa) 236 { 237 if (dfa) { 238 int i; 239 240 for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { 241 kvfree(dfa->tables[i]); 242 dfa->tables[i] = NULL; 243 } 244 kfree(dfa); 245 } 246 } 247 248 /** 249 * aa_dfa_free_kref - free aa_dfa by kref (called by aa_put_dfa) 250 * @kr: kref callback for freeing of a dfa (NOT NULL) 251 */ 252 void aa_dfa_free_kref(struct kref *kref) 253 { 254 struct aa_dfa *dfa = container_of(kref, struct aa_dfa, count); 255 dfa_free(dfa); 256 } 257 258 /** 259 * aa_dfa_unpack - unpack the binary tables of a serialized dfa 260 * @blob: aligned serialized stream of data to unpack (NOT NULL) 261 * @size: size of data to unpack 262 * @flags: flags controlling what type of accept tables are acceptable 263 * 264 * Unpack a dfa that has been serialized. To find information on the dfa 265 * format look in Documentation/admin-guide/LSM/apparmor.rst 266 * Assumes the dfa @blob stream has been aligned on a 8 byte boundary 267 * 268 * Returns: an unpacked dfa ready for matching or ERR_PTR on failure 269 */ 270 struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) 271 { 272 int hsize; 273 int error = -ENOMEM; 274 char *data = blob; 275 struct table_header *table = NULL; 276 struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); 277 if (!dfa) 278 goto fail; 279 280 kref_init(&dfa->count); 281 282 error = -EPROTO; 283 284 /* get dfa table set header */ 285 if (size < sizeof(struct table_set_header)) 286 goto fail; 287 288 if (ntohl(*(__be32 *) data) != YYTH_MAGIC) 289 goto fail; 290 291 hsize = ntohl(*(__be32 *) (data + 4)); 292 if (size < hsize) 293 goto fail; 294 295 dfa->flags = ntohs(*(__be16 *) (data + 12)); 296 if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE) 297 goto fail; 298 299 data += hsize; 300 size -= hsize; 301 302 while (size > 0) { 303 table = unpack_table(data, size); 304 if (!table) 305 goto fail; 306 307 switch (table->td_id) { 308 case YYTD_ID_ACCEPT: 309 if (!(table->td_flags & ACCEPT1_FLAGS(flags))) 310 goto fail; 311 break; 312 case YYTD_ID_ACCEPT2: 313 if (!(table->td_flags & ACCEPT2_FLAGS(flags))) 314 goto fail; 315 break; 316 case YYTD_ID_BASE: 317 if (table->td_flags != YYTD_DATA32) 318 goto fail; 319 break; 320 case YYTD_ID_DEF: 321 case YYTD_ID_NXT: 322 case YYTD_ID_CHK: 323 if (table->td_flags != YYTD_DATA16) 324 goto fail; 325 break; 326 case YYTD_ID_EC: 327 if (table->td_flags != YYTD_DATA8) 328 goto fail; 329 break; 330 default: 331 goto fail; 332 } 333 /* check for duplicate table entry */ 334 if (dfa->tables[table->td_id]) 335 goto fail; 336 dfa->tables[table->td_id] = table; 337 data += table_size(table->td_lolen, table->td_flags); 338 size -= table_size(table->td_lolen, table->td_flags); 339 table = NULL; 340 } 341 342 error = verify_dfa(dfa, flags); 343 if (error) 344 goto fail; 345 346 return dfa; 347 348 fail: 349 kvfree(table); 350 dfa_free(dfa); 351 return ERR_PTR(error); 352 } 353 354 #define match_char(state, def, base, next, check, C) \ 355 do { \ 356 u32 b = (base)[(state)]; \ 357 unsigned int pos = base_idx(b) + (C); \ 358 if ((check)[pos] != (state)) { \ 359 (state) = (def)[(state)]; \ 360 if (b & MATCH_FLAG_DIFF_ENCODE) \ 361 continue; \ 362 break; \ 363 } \ 364 (state) = (next)[pos]; \ 365 break; \ 366 } while (1) 367 368 /** 369 * aa_dfa_match_len - traverse @dfa to find state @str stops at 370 * @dfa: the dfa to match @str against (NOT NULL) 371 * @start: the state of the dfa to start matching in 372 * @str: the string of bytes to match against the dfa (NOT NULL) 373 * @len: length of the string of bytes to match 374 * 375 * aa_dfa_match_len will match @str against the dfa and return the state it 376 * finished matching in. The final state can be used to look up the accepting 377 * label, or as the start state of a continuing match. 378 * 379 * This function will happily match again the 0 byte and only finishes 380 * when @len input is consumed. 381 * 382 * Returns: final state reached after input is consumed 383 */ 384 unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, 385 const char *str, int len) 386 { 387 u16 *def = DEFAULT_TABLE(dfa); 388 u32 *base = BASE_TABLE(dfa); 389 u16 *next = NEXT_TABLE(dfa); 390 u16 *check = CHECK_TABLE(dfa); 391 unsigned int state = start; 392 393 if (state == 0) 394 return 0; 395 396 /* current state is <state>, matching character *str */ 397 if (dfa->tables[YYTD_ID_EC]) { 398 /* Equivalence class table defined */ 399 u8 *equiv = EQUIV_TABLE(dfa); 400 for (; len; len--) 401 match_char(state, def, base, next, check, 402 equiv[(u8) *str++]); 403 } else { 404 /* default is direct to next state */ 405 for (; len; len--) 406 match_char(state, def, base, next, check, (u8) *str++); 407 } 408 409 return state; 410 } 411 412 /** 413 * aa_dfa_match - traverse @dfa to find state @str stops at 414 * @dfa: the dfa to match @str against (NOT NULL) 415 * @start: the state of the dfa to start matching in 416 * @str: the null terminated string of bytes to match against the dfa (NOT NULL) 417 * 418 * aa_dfa_match will match @str against the dfa and return the state it 419 * finished matching in. The final state can be used to look up the accepting 420 * label, or as the start state of a continuing match. 421 * 422 * Returns: final state reached after input is consumed 423 */ 424 unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 425 const char *str) 426 { 427 u16 *def = DEFAULT_TABLE(dfa); 428 u32 *base = BASE_TABLE(dfa); 429 u16 *next = NEXT_TABLE(dfa); 430 u16 *check = CHECK_TABLE(dfa); 431 unsigned int state = start; 432 433 if (state == 0) 434 return 0; 435 436 /* current state is <state>, matching character *str */ 437 if (dfa->tables[YYTD_ID_EC]) { 438 /* Equivalence class table defined */ 439 u8 *equiv = EQUIV_TABLE(dfa); 440 /* default is direct to next state */ 441 while (*str) 442 match_char(state, def, base, next, check, 443 equiv[(u8) *str++]); 444 } else { 445 /* default is direct to next state */ 446 while (*str) 447 match_char(state, def, base, next, check, (u8) *str++); 448 } 449 450 return state; 451 } 452 453 /** 454 * aa_dfa_next - step one character to the next state in the dfa 455 * @dfa: the dfa to tranverse (NOT NULL) 456 * @state: the state to start in 457 * @c: the input character to transition on 458 * 459 * aa_dfa_match will step through the dfa by one input character @c 460 * 461 * Returns: state reach after input @c 462 */ 463 unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, 464 const char c) 465 { 466 u16 *def = DEFAULT_TABLE(dfa); 467 u32 *base = BASE_TABLE(dfa); 468 u16 *next = NEXT_TABLE(dfa); 469 u16 *check = CHECK_TABLE(dfa); 470 471 /* current state is <state>, matching character *str */ 472 if (dfa->tables[YYTD_ID_EC]) { 473 /* Equivalence class table defined */ 474 u8 *equiv = EQUIV_TABLE(dfa); 475 match_char(state, def, base, next, check, equiv[(u8) c]); 476 } else 477 match_char(state, def, base, next, check, (u8) c); 478 479 return state; 480 } 481 482 /** 483 * aa_dfa_match_until - traverse @dfa until accept state or end of input 484 * @dfa: the dfa to match @str against (NOT NULL) 485 * @start: the state of the dfa to start matching in 486 * @str: the null terminated string of bytes to match against the dfa (NOT NULL) 487 * @retpos: first character in str after match OR end of string 488 * 489 * aa_dfa_match will match @str against the dfa and return the state it 490 * finished matching in. The final state can be used to look up the accepting 491 * label, or as the start state of a continuing match. 492 * 493 * Returns: final state reached after input is consumed 494 */ 495 unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start, 496 const char *str, const char **retpos) 497 { 498 u16 *def = DEFAULT_TABLE(dfa); 499 u32 *base = BASE_TABLE(dfa); 500 u16 *next = NEXT_TABLE(dfa); 501 u16 *check = CHECK_TABLE(dfa); 502 u32 *accept = ACCEPT_TABLE(dfa); 503 unsigned int state = start, pos; 504 505 if (state == 0) 506 return 0; 507 508 /* current state is <state>, matching character *str */ 509 if (dfa->tables[YYTD_ID_EC]) { 510 /* Equivalence class table defined */ 511 u8 *equiv = EQUIV_TABLE(dfa); 512 /* default is direct to next state */ 513 while (*str) { 514 pos = base_idx(base[state]) + equiv[(u8) *str++]; 515 if (check[pos] == state) 516 state = next[pos]; 517 else 518 state = def[state]; 519 if (accept[state]) 520 break; 521 } 522 } else { 523 /* default is direct to next state */ 524 while (*str) { 525 pos = base_idx(base[state]) + (u8) *str++; 526 if (check[pos] == state) 527 state = next[pos]; 528 else 529 state = def[state]; 530 if (accept[state]) 531 break; 532 } 533 } 534 535 *retpos = str; 536 return state; 537 } 538 539 540 /** 541 * aa_dfa_matchn_until - traverse @dfa until accept or @n bytes consumed 542 * @dfa: the dfa to match @str against (NOT NULL) 543 * @start: the state of the dfa to start matching in 544 * @str: the string of bytes to match against the dfa (NOT NULL) 545 * @n: length of the string of bytes to match 546 * @retpos: first character in str after match OR str + n 547 * 548 * aa_dfa_match_len will match @str against the dfa and return the state it 549 * finished matching in. The final state can be used to look up the accepting 550 * label, or as the start state of a continuing match. 551 * 552 * This function will happily match again the 0 byte and only finishes 553 * when @n input is consumed. 554 * 555 * Returns: final state reached after input is consumed 556 */ 557 unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start, 558 const char *str, int n, const char **retpos) 559 { 560 u16 *def = DEFAULT_TABLE(dfa); 561 u32 *base = BASE_TABLE(dfa); 562 u16 *next = NEXT_TABLE(dfa); 563 u16 *check = CHECK_TABLE(dfa); 564 u32 *accept = ACCEPT_TABLE(dfa); 565 unsigned int state = start, pos; 566 567 *retpos = NULL; 568 if (state == 0) 569 return 0; 570 571 /* current state is <state>, matching character *str */ 572 if (dfa->tables[YYTD_ID_EC]) { 573 /* Equivalence class table defined */ 574 u8 *equiv = EQUIV_TABLE(dfa); 575 /* default is direct to next state */ 576 for (; n; n--) { 577 pos = base_idx(base[state]) + equiv[(u8) *str++]; 578 if (check[pos] == state) 579 state = next[pos]; 580 else 581 state = def[state]; 582 if (accept[state]) 583 break; 584 } 585 } else { 586 /* default is direct to next state */ 587 for (; n; n--) { 588 pos = base_idx(base[state]) + (u8) *str++; 589 if (check[pos] == state) 590 state = next[pos]; 591 else 592 state = def[state]; 593 if (accept[state]) 594 break; 595 } 596 } 597 598 *retpos = str; 599 return state; 600 } 601