xref: /aosp_15_r20/external/selinux/checkpolicy/policy_scan.l (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 
2 /*
3  * Author : Stephen Smalley, <[email protected]>
4  */
5 
6 /* Updated: David Caplan, <[email protected]>
7  *
8  * 	Added conditional policy language extensions
9  *
10  *          Jason Tang    <[email protected]>
11  *
12  *	Added support for binary policy modules
13  *
14  * Copyright (C) 2003-5 Tresys Technology, LLC
15  * Copyright (C) 2017 Mellanox Technologies Inc.
16  *	This program is free software; you can redistribute it and/or modify
17  *  	it under the terms of the GNU General Public License as published by
18  *	the Free Software Foundation, version 2.
19  */
20 
21 /* FLASK */
22 
23 %{
24 #include <sys/types.h>
25 #include <ctype.h>
26 #include <limits.h>
27 #include <stdint.h>
28 #include <string.h>
29 
30 typedef int (* require_func_t)(void);
31 
32 #ifdef ANDROID
33 #include "policy_parse.h"
34 #else
35 #include "y.tab.h"
36 #endif
37 
38 static char linebuf[2][255];
39 static unsigned int lno = 0;
40 int werror = 0;
41 int yyerror(const char *msg);
42 int yywarn(const char *msg);
43 
44 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
45 /*
46  * Version that does not exit, like yy_fatal_error(),
47  * since fuzz targets must not call exit().
48  */
49 #include <setjmp.h>
50 extern jmp_buf fuzzing_pre_parse_stack_state;
yyfatal(const char * msg)51 void yyfatal(const char *msg)
52 {
53 	yyerror(msg);
54 	longjmp(fuzzing_pre_parse_stack_state, 1);
55 }
56 #define YY_FATAL_ERROR(msg) yyfatal(msg)
57 #endif
58 
59 void set_source_file(const char *name);
60 
61 char source_file[PATH_MAX];
62 unsigned long source_lineno = 1;
63 
64 unsigned long policydb_lineno = 1;
65 
66 unsigned int policydb_errors = 0;
67 %}
68 
69 %option noinput nounput noyywrap
70 
71 %array
72 letter  [A-Za-z]
73 digit   [0-9]
74 alnum   [a-zA-Z0-9]
75 hexval	[0-9A-Fa-f]
76 
77 %%
78 \n.*				{
79 #if defined(__GNUC__) && __GNUC__ >= 8
80 #pragma GCC diagnostic push
81 #pragma GCC diagnostic ignored "-Wstringop-truncation"
82 #endif
83 				  strncpy(linebuf[lno], yytext+1, 255);
84 #if defined(__GNUC__) && __GNUC__ >= 8
85 #pragma GCC diagnostic pop
86 #endif
87 				  linebuf[lno][254] = 0;
88 				  lno = 1 - lno;
89 				  policydb_lineno++;
90 				  if (source_lineno == ULONG_MAX)
91 				      yywarn("source line number overflow");
92 				  else
93 				      source_lineno++;
94 				  yyless(1);
95 				}
96 COMMON |
97 common				{ return(COMMON); }
98 CLASS |
99 class				{ return(CLASS); }
100 CONSTRAIN |
101 constrain			{ return(CONSTRAIN); }
102 VALIDATETRANS |
103 validatetrans			{ return(VALIDATETRANS); }
104 INHERITS |
105 inherits			{ return(INHERITS); }
106 SID |
107 sid				{ return(SID); }
108 ROLE |
109 role				{ return(ROLE); }
110 ROLES |
111 roles				{ return(ROLES); }
112 ROLEATTRIBUTE |
113 roleattribute			{ return(ROLEATTRIBUTE);}
114 ATTRIBUTE_ROLE |
115 attribute_role			{ return(ATTRIBUTE_ROLE);}
116 TYPES |
117 types				{ return(TYPES); }
118 TYPEALIAS |
119 typealias			{ return(TYPEALIAS); }
120 TYPEATTRIBUTE |
121 typeattribute			{ return(TYPEATTRIBUTE); }
122 TYPEBOUNDS |
123 typebounds			{ return(TYPEBOUNDS); }
124 TYPE |
125 type				{ return(TYPE); }
126 BOOL |
127 bool                            { return(BOOL); }
128 TUNABLE |
129 tunable				{ return(TUNABLE); }
130 IF |
131 if				{ return(IF); }
132 ELSE |
133 else				{ return(ELSE); }
134 ALIAS |
135 alias				{ return(ALIAS); }
136 ATTRIBUTE |
137 attribute			{ return(ATTRIBUTE); }
138 EXPANDATTRIBUTE |
139 expandattribute                 { return(EXPANDATTRIBUTE); }
140 TYPE_TRANSITION |
141 type_transition			{ return(TYPE_TRANSITION); }
142 TYPE_MEMBER |
143 type_member			{ return(TYPE_MEMBER); }
144 TYPE_CHANGE |
145 type_change			{ return(TYPE_CHANGE); }
146 ROLE_TRANSITION |
147 role_transition			{ return(ROLE_TRANSITION); }
148 RANGE_TRANSITION |
149 range_transition		{ return(RANGE_TRANSITION); }
150 SENSITIVITY |
151 sensitivity			{ return(SENSITIVITY); }
152 DOMINANCE |
153 dominance			{ return(DOMINANCE); }
154 CATEGORY |
155 category			{ return(CATEGORY); }
156 LEVEL |
157 level				{ return(LEVEL); }
158 RANGE |
159 range				{ return(RANGE); }
160 MLSCONSTRAIN |
161 mlsconstrain			{ return(MLSCONSTRAIN); }
162 MLSVALIDATETRANS |
163 mlsvalidatetrans		{ return(MLSVALIDATETRANS); }
164 USER |
165 user				{ return(USER); }
166 NEVERALLOW |
167 neverallow		        { return(NEVERALLOW); }
168 ALLOW |
169 allow			        { return(ALLOW); }
170 AUDITALLOW |
171 auditallow		        { return(AUDITALLOW); }
172 AUDITDENY |
173 auditdeny		        { return(AUDITDENY); }
174 DONTAUDIT |
175 dontaudit                       { return(DONTAUDIT); }
176 ALLOWXPERM |
177 allowxperm			{ return(ALLOWXPERM); }
178 AUDITALLOWXPERM |
179 auditallowxperm			{ return(AUDITALLOWXPERM); }
180 DONTAUDITXPERM |
181 dontauditxperm			{ return(DONTAUDITXPERM); }
182 NEVERALLOWXPERM |
183 neverallowxperm			{ return(NEVERALLOWXPERM); }
184 SOURCE |
185 source			        { return(SOURCE); }
186 TARGET |
187 target			        { return(TARGET); }
188 SAMEUSER |
189 sameuser			{ return(SAMEUSER);}
190 module|MODULE                   { return(MODULE); }
191 require|REQUIRE                 { return(REQUIRE); }
192 optional|OPTIONAL               { return(OPTIONAL); }
193 OR |
194 or     			        { return(OR);}
195 AND |
196 and				{ return(AND);}
197 NOT |
198 not				{ return(NOT);}
199 xor |
200 XOR                             { return(XOR); }
201 eq |
202 EQ				{ return(EQUALS);}
203 true |
204 TRUE                            { return(CTRUE); }
205 false |
206 FALSE                           { return(CFALSE); }
207 dom |
208 DOM				{ return(DOM);}
209 domby |
210 DOMBY				{ return(DOMBY);}
211 INCOMP |
212 incomp				{ return(INCOMP);}
213 fscon |
214 FSCON                           { return(FSCON);}
215 ibpkeycon |
216 IBPKEYCON			{ return(IBPKEYCON);}
217 ibendportcon |
218 IBENDPORTCON			{ return(IBENDPORTCON);}
219 portcon |
220 PORTCON				{ return(PORTCON);}
221 netifcon |
222 NETIFCON			{ return(NETIFCON);}
223 nodecon |
224 NODECON				{ return(NODECON);}
225 pirqcon |
226 PIRQCON  		        { return(PIRQCON);}
227 iomemcon |
228 IOMEMCON            		{ return(IOMEMCON);}
229 ioportcon |
230 IOPORTCON           		{ return(IOPORTCON);}
231 pcidevicecon |
232 PCIDEVICECON           		{ return(PCIDEVICECON);}
233 devicetreecon |
234 DEVICETREECON           	{ return(DEVICETREECON);}
235 fs_use_xattr |
236 FS_USE_XATTR			{ return(FSUSEXATTR);}
237 fs_use_task |
238 FS_USE_TASK                     { return(FSUSETASK);}
239 fs_use_trans |
240 FS_USE_TRANS                    { return(FSUSETRANS);}
241 genfscon |
242 GENFSCON                        { return(GENFSCON);}
243 r1 |
244 R1				{ return(R1); }
245 r2 |
246 R2				{ return(R2); }
247 r3 |
248 R3				{ return(R3); }
249 u1 |
250 U1				{ return(U1); }
251 u2 |
252 U2				{ return(U2); }
253 u3 |
254 U3				{ return(U3); }
255 t1 |
256 T1				{ return(T1); }
257 t2 |
258 T2				{ return(T2); }
259 t3 |
260 T3				{ return(T3); }
261 l1 |
262 L1				{ return(L1); }
263 l2 |
264 L2				{ return(L2); }
265 h1 |
266 H1				{ return(H1); }
267 h2 |
268 H2				{ return(H2); }
269 policycap |
270 POLICYCAP			{ return(POLICYCAP); }
271 permissive |
272 PERMISSIVE			{ return(PERMISSIVE); }
273 default_user |
274 DEFAULT_USER			{ return(DEFAULT_USER); }
275 default_role |
276 DEFAULT_ROLE			{ return(DEFAULT_ROLE); }
277 default_type |
278 DEFAULT_TYPE			{ return(DEFAULT_TYPE); }
279 default_range |
280 DEFAULT_RANGE			{ return(DEFAULT_RANGE); }
281 low-high |
282 LOW-HIGH			{ return(LOW_HIGH); }
283 high |
284 HIGH				{ return(HIGH); }
285 low |
286 LOW				{ return(LOW); }
287 glblub |
288 GLBLUB				{ return(GLBLUB); }
289 "/"[^ \n\r\t\f]*	        { return(PATH); }
290 \""/"[^\"\n]*\" 		{ return(QPATH); }
291 \"[^"/"\"\n]+\"	{ return(FILENAME); }
292 {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))*	{ return(IDENTIFIER); }
293 {digit}+|0x{hexval}+            { return(NUMBER); }
294 {alnum}*{letter}{alnum}*        { return(FILESYSTEM); }
295 {digit}{1,3}(\.{digit}{1,3}){3}"/"{digit}{1,2}	{ return(IPV4_CIDR); }
296 {digit}{1,3}(\.{digit}{1,3}){3}    { return(IPV4_ADDR); }
297 {hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*  { return(IPV6_ADDR); }
298 {hexval}{0,4}":"{hexval}{0,4}":"({hexval}|[:.])*"/"{digit}{1,3}	{ return(IPV6_CIDR); }
299 {digit}+(\.({alnum}|[_.])*)?    { return(VERSION_IDENTIFIER); }
300 #line[ ]1[ ]\"[^\n]*\"		{ set_source_file(yytext+9); }
301 #line[ ]{digit}+	        {
302 				  errno = 0;
303 				  source_lineno = strtoul(yytext+6, NULL, 10) - 1;
304 				  if (errno) {
305 				    yywarn("source line number too big");
306 				  }
307 				}
308 #[^\n]*                         { /* delete comments */ }
309 [ \t\f]+			{ /* delete whitespace */ }
310 "==" 				{ return(EQUALS); }
311 "!="				{ return (NOTEQUAL); }
312 "&&"				{ return (AND); }
313 "||"				{ return (OR); }
314 "!"				{ return (NOT); }
315 "^"                             { return (XOR); }
316 "," |
317 ":" |
318 ";" |
319 "(" |
320 ")" |
321 "{" |
322 "}" |
323 "[" |
324 "-" |
325 "." |
326 "]" |
327 "~" |
328 "*"				{ return(yytext[0]); }
329 .                               { yyerror("unrecognized character");
330 /* Available since bison 3.6, avoids duplicate error message */
331 #ifdef YYerror
332 				  return YYerror;
333 #else
334 				  return INVALID_CHAR;
335 #endif
336 				}
337 %%
338 int yyerror(const char *msg)
339 {
340 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
341 	const char *token;
342 	char buf[8];
343 
344 	if (isprint((unsigned char)yytext[0])) {
345 		token = yytext;
346 	} else {
347 		snprintf(buf, sizeof(buf), "%#x", yytext[0]);
348 		token = buf;
349 	}
350 
351 	if (source_file[0])
352 		fprintf(stderr, "%s:%lu:",
353 			source_file, source_lineno);
354 	else
355 		fprintf(stderr, "(unknown source)::");
356 	fprintf(stderr, "ERROR '%s' at token '%s' on line %lu:\n%s\n%s\n",
357 			msg,
358 			token,
359 			policydb_lineno,
360 			linebuf[0], linebuf[1]);
361 #else
362 	(void)msg;
363 #endif
364 
365 	policydb_errors++;
366 	return -1;
367 }
368 
369 int yywarn(const char *msg)
370 {
371 	if (werror)
372 		return yyerror(msg);
373 
374 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
375 	if (source_file[0])
376 		fprintf(stderr, "%s:%lu:",
377 			source_file, source_lineno);
378 	else
379 		fprintf(stderr, "(unknown source)::");
380 	fprintf(stderr, "WARNING '%s' at token '%s' on line %lu:\n%s\n%s\n",
381 			msg,
382 			yytext,
383 			policydb_lineno,
384 			linebuf[0], linebuf[1]);
385 #endif
386 
387 	return 0;
388 }
389 
390 void set_source_file(const char *name)
391 {
392 	source_lineno = 1;
393 	strncpy(source_file, name, sizeof(source_file)-1);
394 	source_file[sizeof(source_file)-1] = '\0';
395 	if (strlen(source_file) && source_file[strlen(source_file)-1] == '"')
396 		source_file[strlen(source_file)-1] = '\0';
397 }
398