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

tomoyo: Limit wildcard recursion depth.

Since wildcards that need recursion consume kernel stack memory (or might
cause CPU stall warning problem), we cannot allow infinite recursion.

Since TOMOYO 1.8 survived with 20 recursions limit for 5 years, nobody
would complain if applying this limit to TOMOYO 2.6.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

+30 -25
+30 -25
security/tomoyo/util.c
··· 434 434 */ 435 435 static bool tomoyo_correct_word2(const char *string, size_t len) 436 436 { 437 + u8 recursion = 20; 437 438 const char *const start = string; 438 439 bool in_repetition = false; 439 - unsigned char c; 440 - unsigned char d; 441 - unsigned char e; 442 440 443 441 if (!len) 444 442 goto out; 445 443 while (len--) { 446 - c = *string++; 444 + unsigned char c = *string++; 445 + 447 446 if (c == '\\') { 448 447 if (!len--) 449 448 goto out; 450 449 c = *string++; 450 + if (c >= '0' && c <= '3') { 451 + unsigned char d; 452 + unsigned char e; 453 + 454 + if (!len-- || !len--) 455 + goto out; 456 + d = *string++; 457 + e = *string++; 458 + if (d < '0' || d > '7' || e < '0' || e > '7') 459 + goto out; 460 + c = tomoyo_make_byte(c, d, e); 461 + if (c <= ' ' || c >= 127) 462 + continue; 463 + goto out; 464 + } 451 465 switch (c) { 452 466 case '\\': /* "\\" */ 453 - continue; 454 - case '$': /* "\$" */ 455 467 case '+': /* "\+" */ 456 468 case '?': /* "\?" */ 469 + case 'x': /* "\x" */ 470 + case 'a': /* "\a" */ 471 + case '-': /* "\-" */ 472 + continue; 473 + } 474 + if (!recursion--) 475 + goto out; 476 + switch (c) { 457 477 case '*': /* "\*" */ 458 478 case '@': /* "\@" */ 459 - case 'x': /* "\x" */ 479 + case '$': /* "\$" */ 460 480 case 'X': /* "\X" */ 461 - case 'a': /* "\a" */ 462 481 case 'A': /* "\A" */ 463 - case '-': /* "\-" */ 464 482 continue; 465 483 case '{': /* "/\{" */ 466 484 if (string - 3 < start || *(string - 3) != '/') 467 - break; 485 + goto out; 468 486 in_repetition = true; 469 487 continue; 470 488 case '}': /* "\}/" */ 471 489 if (*string != '/') 472 - break; 490 + goto out; 473 491 if (!in_repetition) 474 - break; 492 + goto out; 475 493 in_repetition = false; 476 494 continue; 477 - case '0': /* "\ooo" */ 478 - case '1': 479 - case '2': 480 - case '3': 481 - if (!len-- || !len--) 482 - break; 483 - d = *string++; 484 - e = *string++; 485 - if (d < '0' || d > '7' || e < '0' || e > '7') 486 - break; 487 - c = tomoyo_make_byte(c, d, e); 488 - if (c <= ' ' || c >= 127) 489 - continue; 490 495 } 491 496 goto out; 492 497 } else if (in_repetition && c == '/') {