[PATCH] checkpolicy: Remove use of REJECT and trailing context in lex rules; make ipv4 address processing like ipv6

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a patch to remove the use of REJECT and trailing context in the
lex rules.  To help accomplish this, it also makes ipv4 address
processing like ipv6 address processing.

It improves policy compile times on my laptop from ~95sec to ~85sec.  

REJECT was used to reject an identifier if it had two consecutive "."s
or one at the end.  The new rule should prevent both of these conditions
without the use of REJECT and the is_valid_identifier function.

Trailing context was used in the rule to identify the module version.
Without the trailing context, the rule would match ipv4 addresses.  A
rule for ipv4 addresses was added to eliminate the need for the use of
trailing context and to allow ipv4 addresses to be handled in a manner
similar to ipv6 addresses.

Finally, the alnum character class was defined and some minor cleanup
was done.

I am, by the way, surprised by the rule to match the module version.
It is "[0-9]+(\.[A-Za-z0-9_.]*)?" when I would have expected something
like "[0-9]+(\.[0-9]+){0,2}".  I assumed that there is a reason why it
is like this and left it alone.


Signed off by: James Carter <jwcart2@xxxxxxxxxxxxx>
---

 policy_parse.y |   79
++++++++++++++++++++++++++++++++++++++-------------------
 policy_scan.l  |   34 +++++-------------------
 2 files changed, 62 insertions(+), 51 deletions(-)


Index: checkpolicy/policy_scan.l
===================================================================
--- checkpolicy/policy_scan.l	(revision 2662)
+++ checkpolicy/policy_scan.l	(working copy)
@@ -31,7 +31,6 @@
 static char linebuf[2][255];
 static unsigned int lno = 0;
 int yywarn(char *msg);
-static int is_valid_identifier(char *id);
 
 char source_file[255];
 unsigned long source_lineno = 1;
@@ -46,8 +45,8 @@
 %array
 letter  [A-Za-z]
 digit   [0-9]
+alnum   [a-zA-Z0-9]
 hexval	[0-9A-Fa-f]
-version [0-9]+(\.[A-Za-z0-9_.]*)?
 
 %%
 \n.*				{ strncpy(linebuf[lno], yytext+1, 255);
@@ -199,17 +198,14 @@
 H1				{ return(H1); }
 h2 |
 H2				{ return(H2); }
-"/"({letter}|{digit}|_|"."|"-"|"/")*	{ return(PATH); }
-{letter}({letter}|{digit}|_|"."|"-")*	{ if (is_valid_identifier(yytext)) 
-						return(IDENTIFIER); 
-					  else 
-					  	REJECT;
-					}
-{digit}{digit}*                 { return(NUMBER); }
-{hexval}{0,4}":"{hexval}{0,4}":"({hexval}|":"|".")*	{ return(IPV6_ADDR); }
-{version}/([ \t\f]*;)           { return(VERSION_IDENTIFIER); }
+"/"({alnum}|[_.-/])*	        { return(PATH); }
+{letter}({alnum}|[_-])*([.]?({alnum}|[_-]))*	{ return(IDENTIFIER); }
+{digit}+                        { return(NUMBER); }
+{digit}{1,3}(\.{digit}{1,3}){3}    { return(IPV4_ADDR); }
+{hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*  { return(IPV6_ADDR); }
+{digit}+(\.({alnum}|[_.])*)?    { return(VERSION_IDENTIFIER); }
 #line[ ]1[ ]\"[^\n]*\"		{ source_lineno = 1; strncpy(source_file, yytext+9, 255); source_file[strlen(source_file)-1] = '\0'; }
-#line[ ]{digit}{digit}*		{ source_lineno = atoi(yytext+6)-1; }
+#line[ ]{digit}+	        { source_lineno = atoi(yytext+6)-1; }
 #[^\n]*                         { /* delete comments */ }
 [ \t\f]+			{ /* delete whitespace */ }
 "==" 				{ return(EQUALS); }
@@ -263,17 +259,3 @@
 			linebuf[0], linebuf[1]);
 	return 0;
 }
-
-static int is_valid_identifier(char *id) {
-        if ((strrchr(id, '.')) != NULL) {
-                if (strstr(id, "..") != NULL) {
-                        /* identifier has consecutive '.' */
-                        return 0;
-                }
-		if (id[strlen(id) - 1] == '.') {
-			/* identifier ends in '.' */
-			return 0;
-		}
-        }
-        return 1;
-}
Index: checkpolicy/policy_parse.y
===================================================================
--- checkpolicy/policy_parse.y	(revision 2662)
+++ checkpolicy/policy_parse.y	(working copy)
@@ -122,7 +122,7 @@
 static int define_fs_context(unsigned int major, unsigned int minor);
 static int define_port_context(unsigned int low, unsigned int high);
 static int define_netif_context(void);
