aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2009-11-24 08:00:05 -0500
committerJames Morris <jmorris@namei.org>2009-11-25 02:51:16 -0500
commit7539cf4b92be4aecc573ea962135f246a7a33401 (patch)
tree6ed5ada6206e788e937ce1325a70a9d6fb0d3c2f
parentb3a222e52e4d4be77cc4520a57af1a4a0d8222d1 (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.c200
-rw-r--r--security/tomoyo/common.h4
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 */
372static 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 */
461static bool tomoyo_file_matches_to_pattern2(const char *filename, 459static 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 */
579static bool to