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/apparmor.h" 24#include "include/match.h" 25 26#define base_idx(X) ((X) & 0xffffff) 27 28/** 29 * unpack_table - unpack a dfa table (one of accept, default, base, next check) 30 * @blob: data to unpack (NOT NULL) 31 * @bsize: size of blob 32 * 33 * Returns: pointer to table else NULL on failure 34 * 35 * NOTE: must be freed by kvfree (not kfree) 36 */ 37static struct table_header *unpack_table(char *blob, size_t bsize) 38{ 39 struct table_header *table = NULL; 40 struct table_header th; 41 size_t tsize; 42 43 if (bsize < sizeof(struct table_header)) 44 goto out; 45 46 /* loaded td_id's start at 1, subtract 1 now to avoid doing 47 * it every time we use td_id as an index 48 */ 49 th.td_id = be16_to_cpu(*(u16 *) (blob)) - 1; 50 th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); 51 th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); 52 blob += sizeof(struct table_header); 53 54 if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || 55 th.td_flags == YYTD_DATA8)) 56 goto out; 57 58 tsize = table_size(th.td_lolen, th.td_flags); 59 if (bsize < tsize) 60 goto out; 61 62 table = kvzalloc(tsize); 63 if (table) { 64 *table = th; 65 if (th.td_flags == YYTD_DATA8) 66 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 67 u8, byte_to_byte); 68 else if (th.td_flags == YYTD_DATA16) 69 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 70 u16, be16_to_cpu); 71 else if (th.td_flags == YYTD_DATA32) 72 UNPACK_ARRAY(table->td_data, blob, th.td_lolen, 73 u32, be32_to_cpu); 74 else 75 goto fail; 76 } 77 78out: 79 /* if table was vmalloced make sure the page tables are synced 80 * before it is used, as it goes live to all cpus. 81 */ 82 if (is_vmalloc_addr(table)) 83 vm_unmap_aliases(); 84 return table; 85fail: 86 kvfree(table); 87 return NULL; 88} 89 90/** 91 * verify_dfa - verify that transitions and states in the tables are in bounds. 92 * @dfa: dfa to test (NOT NULL) 93 * @flags: flags controlling what type of accept table are acceptable 94 * 95 * Assumes dfa has gone through the first pass verification done by unpacking 96 * NOTE: this does not valid accept table values 97 * 98 * Returns: %0 else error code on failure to verify 99 */ 100static int verify_dfa(struct aa_dfa *dfa, int flags) 101{ 102 size_t i, state_count, trans_count; 103 int error = -EPROTO; 104 105 /* check that required tables exist */ 106 if (!(dfa->tables[YYTD_ID_DEF] && 107 dfa->tables[YYTD_ID_BASE] && 108 dfa->tables[YYTD_ID_NXT] && dfa->tables[YYTD_ID_CHK])) 109 goto out; 110 111 /* accept.size == default.size == base.size */ 112 state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; 113 if (ACCEPT1_FLAGS(flags)) { 114 if (!dfa->tables[YYTD_ID_ACCEPT]) 115 goto out; 116 if (state_count != dfa->tables[YYTD_ID_ACCEPT]->td_lolen) 117 goto out; 118 } 119 if (ACCEPT2_FLAGS(flags)) { 120 if (!dfa->tables[YYTD_ID_ACCEPT2]) 121 goto out; 122 if (state_count != dfa->tables[YYTD_ID_ACCEPT2]->td_lolen) 123 goto out; 124 } 125 if (state_count != dfa->tables[YYTD_ID_DEF]->td_lolen) 126 goto out; 127 128 /* next.size == chk.size */ 129 trans_count = dfa->tables[YYTD_ID_NXT]->td_lolen; 130 if (trans_count != dfa->tables[YYTD_ID_CHK]->td_lolen) 131 goto out; 132 133 /* if equivalence classes then its table size must be 256 */ 134 if (dfa->tables[YYTD_ID_EC] && 135 dfa->tables[YYTD_ID_EC]->td_lolen != 256) 136 goto out; 137 138 if (flags & DFA_FLAG_VERIFY_STATES) { 139 for (i = 0; i < state_count; i++) { 140 if (DEFAULT_TABLE(dfa)[i] >= state_count) 141 goto out; 142 if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { 143 printk(KERN_ERR "AppArmor DFA next/check upper " 144 "bounds error\n"); 145 goto out; 146 } 147 } 148 149 for (i = 0; i < trans_count; i++) { 150 if (NEXT_TABLE(dfa)[i] >= state_count) 151 goto out; 152 if (CHECK_TABLE(dfa)[i] >= state_count) 153 goto out; 154 } 155 } 156 157 error = 0; 158out: 159 return error; 160} 161 162/** 163 * dfa_free - free a dfa allocated by aa_dfa_unpack 164 * @dfa: the dfa to free (MAYBE NULL) 165 * 166 * Requires: reference count to dfa == 0 167 */ 168static void dfa_free(struct aa_dfa *dfa) 169{ 170 if (dfa) { 171 int i; 172 173 for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { 174 kvfree(dfa->tables[i]); 175 dfa->tables[i] = NULL; 176 } 177 kfree(dfa); 178 } 179} 180 181/** 182 * aa_dfa_free_kref - free aa_dfa by kref (called by aa_put_dfa) 183 * @kr: kref callback for freeing of a dfa (NOT NULL) 184 */ 185void aa_dfa_free_kref(struct kref *kref) 186{ 187 struct aa_dfa *dfa = container_of(kref, struct aa_dfa, count); 188 dfa_free(dfa); 189} 190 191/** 192 * aa_dfa_unpack - unpack the binary tables of a serialized dfa 193 * @blob: aligned serialized stream of data to unpack (NOT NULL) 194 * @size: size of data to unpack 195 * @flags: flags controlling what type of accept tables are acceptable 196 * 197 * Unpack a dfa that has been serialized. To find information on the dfa 198 * format look in Documentation/security/apparmor.txt 199 * Assumes the dfa @blob stream has been aligned on a 8 byte boundary 200 * 201 * Returns: an unpacked dfa ready for matching or ERR_PTR on failure 202 */ 203struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) 204{ 205 int hsize; 206 int error = -ENOMEM; 207 char *data = blob; 208 struct table_header *table = NULL; 209 struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); 210 if (!dfa) 211 goto fail; 212 213 kref_init(&dfa->count); 214 215 error = -EPROTO; 216 217 /* get dfa table set header */ 218 if (size < sizeof(struct table_set_header)) 219 goto fail; 220 221 if (ntohl(*(u32 *) data) != YYTH_MAGIC) 222 goto fail; 223 224 hsize = ntohl(*(u32 *) (data + 4)); 225 if (size < hsize) 226 goto fail; 227 228 dfa->flags = ntohs(*(u16 *) (data + 12)); 229 data += hsize; 230 size -= hsize; 231 232 while (size > 0) { 233 table = unpack_table(data, size); 234 if (!table) 235 goto fail; 236 237 switch (table->td_id) { 238 case YYTD_ID_ACCEPT: 239 if (!(table->td_flags & ACCEPT1_FLAGS(flags))) 240 goto fail; 241 break; 242 case YYTD_ID_ACCEPT2: 243 if (!(table->td_flags & ACCEPT2_FLAGS(flags))) 244 goto fail; 245 break; 246 case YYTD_ID_BASE: 247 if (table->td_flags != YYTD_DATA32) 248 goto fail; 249 break; 250 case YYTD_ID_DEF: 251 case YYTD_ID_NXT: 252 case YYTD_ID_CHK: 253 if (table->td_flags != YYTD_DATA16) 254 goto fail; 255 break; 256 case YYTD_ID_EC: 257 if (table->td_flags != YYTD_DATA8) 258 goto fail; 259 break; 260 default: 261 goto fail; 262 } 263 /* check for duplicate table entry */ 264 if (dfa->tables[table->td_id]) 265 goto fail; 266 dfa->tables[table->td_id] = table; 267 data += table_size(table->td_lolen, table->td_flags); 268 size -= table_size(table->td_lolen, table->td_flags); 269 table = NULL; 270 } 271 272 error = verify_dfa(dfa, flags); 273 if (error) 274 goto fail; 275 276 return dfa; 277 278fail: 279 kvfree(table); 280 dfa_free(dfa); 281 return ERR_PTR(error); 282} 283 284/** 285 * aa_dfa_match_len - traverse @dfa to find state @str stops at 286 * @dfa: the dfa to match @str against (NOT NULL) 287 * @start: the state of the dfa to start matching in 288 * @str: the string of bytes to match against the dfa (NOT NULL) 289 * @len: length of the string of bytes to match 290 * 291 * aa_dfa_match_len will match @str against the dfa and return the state it 292 * finished matching in. The final state can be used to look up the accepting 293 * label, or as the start state of a continuing match. 294 * 295 * This function will happily match again the 0 byte and only finishes 296 * when @len input is consumed. 297 * 298 * Returns: final state reached after input is consumed 299 */ 300unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, 301 const char *str, int len) 302{ 303 u16 *def = DEFAULT_TABLE(dfa); 304 u32 *base = BASE_TABLE(dfa); 305 u16 *next = NEXT_TABLE(dfa); 306 u16 *check = CHECK_TABLE(dfa); 307 unsigned int state = start, pos; 308 309 if (state == 0) 310 return 0; 311 312 /* current state is <state>, matching character *str */ 313 if (dfa->tables[YYTD_ID_EC]) { 314 /* Equivalence class table defined */ 315 u8 *equiv = EQUIV_TABLE(dfa); 316 /* default is direct to next state */ 317 for (; len; len--) { 318 pos = base_idx(base[state]) + equiv[(u8) *str++]; 319 if (check[pos] == state) 320 state = next[pos]; 321 else 322 state = def[state]; 323 } 324 } else { 325 /* default is direct to next state */ 326 for (; len; len--) { 327 pos = base_idx(base[state]) + (u8) *str++; 328 if (check[pos] == state) 329 state = next[pos]; 330 else 331 state = def[state]; 332 } 333 } 334 335 return state; 336} 337 338/** 339 * aa_dfa_match - traverse @dfa to find state @str stops at 340 * @dfa: the dfa to match @str against (NOT NULL) 341 * @start: the state of the dfa to start matching in 342 * @str: the null terminated string of bytes to match against the dfa (NOT NULL) 343 * 344 * aa_dfa_match will match @str against the dfa and return the state it 345 * finished matching in. The final state can be used to look up the accepting 346 * label, or as the start state of a continuing match. 347 * 348 * Returns: final state reached after input is consumed 349 */ 350unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, 351 const char *str) 352{ 353 u16 *def = DEFAULT_TABLE(dfa); 354 u32 *base = BASE_TABLE(dfa); 355 u16 *next = NEXT_TABLE(dfa); 356 u16 *check = CHECK_TABLE(dfa); 357 unsigned int state = start, pos; 358 359 if (state == 0) 360 return 0; 361 362 /* current state is <state>, matching character *str */ 363 if (dfa->tables[YYTD_ID_EC]) { 364 /* Equivalence class table defined */ 365 u8 *equiv = EQUIV_TABLE(dfa); 366 /* default is direct to next state */ 367 while (*str) { 368 pos = base_idx(base[state]) + equiv[(u8) *str++]; 369 if (check[pos] == state) 370 state = next[pos]; 371 else 372 state = def[state]; 373 } 374 } else { 375 /* default is direct to next state */ 376 while (*str) { 377 pos = base_idx(base[state]) + (u8) *str++; 378 if (check[pos] == state) 379 state = next[pos]; 380 else 381 state = def[state]; 382 } 383 } 384 385 return state; 386} 387 388/** 389 * aa_dfa_next - step one character to the next state in the dfa 390 * @dfa: the dfa to tranverse (NOT NULL) 391 * @state: the state to start in 392 * @c: the input character to transition on 393 * 394 * aa_dfa_match will step through the dfa by one input character @c 395 * 396 * Returns: state reach after input @c 397 */ 398unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, 399 const char c) 400{ 401 u16 *def = DEFAULT_TABLE(dfa); 402 u32 *base = BASE_TABLE(dfa); 403 u16 *next = NEXT_TABLE(dfa); 404 u16 *check = CHECK_TABLE(dfa); 405 unsigned int pos; 406 407 /* current state is <state>, matching character *str */ 408 if (dfa->tables[YYTD_ID_EC]) { 409 /* Equivalence class table defined */ 410 u8 *equiv = EQUIV_TABLE(dfa); 411 /* default is direct to next state */ 412 413 pos = base_idx(base[state]) + equiv[(u8) c]; 414 if (check[pos] == state) 415 state = next[pos]; 416 else 417 state = def[state]; 418 } else { 419 /* default is direct to next state */ 420 pos = base_idx(base[state]) + (u8) c; 421 if (check[pos] == state) 422 state = next[pos]; 423 else 424 state = def[state]; 425 } 426 427 return state; 428} 429