All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] TOMOYO: Add recursive directory matching operator support.
@ 2009-11-24 13:00 Tetsuo Handa
  2009-11-24 23:37 ` John Johansen
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Tetsuo Handa @ 2009-11-24 13:00 UTC (permalink / raw)
  To: linux-security-module; +Cc: linux-kernel

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>
---
 security/tomoyo/common.c |  200 ++++++++++++++++++++++++++++-------------------
 security/tomoyo/common.h |    4 
 2 files changed, 121 insertions(+), 83 deletions(-)

--- security-testing-2.6.orig/security/tomoyo/common.c
+++ security-testing-2.6/security/tomoyo/common.c
@@ -187,6 +187,8 @@ bool tomoyo_is_correct_path(const char *
 			    const s8 pattern_type, const s8 end_type,
 			    const char *function)
 {
+	const char *const start = filename;
+	bool in_repetition = false;
 	bool contains_pattern = false;
 	unsigned char c;
 	unsigned char d;
@@ -212,9 +214,13 @@ bool tomoyo_is_correct_path(const char *
 		if (c == '/')
 			goto out;
 	}
-	while ((c = *filename++) != '\0') {
+	while (1) {
+		c = *filename++;
+		if (!c)
+			break;
 		if (c == '\\') {
-			switch ((c = *filename++)) {
+			c = *filename++;
+			switch (c) {
 			case '\\':  /* "\\" */
 				continue;
 			case '$':   /* "\$" */
@@ -231,6 +237,22 @@ bool tomoyo_is_correct_path(const char *
 					break; /* Must not contain pattern */
 				contains_pattern = true;
 				continue;
+			case '{':   /* "/\{" */
+				if (filename - 3 < start ||
+				    *(filename - 3) != '/')
+					break;
+				if (pattern_type == -1)
+					break; /* Must not contain pattern */
+				contains_pattern = true;
+				in_repetition = true;
+				continue;
+			case '}':   /* "\}/" */
+				if (*filename != '/')
+					break;
+				if (!in_repetition)
+					break;
+				in_repetition = false;
+				continue;
 			case '0':   /* "\ooo" */
 			case '1':
 			case '2':
@@ -246,6 +268,8 @@ bool tomoyo_is_correct_path(const char *
 					continue; /* pattern is not \000 */
 			}
 			goto out;
+		} else if (in_repetition && c == '/') {
+			goto out;
 		} else if (tomoyo_is_invalid(c)) {
 			goto out;
 		}
@@ -254,6 +278,8 @@ bool tomoyo_is_correct_path(const char *
 		if (!contains_pattern)
 			goto out;
 	}
+	if (in_repetition)
+		goto out;
 	return true;
  out:
 	printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
@@ -360,33 +386,6 @@ struct tomoyo_domain_info *tomoyo_find_d
 }
 
 /**
- * tomoyo_path_depth - Evaluate the number of '/' in a string.
- *
- * @pathname: The string to evaluate.
- *
- * Returns path depth of the string.
- *
- * I score 2 for each of the '/' in the @pathname
- * and score 1 if the @pathname ends with '/'.
- */
-static int tomoyo_path_depth(const char *pathname)
-{
-	int i = 0;
-
-	if (pathname) {
-		const char *ep = pathname + strlen(pathname);
-		if (pathname < ep--) {
-			if (*ep != '/')
-				i++;
-			while (pathname <= ep)
-				if (*ep-- == '/')
-					i += 2;
-		}
-	}
-	return i;
-}
-
-/**
  * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
  *
  * @filename: The string to evaluate.
@@ -444,11 +443,10 @@ void tomoyo_fill_path_info(struct tomoyo
 	ptr->is_dir = len && (name[len - 1] == '/');
 	ptr->is_patterned = (ptr->const_len < len);
 	ptr->hash = full_name_hash(name, len);
-	ptr->depth = tomoyo_path_depth(name);
 }
 
 /**
- * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character
+ * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
  * and "\-" pattern.
  *
  * @filename:     The start of string to check.
@@ -458,10 +456,10 @@ void tomoyo_fill_path_info(struct tomoyo
  *
  * Returns true if @filename matches @pattern, false otherwise.
  */
-static bool tomoyo_file_matches_to_pattern2(const char *filename,
-					    const char *filename_end,
-					    const char *pattern,
-					    const char *pattern_end)
+static bool tomoyo_file_matches_pattern2(const char *filename,
+					 const char *filename_end,
+					 const char *pattern,
+					 const char *pattern_end)
 {
 	while (filename < filename_end && pattern < pattern_end) {
 		char c;
@@ -519,7 +517,7 @@ static bool tomoyo_file_matches_to_patte
 		case '*':
 		case '@':
 			for (i = 0; i <= filename_end - filename; i++) {
-				if (tomoyo_file_matches_to_pattern2(
+				if (tomoyo_file_matches_pattern2(
 						    filename + i, filename_end,
 						    pattern + 1, pattern_end))
 					return true;
@@ -550,7 +548,7 @@ static bool tomoyo_file_matches_to_patte
 					j++;
 			}
 			for (i = 1; i <= j; i++) {
-				if (tomoyo_file_matches_to_pattern2(
+				if (tomoyo_file_matches_pattern2(
 						    filename + i, filename_end,
 						    pattern + 1, pattern_end))
 					return true;
@@ -567,7 +565,7 @@ static bool tomoyo_file_matches_to_patte
 }
 
 /**
- * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character.
+ * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
  *
  * @filename:     The start of string to check.
  * @filename_end: The end of string to check.
@@ -576,7 +574,7 @@ static bool tomoyo_file_matches_to_patte
  *
  * Returns true if @filename matches @pattern, false otherwise.
  */
-static bool tomoyo_file_matches_to_pattern(const char *filename,
+static bool tomoyo_file_matches_pattern(const char *filename,
 					   const char *filename_end,
 					   const char *pattern,
 					   const char *pattern_end)
@@ -589,10 +587,10 @@ static bool tomoyo_file_matches_to_patte
 		/* Split at "\-" pattern. */
 		if (*pattern++ != '\\' || *pattern++ != '-')
 			continue;
-		result = tomoyo_file_matches_to_pattern2(filename,
-							 filename_end,
-							 pattern_start,
-							 pattern - 2);
+		result = tomoyo_file_matches_pattern2(filename,
+						      filename_end,
+						      pattern_start,
+						      pattern - 2);
 		if (first)
 			result = !result;
 		if (result)
@@ -600,13 +598,79 @@ static bool tomoyo_file_matches_to_patte
 		first = false;
 		pattern_start = pattern;
 	}
-	result = tomoyo_file_matches_to_pattern2(filename, filename_end,
-						 pattern_start, pattern_end);
+	result = tomoyo_file_matches_pattern2(filename, filename_end,
+					      pattern_start, pattern_end);
 	return first ? result : !result;
 }
 
 /**
+ * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
+ *
+ * @f: The start of string to check.
+ * @p: The start of pattern to compare.
+ *
+ * Returns true if @f matches @p, false otherwise.
+ */
+static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
+{
+	const char *f_delimiter;
+	const char *p_delimiter;
+
+	while (*f && *p) {
+		f_delimiter = strchr(f, '/');
+		if (!f_delimiter)
+			f_delimiter = f + strlen(f);
+		p_delimiter = strchr(p, '/');
+		if (!p_delimiter)
+			p_delimiter = p + strlen(p);
+		if (*p == '\\' && *(p + 1) == '{')
+			goto recursive;
+		if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
+						 p_delimiter))
+			return false;
+		f = f_delimiter;
+		if (*f)
+			f++;
+		p = p_delimiter;
+		if (*p)
+			p++;
+	}
+	/* Ignore trailing "\*" and "\@" in @pattern. */
+	while (*p == '\\' &&
+	       (*(p + 1) == '*' || *(p + 1) == '@'))
+		p += 2;
+	return !*f && !*p;
+ recursive:
+	/*
+	 * The "\{" pattern is permitted only after '/' character.
+	 * This guarantees that below "*(p - 1)" is safe.
+	 * Also, the "\}" pattern is permitted only before '/' character
+	 * so that "\{" + "\}" pair will not break the "\-" operator.
+	 */
+	if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
+	    *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
+		return false; /* Bad pattern. */
+	do {
+		/* Compare current component with pattern. */
+		if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
+						 p_delimiter - 2))
+			break;
+		/* Proceed to next component. */
+		f = f_delimiter;
+		if (!*f)
+			break;
+		f++;
+		/* Continue comparison. */
+		if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
+			return true;
+		f_delimiter = strchr(f, '/');
+	} while (f_delimiter);
+	return false; /* Not matched. */
+}
+
+/**
  * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
+ *
  * @filename: The filename to check.
  * @pattern:  The pattern to compare.
  *
@@ -615,24 +679,24 @@ static bool tomoyo_file_matches_to_patte
  * The following patterns are available.
  *   \\     \ itself.
  *   \ooo   Octal representation of a byte.
- *   \*     More than or equals to 0 character other than '/'.
- *   \@     More than or equals to 0 character other than '/' or '.'.
+ *   \*     Zero or more repetitions of characters other than '/'.
+ *   \@     Zero or more repetitions of characters other than '/' or '.'.
  *   \?     1 byte character other than '/'.
- *   \$     More than or equals to 1 decimal digit.
+ *   \$     One or more repetitions of decimal digits.
  *   \+     1 decimal digit.
- *   \X     More than or equals to 1 hexadecimal digit.
+ *   \X     One or more repetitions of hexadecimal digits.
  *   \x     1 hexadecimal digit.
- *   \A     More than or equals to 1 alphabet character.
+ *   \A     One or more repetitions of alphabet characters.
  *   \a     1 alphabet character.
+ *
  *   \-     Subtraction operator.
+ *
+ *   /\{dir\}/   '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
+ *               /dir/dir/dir/ ).
  */
 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
 				 const struct tomoyo_path_info *pattern)
 {
-	/*
-	  if (!filename || !pattern)
-	  return false;
-	*/
 	const char *f = filename->name;
 	const char *p = pattern->name;
 	const int len = pattern->const_len;
@@ -640,37 +704,15 @@ bool tomoyo_path_matches_pattern(const s
 	/* If @pattern doesn't contain pattern, I can use strcmp(). */
 	if (!pattern->is_patterned)
 		return !tomoyo_pathcmp(filename, pattern);
-	/* Dont compare if the number of '/' differs. */
-	if (filename->depth != pattern->depth)
+	/* Don't compare directory and non-directory. */
+	if (filename->is_dir != pattern->is_dir)
 		return false;
 	/* Compare the initial length without patterns. */
 	if (strncmp(f, p, len))
 		return false;
 	f += len;
 	p += len;
-	/* Main loop. Compare each directory component. */
-	while (*f && *p) {
-		const char *f_delimiter = strchr(f, '/');
-		const char *p_delimiter = strchr(p, '/');
-		if (!f_delimiter)
-			f_delimiter = f + strlen(f);
-		if (!p_delimiter)
-			p_delimiter = p + strlen(p);
-		if (!tomoyo_file_matches_to_pattern(f, f_delimiter,
-						    p, p_delimiter))
-			return false;
-		f = f_delimiter;
-		if (*f)
-			f++;
-		p = p_delimiter;
-		if (*p)
-			p++;
-	}
-	/* Ignore trailing "\*" and "\@" in @pattern. */
-	while (*p == '\\' &&
-	       (*(p + 1) == '*' || *(p + 1) == '@'))
-		p += 2;
-	return !*f && !*p;
+	return tomoyo_path_matches_pattern2(f, p);
 }
 
 /**
--- security-testing-2.6.orig/security/tomoyo/common.h
+++ security-testing-2.6/security/tomoyo/common.h
@@ -56,9 +56,6 @@ struct tomoyo_page_buffer {
  * (5) "is_patterned" is a bool which is true if "name" contains wildcard
  *     characters, false otherwise. This allows TOMOYO to use "hash" and
  *     strcmp() for string comparison if "is_patterned" is false.
- * (6) "depth" is calculated using the number of "/" characters in "name".
- *     This allows TOMOYO to avoid comparing two pathnames which never match
- *     (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
  */
 struct tomoyo_path_info {
 	const char *name;
@@ -66,7 +63,6 @@ struct tomoyo_path_info {
 	u16 const_len;     /* = tomoyo_const_part_length(name)     */
 	bool is_dir;       /* = tomoyo_strendswith(name, "/")      */
 	bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
-	u16 depth;         /* = tomoyo_path_depth(name)            */
 };
 
 /*

^ permalink raw reply	[flat|nested] 7+ messages in thread
* [TOMOYO #16 00/25] Starting TOMOYO 2.3
@ 2009-10-04 12:49 Tetsuo Handa
  2009-10-04 12:49 ` [TOMOYO #16 01/25] LSM: Add security_path_chmod() and security_path_chown() Tetsuo Handa
  0 siblings, 1 reply; 7+ messages in thread
From: Tetsuo Handa @ 2009-10-04 12:49 UTC (permalink / raw)
  To: linux-security-module; +Cc: linux-kernel

Hello.

This is the beginning of TOMOYO 2.3. TOMOYO 2.2 (which is in kernel 2.6.30 and
later) is terribly lacking in functionality (e.g. no audit logs, no network).
I hope TOMOYO 2.3 can provide practically sufficient functionality.

This patchset provides almost all functionality in TOMOYO 1.7.0 except
(1) DAC before MAC checks for directory modification operations.
(2) Incoming UDP/RAW packet filtering.
(3) Signal transmission restriction.
(4) Many of non-posix capabilities support.

Since this patchset is not yet accepted, I haven't written documentation for
TOMOYO 2.3. You can see http://tomoyo.sourceforge.jp/1.7/policy-reference.html
instead.

Conventionally, patches should be submitted in the form of diff file.
But this time, I submit in the form of entire file due to amount of changes.

# diff -u security/tomoyo.2.2/realpath.c security/tomoyo/new-realpath.c | diffstat -f0
 new-realpath.c |  609  186 +   423 -   0 !
 1 file changed, 186 insertions(+), 423 deletions(-)
# wc -l security/tomoyo/new-realpath.c
251 security/tomoyo/new-realpath.c

# diff -u security/tomoyo.2.2/file.c security/tomoyo/new-file.c | diffstat -f0
 new-file.c | 2472      1693 +  779 -   0 !
 1 file changed, 1693 insertions(+), 779 deletions(-)
# wc -l security/tomoyo/new-file.c
2249 security/tomoyo/new-file.c

# diff -u security/tomoyo.2.2/domain.c security/tomoyo/new-domain.c | diffstat -f0
 new-domain.c | 1322    877 +   445 -   0 !
 1 file changed, 877 insertions(+), 445 deletions(-)
# wc -l security/tomoyo/new-domain.c
1354 security/tomoyo/new-domain.c

# diff -u security/tomoyo.2.2/tomoyo.c security/tomoyo/lsm.c | diffstat -f0
 lsm.c |  492   350 +   142 -   0 !
 1 file changed, 350 insertions(+), 142 deletions(-)
# wc -l security/tomoyo/lsm.c
523 security/tomoyo/lsm.c

# diff -Nur security/tomoyo.2.2/ security/tomoyo/ | diffstat -f0
 Kconfig         |   67         67 +    0 -     0 !
 Makefile        |    2         1 +     1 -     0 !
 address_group.c |  270         270 +   0 -     0 !
 audit.c         |  561         561 +   0 -     0 !
 capability.c    |  141         141 +   0 -     0 !
 common.c        | 2276         0 +     2276 -  0 !
 common.h        |  461         0 +     461 -   0 !
 condition.c     | 1332         1332 +  0 -     0 !
 domain.c        |  922         0 +     922 -   0 !
 environ.c       |  232         232 +   0 -     0 !
 file.c          | 1335         0 +     1335 -  0 !
 gc.c            |  606         606 +   0 -     0 !
 internal.h      | 1317         1317 +  0 -     0 !
 load_policy.c   |   97         97 +    0 -     0 !
 lsm.c           |  523         523 +   0 -     0 !
 memory.c        |  391         391 +   0 -     0 !
 mount.c         |  366         366 +   0 -     0 !
 network.c       |  757         757 +   0 -     0 !
 new-domain.c    | 1354         1354 +  0 -     0 !
 new-file.c      | 2249         2249 +  0 -     0 !
 new-realpath.c  |  251         251 +   0 -     0 !
 number_group.c  |  212         212 +   0 -     0 !
 path_group.c    |  210         210 +   0 -     0 !
 policy_io.c     | 2734         2734 +  0 -     0 !
 realpath.c      |  488         0 +     488 -   0 !
 realpath.h      |   66         0 +     66 -    0 !
 securityfs_if.c |  148         148 +   0 -     0 !
 tomoyo.c        |  315         0 +     315 -   0 !
 tomoyo.h        |   96         0 +     96 -    0 !
 util.c          | 1144         1144 +  0 -     0 !
 30 files changed, 14963 insertions(+), 5960 deletions(-)

Regards.
-- 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-11-25 15:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-24 13:00 [PATCH] TOMOYO: Add recursive directory matching operator support Tetsuo Handa
2009-11-24 23:37 ` John Johansen
2009-11-25  7:52 ` James Morris
2009-11-25 14:00 ` Serge E. Hallyn
2009-11-25 14:59   ` [PATCH] TOMOYO: Add recursive directory matching operatorsupport Tetsuo Handa
2009-11-25 15:27     ` Serge E. Hallyn
  -- strict thread matches above, loose matches on Subject: below --
2009-10-04 12:49 [TOMOYO #16 00/25] Starting TOMOYO 2.3 Tetsuo Handa
2009-10-04 12:49 ` [TOMOYO #16 01/25] LSM: Add security_path_chmod() and security_path_chown() Tetsuo Handa
2009-10-08 17:10   ` John Johansen
2009-10-12  1:04     ` James Morris
2009-10-13 11:34       ` [TOMOYO #16 01/25] LSM: Add security_path_chmod() andsecurity_path_chown() Tetsuo Handa
2009-10-13 11:37         ` [PATCH] TOMOYO: Add recursive directory matching operator support Tetsuo Handa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.