-static int define_ipv4_node_context(unsigned int addr, unsigned int mask);
+static int define_ipv4_node_context(void);
 static int define_ipv6_node_context(void);
 
 typedef int (* require_func_t)();
@@ -195,6 +195,7 @@
 %token NUMBER
 %token EQUALS
 %token NOTEQUAL
+%token IPV4_ADDR
 %token IPV6_ADDR
 %token MODULE VERSION_IDENTIFIER REQUIRE OPTIONAL
 
@@ -654,7 +655,7 @@
 			| node_contexts node_context_def
 			;
 node_context_def	: NODECON ipv4_addr_def ipv4_addr_def security_context_def
-			{if (define_ipv4_node_context($2,$3)) return -1;}
+			{if (define_ipv4_node_context()) return -1;}
 			| NODECON ipv6_addr ipv6_addr security_context_def
 			{if (define_ipv6_node_context()) return -1;}
 			;
@@ -684,18 +685,9 @@
                         | GENFSCON identifier path security_context_def
 			{if (define_genfs_context(0)) return -1;}
 			;
-ipv4_addr_def		: number '.' number '.' number '.' number
-			{ 
-			  unsigned int addr;
-	  		  unsigned char *p = ((unsigned char *)&addr);
-
-			  p[0] = $1 & 0xff;				
-			  p[1] = $3 & 0xff;
-			  p[2] = $5 & 0xff;
-			  p[3] = $7 & 0xff;
-			  $$ = addr;
-			}
-    			;
+ipv4_addr_def		: IPV4_ADDR
+			{ if (insert_id(yytext,0)) return -1; }
+			;
 security_context_def	: identifier ':' identifier ':' identifier opt_mls_range_def
 	                ;
 opt_mls_range_def	: ':' mls_range_def
@@ -4184,27 +4176,63 @@
 	return 0;
 }
 
-static int define_ipv4_node_context(unsigned int addr, unsigned int mask)
-{
+static int define_ipv4_node_context()
+{	
+	char *id;
+	int rc = 0;
+	struct in_addr addr, mask;
 	ocontext_t *newc, *c, *l, *head;
 
 	if (pass == 1) {
+		free(queue_remove(id_queue));
+		free(queue_remove(id_queue));
 		parse_security_context(NULL);
-		if (mlspol)
-			free(queue_remove(id_queue));
-		return 0;
+		goto out;
 	}
 
+	id = queue_remove(id_queue);
+	if (!id) {
+		yyerror("failed to read ipv4 address");
+		rc = -1;
+		goto out;
+	}
+
+	rc = inet_pton(AF_INET, id, &addr);
+	free(id);
+	if (rc < 1) {
+		yyerror("failed to parse ipv4 address");
+		if (rc == 0)
+			rc = -1;
+		goto out;
+	}
+
+	id = queue_remove(id_queue);
+	if (!id) {
+		yyerror("failed to read ipv4 address");
+		rc = -1;
+		goto out;
+	}
+
+	rc = inet_pton(AF_INET, id, &mask);
+	free(id);
+	if (rc < 1) {
+		yyerror("failed to parse ipv4 mask");
+		if (rc == 0)
+			rc = -1;
+		goto out;
+	}
+
 	newc = malloc(sizeof(ocontext_t));
 	if (!newc) {
 		yyerror("out of memory");
-		return -1;
+		rc = -1;
+		goto out;
 	}
+
 	memset(newc, 0, sizeof(ocontext_t));
+	newc->u.node.addr = addr.s_addr;
+	newc->u.node.mask = mask.s_addr;
 
-	newc->u.node.addr = addr;
-	newc->u.node.mask = mask;
-
 	if (parse_security_context(&newc->context[0])) {
 		free(newc);
 		return -1;
@@ -4224,8 +4252,9 @@
 		l->next = newc;
 	else
 		policydbp->ocontexts[OCON_NODE] = newc;
-
-	return 0;
+	rc = 0;
+out:
+	return rc;
 }
 
 static int define_ipv6_node_context(void)

-- 
James Carter <jwcart2@xxxxxxxxxxxxx>
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux