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