Commit ed686308c6837ff67f56e4115d0fd6bdc65a4313

Authored by John Johansen
1 parent 4da05cc08d

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>

Showing 1 changed file with 9 additions and 7 deletions Side-by-side Diff

security/apparmor/match.c
... ... @@ -23,6 +23,8 @@
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)
... ... @@ -137,7 +139,7 @@
137 139 for (i = 0; i < state_count; i++) {
138 140 if (DEFAULT_TABLE(dfa)[i] >= state_count)
139 141 goto out;
140   - if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
  142 + if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
141 143 printk(KERN_ERR "AppArmor DFA next/check upper "
142 144 "bounds error\n");
143 145 goto out;
... ... @@ -313,7 +315,7 @@
313 315 u8 *equiv = EQUIV_TABLE(dfa);
314 316 /* default is direct to next state */
315 317 for (; len; len--) {
316   - pos = base[state] + equiv[(u8) *str++];
  318 + pos = base_idx(base[state]) + equiv[(u8) *str++];
317 319 if (check[pos] == state)
318 320 state = next[pos];
319 321 else
... ... @@ -322,7 +324,7 @@
322 324 } else {
323 325 /* default is direct to next state */
324 326 for (; len; len--) {
325   - pos = base[state] + (u8) *str++;
  327 + pos = base_idx(base[state]) + (u8) *str++;
326 328 if (check[pos] == state)
327 329 state = next[pos];
328 330 else
... ... @@ -363,7 +365,7 @@
363 365 u8 *equiv = EQUIV_TABLE(dfa);
364 366 /* default is direct to next state */
365 367 while (*str) {
366   - pos = base[state] + equiv[(u8) *str++];
  368 + pos = base_idx(base[state]) + equiv[(u8) *str++];
367 369 if (check[pos] == state)
368 370 state = next[pos];
369 371 else
... ... @@ -372,7 +374,7 @@
372 374 } else {
373 375 /* default is direct to next state */
374 376 while (*str) {
375   - pos = base[state] + (u8) *str++;
  377 + pos = base_idx(base[state]) + (u8) *str++;
376 378 if (check[pos] == state)
377 379 state = next[pos];
378 380 else
379 381  
... ... @@ -408,14 +410,14 @@
408 410 u8 *equiv = EQUIV_TABLE(dfa);
409 411 /* default is direct to next state */
410 412  
411   - pos = base[state] + equiv[(u8) c];
  413 + pos = base_idx(base[state]) + equiv[(u8) c];
412 414 if (check[pos] == state)
413 415 state = next[pos];
414 416 else
415 417 state = def[state];
416 418 } else {
417 419 /* default is direct to next state */
418   - pos = base[state] + (u8) c;
  420 + pos = base_idx(base[state]) + (u8) c;
419 421 if (check[pos] == state)
420 422 state = next[pos];
421 423 else