Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

apparmor: reserve and mask off the top 8 bits of the base field

The top 8 bits of the base field have never been used, in fact can't
be used, by the current 'dfa16' format. However they will be used in the
future as flags, so mask them off when using base as an index value.

Note: the use of the top 8 bits, without masking is trapped by the verify
checks that base entries are within the size bounds.

Signed-off-by: John Johansen <john.johansen@canonical.com>
Acked-by: Kees Cook <kees@ubuntu.com>

+9 -7
+9 -7
security/apparmor/match.c
··· 23 23 #include "include/apparmor.h" 24 24 #include "include/match.h" 25 25 26 + #define base_idx(X) ((X) & 0xffffff) 27 + 26 28 /** 27 29 * unpack_table - unpack a dfa table (one of accept, default, base, next check) 28 30 * @blob: data to unpack (NOT NULL) ··· 139 137 for (i = 0; i < state_count; i++) { 140 138 if (DEFAULT_TABLE(dfa)[i] >= state_count) 141 139 goto out; 142 - if (BASE_TABLE(dfa)[i] + 255 >= trans_count) { 140 + if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) { 143 141 printk(KERN_ERR "AppArmor DFA next/check upper " 144 142 "bounds error\n"); 145 143 goto out; ··· 315 313 u8 *equiv = EQUIV_TABLE(dfa); 316 314 /* default is direct to next state */ 317 315 for (; len; len--) { 318 - pos = base[state] + equiv[(u8) *str++]; 316 + pos = base_idx(base[state]) + equiv[(u8) *str++]; 319 317 if (check[pos] == state) 320 318 state = next[pos]; 321 319 else ··· 324 322 } else { 325 323 /* default is direct to next state */ 326 324 for (; len; len--) { 327 - pos = base[state] + (u8) *str++; 325 + pos = base_idx(base[state]) + (u8) *str++; 328 326 if (check[pos] == state) 329 327 state = next[pos]; 330 328 else ··· 365 363 u8 *equiv = EQUIV_TABLE(dfa); 366 364 /* default is direct to next state */ 367 365 while (*str) { 368 - pos = base[state] + equiv[(u8) *str++]; 366 + pos = base_idx(base[state]) + equiv[(u8) *str++]; 369 367 if (check[pos] == state) 370 368 state = next[pos]; 371 369 else ··· 374 372 } else { 375 373 /* default is direct to next state */ 376 374 while (*str) { 377 - pos = base[state] + (u8) *str++; 375 + pos = base_idx(base[state]) + (u8) *str++; 378 376 if (check[pos] == state) 379 377 state = next[pos]; 380 378 else ··· 410 408 u8 *equiv = EQUIV_TABLE(dfa); 411 409 /* default is direct to next state */ 412 410 413 - pos = base[state] + equiv[(u8) c]; 411 + pos = base_idx(base[state]) + equiv[(u8) c]; 414 412 if (check[pos] == state) 415 413 state = next[pos]; 416 414 else 417 415 state = def[state]; 418 416 } else { 419 417 /* default is direct to next state */ 420 - pos = base[state] + (u8) c; 418 + pos = base_idx(base[state]) + (u8) c; 421 419 if (check[pos] == state) 422 420 state = next[pos]; 423 421 else