From: <ssm...@us...> - 2007-11-01 20:14:37
|
Revision: 2665 http://selinux.svn.sourceforge.net/selinux/?rev=2665&view=rev Author: ssmalley Date: 2007-11-01 13:14:36 -0700 (Thu, 01 Nov 2007) Log Message: ----------- Author: James Carter Email: jw...@ty... Subject: checkpolicy: Remove use of REJECT and trailing context in lex rules; make ipv4 address processing like ipv6 Date: Wed, 31 Oct 2007 15:43:45 -0400 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 <jw...@ty...> Modified Paths: -------------- trunk/checkpolicy/policy_parse.y trunk/checkpolicy/policy_scan.l Modified: trunk/checkpolicy/policy_parse.y =================================================================== --- trunk/checkpolicy/policy_parse.y 2007-11-01 16:51:46 UTC (rev 2664) +++ trunk/checkpolicy/policy_parse.y 2007-11-01 20:14:36 UTC (rev 2665) @@ -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) Modified: trunk/checkpolicy/policy_scan.l =================================================================== --- trunk/checkpolicy/policy_scan.l 2007-11-01 16:51:46 UTC (rev 2664) +++ trunk/checkpolicy/policy_scan.l 2007-11-01 20:14:36 UTC (rev 2665) @@ -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; -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |