[apparmor] [Patch][parser] fix: globbing for af_unix abstract names

John Johansen john.johansen at canonical.com
Fri Jan 30 23:14:39 UTC 2015


And the related patch to fix globbing for af_unix abstract names

Abstract af_unix socket names can contain a null character, however the
aare to pcre conversion explicitly disallows null characters because they
are not valid characters for pathnames. Fix this so that they type of
globbing is selectable.

this is a partial fix for

Bug: http://bugs.launchpad.net/bugs/1413410

Signed-off-by: John Johansen <john.johansen at canonical.com>


nominated for 2.9 and 3.0


---

=== modified file 'parser/af_unix.cc'
--- parser/af_unix.cc	2014-10-08 20:20:20 +0000
+++ parser/af_unix.cc	2015-01-30 17:46:36 +0000
@@ -243,7 +243,7 @@
 			buffer << "\\x01";
 		} else {
 			/* skip leading @ */
-			ptype = convert_aaregex_to_pcre(addr + 1, 0, buf, &pos);
+			ptype = convert_aaregex_to_pcre(addr + 1, 0, glob_null, buf, &pos);
 			if (ptype == ePatternInvalid)
 				return false;
 			/* kernel starts abstract with \0 */
@@ -267,7 +267,7 @@
 
 	if (label) {
 		int pos;
-		ptype = convert_aaregex_to_pcre(label, 0, buf, &pos);
+		ptype = convert_aaregex_to_pcre(label, 0, glob_default, buf, &pos);
 		if (ptype == ePatternInvalid)
 			return false;
 		/* kernel starts abstract with \0 */

=== modified file 'parser/dbus.cc'
--- parser/dbus.cc	2014-10-08 20:20:20 +0000
+++ parser/dbus.cc	2015-01-30 17:47:35 +0000
@@ -228,7 +228,7 @@
 	busbuf.append(buffer.str());
 
 	if (bus) {
-		ptype = convert_aaregex_to_pcre(bus, 0, busbuf, &pos);
+		ptype = convert_aaregex_to_pcre(bus, 0, glob_default, busbuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 	} else {
@@ -238,7 +238,7 @@
 	vec[0] = busbuf.c_str();
 
 	if (name) {
-		ptype = convert_aaregex_to_pcre(name, 0, namebuf, &pos);
+		ptype = convert_aaregex_to_pcre(name, 0, glob_default, namebuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		vec[1] = namebuf.c_str();
@@ -248,7 +248,7 @@
 	}
 
 	if (peer_label) {
-		ptype = convert_aaregex_to_pcre(peer_label, 0,
+		ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default,
 						peer_labelbuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
@@ -259,7 +259,7 @@
 	}
 
 	if (path) {
-		ptype = convert_aaregex_to_pcre(path, 0, pathbuf, &pos);
+		ptype = convert_aaregex_to_pcre(path, 0, glob_default, pathbuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		vec[3] = pathbuf.c_str();
@@ -269,7 +269,7 @@
 	}
 
 	if (interface) {
-		ptype = convert_aaregex_to_pcre(interface, 0, ifacebuf, &pos);
+		ptype = convert_aaregex_to_pcre(interface, 0, glob_default, ifacebuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		vec[4] = ifacebuf.c_str();
@@ -279,7 +279,7 @@
 	}
 
 	if (member) {
-		ptype = convert_aaregex_to_pcre(member, 0, memberbuf, &pos);
+		ptype = convert_aaregex_to_pcre(member, 0, glob_default, memberbuf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		vec[5] = memberbuf.c_str();

=== modified file 'parser/mount.cc'
--- parser/mount.cc	2014-12-12 14:21:31 +0000
+++ parser/mount.cc	2015-01-30 17:47:53 +0000
@@ -554,7 +554,7 @@
 	}
 
 	list_for_each(opts, ent) {
-		ptype = convert_aaregex_to_pcre(ent->value, 0, buffer, &pos);
+		ptype = convert_aaregex_to_pcre(ent->value, 0, glob_default, buffer, &pos);
 		if (ptype == ePatternInvalid)
 			return FALSE;
 

=== modified file 'parser/parser.h'
--- parser/parser.h	2014-10-08 20:20:20 +0000
+++ parser/parser.h	2015-01-30 17:50:02 +0000
@@ -334,7 +334,9 @@
 #define default_match_pattern "[^\\000]*"
 #define anyone_match_pattern "[^\\000]+"
 
-extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
+#define glob_default	0
+#define glob_null	1
+extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob,
 					 std::string& pcre, int *first_re_pos);
 extern int build_list_val_expr(std::string& buffer, struct value_list *list);
 extern int convert_entry(std::string& buffer, char *entry);

=== modified file 'parser/parser_regex.c'
--- parser/parser_regex.c	2015-01-29 22:54:08 +0000
+++ parser/parser_regex.c	2015-01-30 22:49:16 +0000
@@ -86,7 +86,7 @@
 
 /* converts the apparmor regex in aare and appends pcre regex output
  * to pcre string */
-pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
+pattern_t convert_aaregex_to_pcre(const char *aare, int anchor, int glob,
 				  std::string& pcre, int *first_re_pos)
 {
 #define update_re_pos(X) if (!(*first_re_pos)) { *first_re_pos = (X); }
@@ -172,7 +172,18 @@
 					while (*s == '*')
 						s++;
 					if (*s == '/' || !*s) {
-						pcre.append("[^/\\x00]");
+						switch (glob) {
+						case glob_default:
+							pcre.append("[^/\\x00]");
+							break;
+						case glob_null:
+							pcre.append("[^/]");
+							break;
+						default:
+							error = e_parse_error;
+							PERROR(_("%s: Invalid glob type %d\n"), progname, glob);
+							break;
+						}
 					}
 				}
 				if (*(sptr + 1) == '*') {
@@ -190,12 +201,34 @@
 						ptype = ePatternRegex;
 					}
 
-					pcre.append("[^\\x00]*");
+					switch (glob) {
+					case glob_default:
+						pcre.append("[^\\x00]*");
+						break;
+					case glob_null:
+						pcre.append(".*");
+						break;
+					default:
+						error = e_parse_error;
+						PERROR(_("%s: Invalid glob type %d\n"), progname, glob);
+						break;
+					}
 					sptr++;
 				} else {
 					update_re_pos(sptr - aare);
 					ptype = ePatternRegex;
-					pcre.append("[^/\\x00]*");
+					switch (glob) {
+					case glob_default:
+						pcre.append("[^/\\x00]*");
+						break;
+					case glob_null:
+						pcre.append("[^/]*");
+						break;
+					default:
+						error = e_parse_error;
+						PERROR(_("%s: Invalid glob type %d\n"), progname, glob);
+						break;
+					}
 				}	/* *(sptr+1) == '*' */
 			}	/* bEscape */
 
@@ -427,7 +460,7 @@
 		name = prof->attachment;
 	else
 		name = local_name(prof->name);
-	ptype = convert_aaregex_to_pcre(name, 0, tbuf,
+	ptype = convert_aaregex_to_pcre(name, 0, glob_default, tbuf,
 					&prof->xmatch_len);
 	if (ptype == ePatternBasic)
 		prof->xmatch_len = strlen(name);
@@ -455,8 +488,8 @@
 				int len;
 				tbuf.clear();
 				ptype = convert_aaregex_to_pcre(alt->name, 0,
-								tbuf,
-								&len);
+								glob_default,
+								tbuf, &len);
 				if (ptype == ePatternBasic)
 					len = strlen(alt->name);
 				if (len < prof->xmatch_len)
@@ -488,7 +521,7 @@
 
 	if (entry->mode & ~AA_CHANGE_PROFILE)
 		filter_slashes(entry->name);
-	ptype = convert_aaregex_to_pcre(entry->name, 0, tbuf, &pos);
+	ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos);
 	if (ptype == ePatternInvalid)
 		return FALSE;
 
@@ -526,7 +559,7 @@
 		int pos;
 		vec[0] = tbuf.c_str();
 		if (entry->link_name) {
-			ptype = convert_aaregex_to_pcre(entry->link_name, 0, lbuf, &pos);
+			ptype = convert_aaregex_to_pcre(entry->link_name, 0, glob_default, lbuf, &pos);
 			if (ptype == ePatternInvalid)
 				return FALSE;
 			if (entry->subset)
@@ -549,7 +582,7 @@
 
 		if (entry->ns) {
 			int pos;
-			ptype = convert_aaregex_to_pcre(entry->ns, 0, lbuf, &pos);
+			ptype = convert_aaregex_to_pcre(entry->ns, 0, glob_default, lbuf, &pos);
 			vec[index++] = lbuf.c_str();
 		}
 		vec[index++] = tbuf.c_str();
@@ -631,13 +664,13 @@
 
 	buffer.append("(");
 
-	ptype = convert_aaregex_to_pcre(list->value, 0, buffer, &pos);
+	ptype = convert_aaregex_to_pcre(list->value, 0, glob_default, buffer, &pos);
 	if (ptype == ePatternInvalid)
 		goto fail;
 
 	list_for_each(list->next, ent) {
 		buffer.append("|");
-		ptype = convert_aaregex_to_pcre(ent->value, 0, buffer, &pos);
+		ptype = convert_aaregex_to_pcre(ent->value, 0, glob_default, buffer, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 	}
@@ -654,7 +687,7 @@
 	int pos;
 
 	if (entry) {
-		ptype = convert_aaregex_to_pcre(entry, 0, buffer, &pos);
+		ptype = convert_aaregex_to_pcre(entry, 0, glob_default, buffer, &pos);
 		if (ptype == ePatternInvalid)
 			return FALSE;
 	} else {
@@ -805,7 +838,7 @@
 	return rc;
 }
 
-#define MY_REGEX_TEST(input, expected_str, expected_type)						\
+#define MY_REGEX_EXT_TEST(glob, input, expected_str, expected_type)	\
 	do {												\
 		std::string tbuf;									\
 		std::string tbuf2 = "testprefix";							\
@@ -814,7 +847,7 @@
 		pattern_t ptype;									\
 		int pos;										\
 													\
-		ptype = convert_aaregex_to_pcre((input), 0, tbuf, &pos);				\
+		ptype = convert_aaregex_to_pcre((input), 0, glob, tbuf, &pos); \
 		asprintf(&output_string, "simple regex conversion for '%s'\texpected = '%s'\tresult = '%s'", \
 				(input), (expected_str), tbuf.c_str());					\
 		MY_TEST(strcmp(tbuf.c_str(), (expected_str)) == 0, output_string);			\
@@ -823,21 +856,25 @@
 		/* ensure convert_aaregex_to_pcre appends only to passed ref string */			\
 		expected_str2 = tbuf2;									\
 		expected_str2.append((expected_str));							\
-		ptype = convert_aaregex_to_pcre((input), 0, tbuf2, &pos);				\
-		asprintf(&output_string, "simple regex conversion for '%s'\texpected = '%s'\tresult = '%s'", \
+		ptype = convert_aaregex_to_pcre((input), 0, glob, tbuf2, &pos); \
+		asprintf(&output_string, "simple regex conversion %sfor '%s'\texpected = '%s'\tresult = '%s'", \
+			 glob == glob_null ? "with null allowed in glob " : "",\
 				(input), expected_str2.c_str(), tbuf2.c_str());				\
 		MY_TEST((tbuf2 == expected_str2), output_string);					\
 		free(output_string);									\
 	}												\
 	while (0)
 
+#define MY_REGEX_TEST(input, expected_str, expected_type) MY_REGEX_EXT_TEST(glob_default, input, expected_str, expected_type)
+
+
 #define MY_REGEX_FAIL_TEST(input)						\
 	do {												\
 		std::string tbuf;									\
 		pattern_t ptype;									\
 		int pos;										\
 													\
-		ptype = convert_aaregex_to_pcre((input), 0, tbuf, &pos);				\
+		ptype = convert_aaregex_to_pcre((input), 0, glob_default, tbuf, &pos); \
 		MY_TEST(ptype == ePatternInvalid, "simple regex conversion invalid type check for '" input "'"); \
 	}												\
 	while (0)
@@ -958,6 +995,27 @@
 	MY_REGEX_TEST("{alpha,b[\\{a,b\\}]t,gamma}", "(alpha|b[\\{a,b\\}]t|gamma)", ePatternRegex);
 	MY_REGEX_TEST("{alpha,b[\\{a\\,b\\}]t,gamma}", "(alpha|b[\\{a\\,b\\}]t|gamma)", ePatternRegex);
 
+	/* test different globbing behavior conversion */
+	MY_REGEX_EXT_TEST(glob_default, "/foo/**", "/foo/[^/\\x00][^\\x00]*", ePatternTailGlob);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/**", "/foo/[^/].*", ePatternTailGlob);
+	MY_REGEX_EXT_TEST(glob_default, "/foo/f**", "/foo/f[^\\x00]*", ePatternTailGlob);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/f**", "/foo/f.*", ePatternTailGlob);
+
+	MY_REGEX_EXT_TEST(glob_default, "/foo/*", "/foo/[^/\\x00][^/\\x00]*", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/*", "/foo/[^/][^/]*", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_default, "/foo/f*", "/foo/f[^/\\x00]*", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/f*", "/foo/f[^/]*", ePatternRegex);
+
+	MY_REGEX_EXT_TEST(glob_default, "/foo/**.ext", "/foo/[^\\x00]*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/**.ext", "/foo/.*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_default, "/foo/f**.ext", "/foo/f[^\\x00]*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/f**.ext", "/foo/f.*\\.ext", ePatternRegex);
+
+	MY_REGEX_EXT_TEST(glob_default, "/foo/*.ext", "/foo/[^/\\x00]*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/*.ext", "/foo/[^/]*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_default, "/foo/f*.ext", "/foo/f[^/\\x00]*\\.ext", ePatternRegex);
+	MY_REGEX_EXT_TEST(glob_null, "/foo/f*.ext", "/foo/f[^/]*\\.ext", ePatternRegex);
+
 	return rc;
 }
 

=== modified file 'parser/ptrace.cc'
--- parser/ptrace.cc	2014-10-08 20:20:20 +0000
+++ parser/ptrace.cc	2015-01-30 17:48:18 +0000
@@ -139,7 +139,7 @@
 	buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_PTRACE;
 
 	if (peer_label) {
-		ptype = convert_aaregex_to_pcre(peer_label, 0, buf, &pos);
+		ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default, buf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		buffer << buf;

=== modified file 'parser/signal.cc'
--- parser/signal.cc	2014-10-08 20:20:20 +0000
+++ parser/signal.cc	2015-01-30 17:48:43 +0000
@@ -294,7 +294,7 @@
 		buffer << ")";
 	}
 	if (peer_label) {
-		ptype = convert_aaregex_to_pcre(peer_label, 0, buf, &pos);
+		ptype = convert_aaregex_to_pcre(peer_label, 0, glob_default, buf, &pos);
 		if (ptype == ePatternInvalid)
 			goto fail;
 		buffer << buf;





More information about the AppArmor mailing list