diff options
| author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2009-11-24 08:00:05 -0500 |
|---|---|---|
| committer | James Morris <jmorris@namei.org> | 2009-11-25 02:51:16 -0500 |
| commit | 7539cf4b92be4aecc573ea962135f246a7a33401 (patch) | |
| tree | 6ed5ada6206e788e937ce1325a70a9d6fb0d3c2f | |
| parent | b3a222e52e4d4be77cc4520a57af1a4a0d8222d1 (diff) | |
TOMOYO: Add recursive directory matching operator support.
TOMOYO 1.7.1 has recursive directory matching operator support.
I want to add it to TOMOYO for Linux 2.6.33 .
----------
[PATCH] TOMOYO: Add recursive directory matching operator support.
This patch introduces new operator /\{dir\}/ which matches
'/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/ /dir/dir/dir/ ).
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: James Morris <jmorris@namei.org>
| -rw-r--r-- | security/tomoyo/common.c | 200 | ||||
| -rw-r--r-- | security/tomoyo/common.h | 4 |
2 files changed, 121 insertions, 83 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 3c8bd8ee0b95..e0d0354008b7 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
| @@ -187,6 +187,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | |||
| 187 | const s8 pattern_type, const s8 end_type, | 187 | const s8 pattern_type, const s8 end_type, |
| 188 | const char *function) | 188 | const char *function) |
| 189 | { | 189 | { |
| 190 | const char *const start = filename; | ||
| 191 | bool in_repetition = false; | ||
| 190 | bool contains_pattern = false; | 192 | bool contains_pattern = false; |
| 191 | unsigned char c; | 193 | unsigned char c; |
| 192 | unsigned char d; | 194 | unsigned char d; |
| @@ -212,9 +214,13 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | |||
| 212 | if (c == '/') | 214 | if (c == '/') |
| 213 | goto out; | 215 | goto out; |
| 214 | } | 216 | } |
| 215 | while ((c = *filename++) != '\0') { | 217 | while (1) { |
| 218 | c = *filename++; | ||
| 219 | if (!c) | ||
| 220 | break; | ||
| 216 | if (c == '\\') { | 221 | if (c == '\\') { |
| 217 | switch ((c = *filename++)) { | 222 | c = *filename++; |
| 223 | switch (c) { | ||
| 218 | case '\\': /* "\\" */ | 224 | case '\\': /* "\\" */ |
| 219 | continue; | 225 | continue; |
| 220 | case '$': /* "\$" */ | 226 | case '$': /* "\$" */ |
| @@ -231,6 +237,22 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | |||
| 231 | break; /* Must not contain pattern */ | 237 | break; /* Must not contain pattern */ |
| 232 | contains_pattern = true; | 238 | contains_pattern = true; |
| 233 | continue; | 239 | continue; |
| 240 | case '{': /* "/\{" */ | ||
| 241 | if (filename - 3 < start || | ||
| 242 | *(filename - 3) != '/') | ||
| 243 | break; | ||
| 244 | if (pattern_type == -1) | ||
| 245 | break; /* Must not contain pattern */ | ||
| 246 | contains_pattern = true; | ||
| 247 | in_repetition = true; | ||
| 248 | continue; | ||
| 249 | case '}': /* "\}/" */ | ||
| 250 | if (*filename != '/') | ||
| 251 | break; | ||
| 252 | if (!in_repetition) | ||
| 253 | break; | ||
| 254 | in_repetition = false; | ||
| 255 | continue; | ||
| 234 | case '0': /* "\ooo" */ | 256 | case '0': /* "\ooo" */ |
| 235 | case '1': | 257 | case '1': |
| 236 | case '2': | 258 | case '2': |
| @@ -246,6 +268,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | |||
| 246 | continue; /* pattern is not \000 */ | 268 | continue; /* pattern is not \000 */ |
| 247 | } | 269 | } |
| 248 | goto out; | 270 | goto out; |
| 271 | } else if (in_repetition && c == '/') { | ||
| 272 | goto out; | ||
| 249 | } else if (tomoyo_is_invalid(c)) { | 273 | } else if (tomoyo_is_invalid(c)) { |
| 250 | goto out; | 274 | goto out; |
| 251 | } | 275 | } |
| @@ -254,6 +278,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, | |||
| 254 | if (!contains_pattern) | 278 | if (!contains_pattern) |
| 255 | goto out; | 279 | goto out; |
| 256 | } | 280 | } |
| 281 | if (in_repetition) | ||
| 282 | goto out; | ||
| 257 | return true; | 283 | return true; |
| 258 | out: | 284 | out: |
| 259 | printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, | 285 | printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function, |
| @@ -360,33 +386,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) | |||
| 360 | } | 386 | } |
| 361 | 387 | ||
| 362 | /** | 388 | /** |
| 363 | * tomoyo_path_depth - Evaluate the number of '/' in a string. | ||
| 364 | * | ||
| 365 | * @pathname: The string to evaluate. | ||
| 366 | * | ||
| 367 | * Returns path depth of the string. | ||
| 368 | * | ||
| 369 | * I score 2 for each of the '/' in the @pathname | ||
| 370 | * and score 1 if the @pathname ends with '/'. | ||
| 371 | */ | ||
| 372 | static int tomoyo_path_depth(const char *pathname) | ||
| 373 | { | ||
| 374 | int i = 0; | ||
| 375 | |||
| 376 | if (pathname) { | ||
| 377 | const char *ep = pathname + strlen(pathname); | ||
| 378 | if (pathname < ep--) { | ||
| 379 | if (*ep != '/') | ||
| 380 | i++; | ||
| 381 | while (pathname <= ep) | ||
| 382 | if (*ep-- == '/') | ||
| 383 | i += 2; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | return i; | ||
| 387 | } | ||
| 388 | |||
| 389 | /** | ||
| 390 | * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. | 389 | * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. |
| 391 | * | 390 | * |
| 392 | * @filename: The string to evaluate. | 391 | * @filename: The string to evaluate. |
| @@ -444,11 +443,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) | |||
| 444 | ptr->is_dir = len && (name[len - 1] == '/'); | 443 | ptr->is_dir = len && (name[len - 1] == '/'); |
| 445 | ptr->is_patterned = (ptr->const_len < len); | 444 | ptr->is_patterned = (ptr->const_len < len); |
| 446 | ptr->hash = full_name_hash(name, len); | 445 | ptr->hash = full_name_hash(name, len); |
| 447 | ptr->depth = tomoyo_path_depth(name); | ||
| 448 | } | 446 | } |
| 449 | 447 | ||
| 450 | /** | 448 | /** |
| 451 | * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character | 449 | * tomoyo_file_matches_pattern2 - Pattern matching without '/' character |
| 452 | * and "\-" pattern. | 450 | * and "\-" pattern. |
| 453 | * | 451 | * |
| 454 | * @filename: The start of string to check. | 452 | * @filename: The start of string to check. |
| @@ -458,10 +456,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr) | |||
| 458 | * | 456 | * |
| 459 | * Returns true if @filename matches @pattern, false otherwise. | 457 | * Returns true if @filename matches @pattern, false otherwise. |
| 460 | */ | 458 | */ |
| 461 | static bool tomoyo_file_matches_to_pattern2(const char *filename, | 459 | static bool tomoyo_file_matches_pattern2(const char *filename, |
| 462 | const char *filename_end, | 460 | const char *filename_end, |
| 463 | const char *pattern, | 461 | const char *pattern, |
| 464 | const char *pattern_end) | 462 | const char *pattern_end) |
| 465 | { | 463 | { |
| 466 | while (filename < filename_end && pattern < pattern_end) { | 464 | while (filename < filename_end && pattern < pattern_end) { |
| 467 | char c; | 465 | char c; |
| @@ -519,7 +517,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename, | |||
| 519 | case '*': | 517 | case '*': |
| 520 | case '@': | 518 | case '@': |
| 521 | for (i = 0; i <= filename_end - filename; i++) { | 519 | for (i = 0; i <= filename_end - filename; i++) { |
| 522 | if (tomoyo_file_matches_to_pattern2( | 520 | if (tomoyo_file_matches_pattern2( |
| 523 | filename + i, filename_end, | 521 | filename + i, filename_end, |
| 524 | pattern + 1, pattern_end)) | 522 | pattern + 1, pattern_end)) |
| 525 | return true; | 523 | return true; |
| @@ -550,7 +548,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename, | |||
| 550 | j++; | 548 | j++; |
| 551 | } | 549 | } |
| 552 | for (i = 1; i <= j; i++) { | 550 | for (i = 1; i <= j; i++) { |
| 553 | if (tomoyo_file_matches_to_pattern2( | 551 | if (tomoyo_file_matches_pattern2( |
| 554 | filename + i, filename_end, | 552 | filename + i, filename_end, |
| 555 | pattern + 1, pattern_end)) | 553 | pattern + 1, pattern_end)) |
| 556 | return true; | 554 | return true; |
| @@ -567,7 +565,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename, | |||
| 567 | } | 565 | } |
| 568 | 566 | ||
| 569 | /** | 567 | /** |
| 570 | * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character. | 568 | * tomoyo_file_matches_pattern - Pattern matching without without '/' character. |
| 571 | * | 569 | * |
| 572 | * @filename: The start of string to check. | 570 | * @filename: The start of string to check. |
| 573 | * @filename_end: The end of string to check. | 571 | * @filename_end: The end of string to check. |
| @@ -576,7 +574,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename, | |||
| 576 | * | 574 | * |
| 577 | * Returns true if @filename matches @pattern, false otherwise. | 575 | * Returns true if @filename matches @pattern, false otherwise. |
| 578 | */ | 576 | */ |
| 579 | static bool to | ||
