xref: /aosp_15_r20/external/selinux/python/sepolgen/src/sepolgen/refparser.py (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker# Authors: Karl MacMillan <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker#
3*2d543d20SAndroid Build Coastguard Worker# Copyright (C) 2006-2007 Red Hat
4*2d543d20SAndroid Build Coastguard Worker# see file 'COPYING' for use and warranty information
5*2d543d20SAndroid Build Coastguard Worker#
6*2d543d20SAndroid Build Coastguard Worker# This program is free software; you can redistribute it and/or
7*2d543d20SAndroid Build Coastguard Worker# modify it under the terms of the GNU General Public License as
8*2d543d20SAndroid Build Coastguard Worker# published by the Free Software Foundation; version 2 only
9*2d543d20SAndroid Build Coastguard Worker#
10*2d543d20SAndroid Build Coastguard Worker# This program is distributed in the hope that it will be useful,
11*2d543d20SAndroid Build Coastguard Worker# but WITHOUT ANY WARRANTY; without even the implied warranty of
12*2d543d20SAndroid Build Coastguard Worker# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*2d543d20SAndroid Build Coastguard Worker# GNU General Public License for more details.
14*2d543d20SAndroid Build Coastguard Worker#
15*2d543d20SAndroid Build Coastguard Worker# You should have received a copy of the GNU General Public License
16*2d543d20SAndroid Build Coastguard Worker# along with this program; if not, write to the Free Software
17*2d543d20SAndroid Build Coastguard Worker# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*2d543d20SAndroid Build Coastguard Worker#
19*2d543d20SAndroid Build Coastguard Worker
20*2d543d20SAndroid Build Coastguard Worker# OVERVIEW
21*2d543d20SAndroid Build Coastguard Worker#
22*2d543d20SAndroid Build Coastguard Worker#
23*2d543d20SAndroid Build Coastguard Worker# This is a parser for the refpolicy policy "language" - i.e., the
24*2d543d20SAndroid Build Coastguard Worker# normal SELinux policy language plus the refpolicy style M4 macro
25*2d543d20SAndroid Build Coastguard Worker# constructs on top of that base language. This parser is primarily
26*2d543d20SAndroid Build Coastguard Worker# aimed at parsing the policy headers in order to create an abstract
27*2d543d20SAndroid Build Coastguard Worker# policy representation suitable for generating policy.
28*2d543d20SAndroid Build Coastguard Worker#
29*2d543d20SAndroid Build Coastguard Worker# Both the lexer and parser are included in this file. The are implemented
30*2d543d20SAndroid Build Coastguard Worker# using the Ply library (included with sepolgen).
31*2d543d20SAndroid Build Coastguard Worker
32*2d543d20SAndroid Build Coastguard Workerimport sys
33*2d543d20SAndroid Build Coastguard Workerimport os
34*2d543d20SAndroid Build Coastguard Workerimport re
35*2d543d20SAndroid Build Coastguard Workerimport traceback
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Workerfrom . import access
38*2d543d20SAndroid Build Coastguard Workerfrom . import defaults
39*2d543d20SAndroid Build Coastguard Workerfrom . import lex
40*2d543d20SAndroid Build Coastguard Workerfrom . import refpolicy
41*2d543d20SAndroid Build Coastguard Workerfrom . import yacc
42*2d543d20SAndroid Build Coastguard Worker
43*2d543d20SAndroid Build Coastguard Worker# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
44*2d543d20SAndroid Build Coastguard Worker#
45*2d543d20SAndroid Build Coastguard Worker# lexer
46*2d543d20SAndroid Build Coastguard Worker#
47*2d543d20SAndroid Build Coastguard Worker# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
48*2d543d20SAndroid Build Coastguard Worker
49*2d543d20SAndroid Build Coastguard Workertokens = (
50*2d543d20SAndroid Build Coastguard Worker    # basic tokens, punctuation
51*2d543d20SAndroid Build Coastguard Worker    'TICK',
52*2d543d20SAndroid Build Coastguard Worker    'SQUOTE',
53*2d543d20SAndroid Build Coastguard Worker    'OBRACE',
54*2d543d20SAndroid Build Coastguard Worker    'CBRACE',
55*2d543d20SAndroid Build Coastguard Worker    'SEMI',
56*2d543d20SAndroid Build Coastguard Worker    'COLON',
57*2d543d20SAndroid Build Coastguard Worker    'OPAREN',
58*2d543d20SAndroid Build Coastguard Worker    'CPAREN',
59*2d543d20SAndroid Build Coastguard Worker    'COMMA',
60*2d543d20SAndroid Build Coastguard Worker    'MINUS',
61*2d543d20SAndroid Build Coastguard Worker    'TILDE',
62*2d543d20SAndroid Build Coastguard Worker    'ASTERISK',
63*2d543d20SAndroid Build Coastguard Worker    'AMP',
64*2d543d20SAndroid Build Coastguard Worker    'BAR',
65*2d543d20SAndroid Build Coastguard Worker    'EXPL',
66*2d543d20SAndroid Build Coastguard Worker    'EQUAL',
67*2d543d20SAndroid Build Coastguard Worker    'FILENAME',
68*2d543d20SAndroid Build Coastguard Worker    'IDENTIFIER',
69*2d543d20SAndroid Build Coastguard Worker    'NUMBER',
70*2d543d20SAndroid Build Coastguard Worker    'PATH',
71*2d543d20SAndroid Build Coastguard Worker    'IPV6_ADDR',
72*2d543d20SAndroid Build Coastguard Worker    # reserved words
73*2d543d20SAndroid Build Coastguard Worker    #   module
74*2d543d20SAndroid Build Coastguard Worker    'MODULE',
75*2d543d20SAndroid Build Coastguard Worker    'POLICY_MODULE',
76*2d543d20SAndroid Build Coastguard Worker    'REQUIRE',
77*2d543d20SAndroid Build Coastguard Worker    #   flask
78*2d543d20SAndroid Build Coastguard Worker    'SID',
79*2d543d20SAndroid Build Coastguard Worker    'GENFSCON',
80*2d543d20SAndroid Build Coastguard Worker    'FS_USE_XATTR',
81*2d543d20SAndroid Build Coastguard Worker    'FS_USE_TRANS',
82*2d543d20SAndroid Build Coastguard Worker    'FS_USE_TASK',
83*2d543d20SAndroid Build Coastguard Worker    'PORTCON',
84*2d543d20SAndroid Build Coastguard Worker    'NODECON',
85*2d543d20SAndroid Build Coastguard Worker    'NETIFCON',
86*2d543d20SAndroid Build Coastguard Worker    'PIRQCON',
87*2d543d20SAndroid Build Coastguard Worker    'IOMEMCON',
88*2d543d20SAndroid Build Coastguard Worker    'IOPORTCON',
89*2d543d20SAndroid Build Coastguard Worker    'PCIDEVICECON',
90*2d543d20SAndroid Build Coastguard Worker    'DEVICETREECON',
91*2d543d20SAndroid Build Coastguard Worker    #   object classes
92*2d543d20SAndroid Build Coastguard Worker    'CLASS',
93*2d543d20SAndroid Build Coastguard Worker    #   types and attributes
94*2d543d20SAndroid Build Coastguard Worker    'TYPEATTRIBUTE',
95*2d543d20SAndroid Build Coastguard Worker    'ROLEATTRIBUTE',
96*2d543d20SAndroid Build Coastguard Worker    'TYPE',
97*2d543d20SAndroid Build Coastguard Worker    'ATTRIBUTE',
98*2d543d20SAndroid Build Coastguard Worker    'ATTRIBUTE_ROLE',
99*2d543d20SAndroid Build Coastguard Worker    'ALIAS',
100*2d543d20SAndroid Build Coastguard Worker    'TYPEALIAS',
101*2d543d20SAndroid Build Coastguard Worker    #   conditional policy
102*2d543d20SAndroid Build Coastguard Worker    'BOOL',
103*2d543d20SAndroid Build Coastguard Worker    'TRUE',
104*2d543d20SAndroid Build Coastguard Worker    'FALSE',
105*2d543d20SAndroid Build Coastguard Worker    'IF',
106*2d543d20SAndroid Build Coastguard Worker    'ELSE',
107*2d543d20SAndroid Build Coastguard Worker    #   users and roles
108*2d543d20SAndroid Build Coastguard Worker    'ROLE',
109*2d543d20SAndroid Build Coastguard Worker    'TYPES',
110*2d543d20SAndroid Build Coastguard Worker    #   rules
111*2d543d20SAndroid Build Coastguard Worker    'ALLOW',
112*2d543d20SAndroid Build Coastguard Worker    'DONTAUDIT',
113*2d543d20SAndroid Build Coastguard Worker    'AUDITALLOW',
114*2d543d20SAndroid Build Coastguard Worker    'NEVERALLOW',
115*2d543d20SAndroid Build Coastguard Worker    'PERMISSIVE',
116*2d543d20SAndroid Build Coastguard Worker    'TYPEBOUNDS',
117*2d543d20SAndroid Build Coastguard Worker    'TYPE_TRANSITION',
118*2d543d20SAndroid Build Coastguard Worker    'TYPE_CHANGE',
119*2d543d20SAndroid Build Coastguard Worker    'TYPE_MEMBER',
120*2d543d20SAndroid Build Coastguard Worker    'RANGE_TRANSITION',
121*2d543d20SAndroid Build Coastguard Worker    'ROLE_TRANSITION',
122*2d543d20SAndroid Build Coastguard Worker    #   refpolicy keywords
123*2d543d20SAndroid Build Coastguard Worker    'OPT_POLICY',
124*2d543d20SAndroid Build Coastguard Worker    'INTERFACE',
125*2d543d20SAndroid Build Coastguard Worker    'TUNABLE_POLICY',
126*2d543d20SAndroid Build Coastguard Worker    'GEN_REQ',
127*2d543d20SAndroid Build Coastguard Worker    'TEMPLATE',
128*2d543d20SAndroid Build Coastguard Worker    'GEN_CONTEXT',
129*2d543d20SAndroid Build Coastguard Worker    'GEN_TUNABLE',
130*2d543d20SAndroid Build Coastguard Worker    #   m4
131*2d543d20SAndroid Build Coastguard Worker    'IFELSE',
132*2d543d20SAndroid Build Coastguard Worker    'IFDEF',
133*2d543d20SAndroid Build Coastguard Worker    'IFNDEF',
134*2d543d20SAndroid Build Coastguard Worker    'DEFINE'
135*2d543d20SAndroid Build Coastguard Worker    )
136*2d543d20SAndroid Build Coastguard Worker
137*2d543d20SAndroid Build Coastguard Worker# All reserved keywords - see t_IDENTIFIER for how these are matched in
138*2d543d20SAndroid Build Coastguard Worker# the lexer.
139*2d543d20SAndroid Build Coastguard Workerreserved = {
140*2d543d20SAndroid Build Coastguard Worker    # module
141*2d543d20SAndroid Build Coastguard Worker    'module' : 'MODULE',
142*2d543d20SAndroid Build Coastguard Worker    'policy_module' : 'POLICY_MODULE',
143*2d543d20SAndroid Build Coastguard Worker    'require' : 'REQUIRE',
144*2d543d20SAndroid Build Coastguard Worker    # flask
145*2d543d20SAndroid Build Coastguard Worker    'sid' : 'SID',
146*2d543d20SAndroid Build Coastguard Worker    'genfscon' : 'GENFSCON',
147*2d543d20SAndroid Build Coastguard Worker    'fs_use_xattr' : 'FS_USE_XATTR',
148*2d543d20SAndroid Build Coastguard Worker    'fs_use_trans' : 'FS_USE_TRANS',
149*2d543d20SAndroid Build Coastguard Worker    'fs_use_task' : 'FS_USE_TASK',
150*2d543d20SAndroid Build Coastguard Worker    'portcon' : 'PORTCON',
151*2d543d20SAndroid Build Coastguard Worker    'nodecon' : 'NODECON',
152*2d543d20SAndroid Build Coastguard Worker    'netifcon' : 'NETIFCON',
153*2d543d20SAndroid Build Coastguard Worker    'pirqcon' : 'PIRQCON',
154*2d543d20SAndroid Build Coastguard Worker    'iomemcon' : 'IOMEMCON',
155*2d543d20SAndroid Build Coastguard Worker    'ioportcon' : 'IOPORTCON',
156*2d543d20SAndroid Build Coastguard Worker    'pcidevicecon' : 'PCIDEVICECON',
157*2d543d20SAndroid Build Coastguard Worker    'devicetreecon' : 'DEVICETREECON',
158*2d543d20SAndroid Build Coastguard Worker    # object classes
159*2d543d20SAndroid Build Coastguard Worker    'class' : 'CLASS',
160*2d543d20SAndroid Build Coastguard Worker    # types and attributes
161*2d543d20SAndroid Build Coastguard Worker    'typeattribute' : 'TYPEATTRIBUTE',
162*2d543d20SAndroid Build Coastguard Worker    'roleattribute' : 'ROLEATTRIBUTE',
163*2d543d20SAndroid Build Coastguard Worker    'type' : 'TYPE',
164*2d543d20SAndroid Build Coastguard Worker    'attribute' : 'ATTRIBUTE',
165*2d543d20SAndroid Build Coastguard Worker    'attribute_role' : 'ATTRIBUTE_ROLE',
166*2d543d20SAndroid Build Coastguard Worker    'alias' : 'ALIAS',
167*2d543d20SAndroid Build Coastguard Worker    'typealias' : 'TYPEALIAS',
168*2d543d20SAndroid Build Coastguard Worker    # conditional policy
169*2d543d20SAndroid Build Coastguard Worker    'bool' : 'BOOL',
170*2d543d20SAndroid Build Coastguard Worker    'true' : 'TRUE',
171*2d543d20SAndroid Build Coastguard Worker    'false' : 'FALSE',
172*2d543d20SAndroid Build Coastguard Worker    'if' : 'IF',
173*2d543d20SAndroid Build Coastguard Worker    'else' : 'ELSE',
174*2d543d20SAndroid Build Coastguard Worker    # users and roles
175*2d543d20SAndroid Build Coastguard Worker    'role' : 'ROLE',
176*2d543d20SAndroid Build Coastguard Worker    'types' : 'TYPES',
177*2d543d20SAndroid Build Coastguard Worker    # rules
178*2d543d20SAndroid Build Coastguard Worker    'allow' : 'ALLOW',
179*2d543d20SAndroid Build Coastguard Worker    'dontaudit' : 'DONTAUDIT',
180*2d543d20SAndroid Build Coastguard Worker    'auditallow' : 'AUDITALLOW',
181*2d543d20SAndroid Build Coastguard Worker    'neverallow' : 'NEVERALLOW',
182*2d543d20SAndroid Build Coastguard Worker    'permissive' : 'PERMISSIVE',
183*2d543d20SAndroid Build Coastguard Worker    'typebounds' : 'TYPEBOUNDS',
184*2d543d20SAndroid Build Coastguard Worker    'type_transition' : 'TYPE_TRANSITION',
185*2d543d20SAndroid Build Coastguard Worker    'type_change' : 'TYPE_CHANGE',
186*2d543d20SAndroid Build Coastguard Worker    'type_member' : 'TYPE_MEMBER',
187*2d543d20SAndroid Build Coastguard Worker    'range_transition' : 'RANGE_TRANSITION',
188*2d543d20SAndroid Build Coastguard Worker    'role_transition' : 'ROLE_TRANSITION',
189*2d543d20SAndroid Build Coastguard Worker    # refpolicy keywords
190*2d543d20SAndroid Build Coastguard Worker    'optional_policy' : 'OPT_POLICY',
191*2d543d20SAndroid Build Coastguard Worker    'interface' : 'INTERFACE',
192*2d543d20SAndroid Build Coastguard Worker    'tunable_policy' : 'TUNABLE_POLICY',
193*2d543d20SAndroid Build Coastguard Worker    'gen_require' : 'GEN_REQ',
194*2d543d20SAndroid Build Coastguard Worker    'template' : 'TEMPLATE',
195*2d543d20SAndroid Build Coastguard Worker    'gen_context' : 'GEN_CONTEXT',
196*2d543d20SAndroid Build Coastguard Worker    'gen_tunable' : 'GEN_TUNABLE',
197*2d543d20SAndroid Build Coastguard Worker    # M4
198*2d543d20SAndroid Build Coastguard Worker    'ifelse' : 'IFELSE',
199*2d543d20SAndroid Build Coastguard Worker    'ifndef' : 'IFNDEF',
200*2d543d20SAndroid Build Coastguard Worker    'ifdef' : 'IFDEF',
201*2d543d20SAndroid Build Coastguard Worker    'define' : 'DEFINE'
202*2d543d20SAndroid Build Coastguard Worker    }
203*2d543d20SAndroid Build Coastguard Worker
204*2d543d20SAndroid Build Coastguard Worker# The ply lexer allows definition of tokens in 2 ways: regular expressions
205*2d543d20SAndroid Build Coastguard Worker# or functions.
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker# Simple regex tokens
208*2d543d20SAndroid Build Coastguard Workert_TICK      = r'\`'
209*2d543d20SAndroid Build Coastguard Workert_SQUOTE    = r'\''
210*2d543d20SAndroid Build Coastguard Workert_OBRACE    = r'\{'
211*2d543d20SAndroid Build Coastguard Workert_CBRACE    = r'\}'
212*2d543d20SAndroid Build Coastguard Worker# This will handle spurious extra ';' via the +
213*2d543d20SAndroid Build Coastguard Workert_SEMI      = r'\;+'
214*2d543d20SAndroid Build Coastguard Workert_COLON     = r'\:'
215*2d543d20SAndroid Build Coastguard Workert_OPAREN    = r'\('
216*2d543d20SAndroid Build Coastguard Workert_CPAREN    = r'\)'
217*2d543d20SAndroid Build Coastguard Workert_COMMA     = r'\,'
218*2d543d20SAndroid Build Coastguard Workert_MINUS     = r'\-'
219*2d543d20SAndroid Build Coastguard Workert_TILDE     = r'\~'
220*2d543d20SAndroid Build Coastguard Workert_ASTERISK  = r'\*'
221*2d543d20SAndroid Build Coastguard Workert_AMP       = r'\&'
222*2d543d20SAndroid Build Coastguard Workert_BAR       = r'\|'
223*2d543d20SAndroid Build Coastguard Workert_EXPL      = r'\!'
224*2d543d20SAndroid Build Coastguard Workert_EQUAL     = r'\='
225*2d543d20SAndroid Build Coastguard Workert_NUMBER    = r'[0-9\.]+'
226*2d543d20SAndroid Build Coastguard Workert_PATH      = r'/[a-zA-Z0-9)_\.\*/\$]*'
227*2d543d20SAndroid Build Coastguard Worker#t_IPV6_ADDR = r'[a-fA-F0-9]{0,4}:[a-fA-F0-9]{0,4}:([a-fA-F0-9]{0,4}:)*'
228*2d543d20SAndroid Build Coastguard Worker
229*2d543d20SAndroid Build Coastguard Worker# Ignore whitespace - this is a special token for ply that more efficiently
230*2d543d20SAndroid Build Coastguard Worker# ignores uninteresting tokens.
231*2d543d20SAndroid Build Coastguard Workert_ignore    = " \t"
232*2d543d20SAndroid Build Coastguard Worker
233*2d543d20SAndroid Build Coastguard Worker# More complex tokens
234*2d543d20SAndroid Build Coastguard Workerdef t_IPV6_ADDR(t):
235*2d543d20SAndroid Build Coastguard Worker    r'[a-fA-F0-9]{0,4}:[a-fA-F0-9]{0,4}:([a-fA-F0-9]|:)*'
236*2d543d20SAndroid Build Coastguard Worker    # This is a function simply to force it sooner into
237*2d543d20SAndroid Build Coastguard Worker    # the regex list
238*2d543d20SAndroid Build Coastguard Worker    return t
239*2d543d20SAndroid Build Coastguard Worker
240*2d543d20SAndroid Build Coastguard Workerdef t_m4comment(t):
241*2d543d20SAndroid Build Coastguard Worker    r'dnl.*\n'
242*2d543d20SAndroid Build Coastguard Worker    # Ignore all comments
243*2d543d20SAndroid Build Coastguard Worker    t.lexer.lineno += 1
244*2d543d20SAndroid Build Coastguard Worker
245*2d543d20SAndroid Build Coastguard Workerdef t_refpolicywarn1(t):
246*2d543d20SAndroid Build Coastguard Worker    r'define.*refpolicywarn\(.*\n'
247*2d543d20SAndroid Build Coastguard Worker    # Ignore refpolicywarn statements - they sometimes
248*2d543d20SAndroid Build Coastguard Worker    # contain text that we can't parse.
249*2d543d20SAndroid Build Coastguard Worker    t.skip(1)
250*2d543d20SAndroid Build Coastguard Worker
251*2d543d20SAndroid Build Coastguard Workerdef t_refpolicywarn(t):
252*2d543d20SAndroid Build Coastguard Worker    r'refpolicywarn\(.*\n'
253*2d543d20SAndroid Build Coastguard Worker    # Ignore refpolicywarn statements - they sometimes
254*2d543d20SAndroid Build Coastguard Worker    # contain text that we can't parse.
255*2d543d20SAndroid Build Coastguard Worker    t.lexer.lineno += 1
256*2d543d20SAndroid Build Coastguard Worker
257*2d543d20SAndroid Build Coastguard Workerdef t_IDENTIFIER(t):
258*2d543d20SAndroid Build Coastguard Worker    r'[a-zA-Z_\$][a-zA-Z0-9_\-\+\.\$\*~]*'
259*2d543d20SAndroid Build Coastguard Worker    # Handle any keywords
260*2d543d20SAndroid Build Coastguard Worker    t.type = reserved.get(t.value,'IDENTIFIER')
261*2d543d20SAndroid Build Coastguard Worker    return t
262*2d543d20SAndroid Build Coastguard Worker
263*2d543d20SAndroid Build Coastguard Workerdef t_FILENAME(t):
264*2d543d20SAndroid Build Coastguard Worker    r'\"[a-zA-Z0-9_\-\+\.\$\*~ :\[\]]+\"'
265*2d543d20SAndroid Build Coastguard Worker    # Handle any keywords
266*2d543d20SAndroid Build Coastguard Worker    t.type = reserved.get(t.value,'FILENAME')
267*2d543d20SAndroid Build Coastguard Worker    return t
268*2d543d20SAndroid Build Coastguard Worker
269*2d543d20SAndroid Build Coastguard Workerdef t_comment(t):
270*2d543d20SAndroid Build Coastguard Worker    r'\#.*\n'
271*2d543d20SAndroid Build Coastguard Worker    # Ignore all comments
272*2d543d20SAndroid Build Coastguard Worker    t.lexer.lineno += 1
273*2d543d20SAndroid Build Coastguard Worker
274*2d543d20SAndroid Build Coastguard Workerdef t_error(t):
275*2d543d20SAndroid Build Coastguard Worker    print("Illegal character '%s'" % t.value[0])
276*2d543d20SAndroid Build Coastguard Worker    t.skip(1)
277*2d543d20SAndroid Build Coastguard Worker
278*2d543d20SAndroid Build Coastguard Workerdef t_newline(t):
279*2d543d20SAndroid Build Coastguard Worker    r'\n+'
280*2d543d20SAndroid Build Coastguard Worker    t.lexer.lineno += len(t.value)
281*2d543d20SAndroid Build Coastguard Worker
282*2d543d20SAndroid Build Coastguard Worker# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
283*2d543d20SAndroid Build Coastguard Worker#
284*2d543d20SAndroid Build Coastguard Worker# Parser
285*2d543d20SAndroid Build Coastguard Worker#
286*2d543d20SAndroid Build Coastguard Worker# :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
287*2d543d20SAndroid Build Coastguard Worker
288*2d543d20SAndroid Build Coastguard Worker# Global data used during parsing - making it global is easier than
289*2d543d20SAndroid Build Coastguard Worker# passing the state through the parsing functions.
290*2d543d20SAndroid Build Coastguard Worker
291*2d543d20SAndroid Build Coastguard Worker#   m is the top-level data structure (stands for modules).
292*2d543d20SAndroid Build Coastguard Workerm = None
293*2d543d20SAndroid Build Coastguard Worker#   error is either None (indicating no error) or a string error message.
294*2d543d20SAndroid Build Coastguard Workererror = None
295*2d543d20SAndroid Build Coastguard Workerparse_file = ""
296*2d543d20SAndroid Build Coastguard Worker#   spt is the support macros (e.g., obj/perm sets) - it is an instance of
297*2d543d20SAndroid Build Coastguard Worker#     refpolicy.SupportMacros and should always be present during parsing
298*2d543d20SAndroid Build Coastguard Worker#     though it may not contain any macros.
299*2d543d20SAndroid Build Coastguard Workerspt = None
300*2d543d20SAndroid Build Coastguard Workersuccess = True
301*2d543d20SAndroid Build Coastguard Worker
302*2d543d20SAndroid Build Coastguard Worker# utilities
303*2d543d20SAndroid Build Coastguard Workerdef collect(stmts, parent, val=None):
304*2d543d20SAndroid Build Coastguard Worker    if stmts is None:
305*2d543d20SAndroid Build Coastguard Worker        return
306*2d543d20SAndroid Build Coastguard Worker    for s in stmts:
307*2d543d20SAndroid Build Coastguard Worker        if s is None:
308*2d543d20SAndroid Build Coastguard Worker            continue
309*2d543d20SAndroid Build Coastguard Worker        s.parent = parent
310*2d543d20SAndroid Build Coastguard Worker        if val is not None:
311*2d543d20SAndroid Build Coastguard Worker            parent.children.insert(0, (val, s))
312*2d543d20SAndroid Build Coastguard Worker        else:
313*2d543d20SAndroid Build Coastguard Worker            parent.children.insert(0, s)
314*2d543d20SAndroid Build Coastguard Worker
315*2d543d20SAndroid Build Coastguard Workerdef expand(ids, s):
316*2d543d20SAndroid Build Coastguard Worker    for id in ids:
317*2d543d20SAndroid Build Coastguard Worker        if spt.has_key(id):  # noqa
318*2d543d20SAndroid Build Coastguard Worker            s.update(spt.by_name(id))
319*2d543d20SAndroid Build Coastguard Worker        else:
320*2d543d20SAndroid Build Coastguard Worker            s.add(id)
321*2d543d20SAndroid Build Coastguard Worker
322*2d543d20SAndroid Build Coastguard Worker# Top-level non-terminal
323*2d543d20SAndroid Build Coastguard Workerdef p_statements(p):
324*2d543d20SAndroid Build Coastguard Worker    '''statements : statement
325*2d543d20SAndroid Build Coastguard Worker                  | statements statement
326*2d543d20SAndroid Build Coastguard Worker                  | empty
327*2d543d20SAndroid Build Coastguard Worker    '''
328*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2 and p[1]:
329*2d543d20SAndroid Build Coastguard Worker        m.children.append(p[1])
330*2d543d20SAndroid Build Coastguard Worker    elif len(p) > 2 and p[2]:
331*2d543d20SAndroid Build Coastguard Worker        m.children.append(p[2])
332*2d543d20SAndroid Build Coastguard Worker
333*2d543d20SAndroid Build Coastguard Workerdef p_statement(p):
334*2d543d20SAndroid Build Coastguard Worker    '''statement : interface
335*2d543d20SAndroid Build Coastguard Worker                 | template
336*2d543d20SAndroid Build Coastguard Worker                 | obj_perm_set
337*2d543d20SAndroid Build Coastguard Worker                 | policy
338*2d543d20SAndroid Build Coastguard Worker                 | policy_module_stmt
339*2d543d20SAndroid Build Coastguard Worker                 | module_stmt
340*2d543d20SAndroid Build Coastguard Worker    '''
341*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
342*2d543d20SAndroid Build Coastguard Worker
343*2d543d20SAndroid Build Coastguard Workerdef p_empty(p):
344*2d543d20SAndroid Build Coastguard Worker    'empty :'
345*2d543d20SAndroid Build Coastguard Worker    pass
346*2d543d20SAndroid Build Coastguard Worker
347*2d543d20SAndroid Build Coastguard Worker#
348*2d543d20SAndroid Build Coastguard Worker# Reference policy language constructs
349*2d543d20SAndroid Build Coastguard Worker#
350*2d543d20SAndroid Build Coastguard Worker
351*2d543d20SAndroid Build Coastguard Worker# This is for the policy module statement (e.g., policy_module(foo,1.2.0)).
352*2d543d20SAndroid Build Coastguard Worker# We have a separate terminal for either the basic language module statement
353*2d543d20SAndroid Build Coastguard Worker# and interface calls to make it easier to identifier.
354*2d543d20SAndroid Build Coastguard Workerdef p_policy_module_stmt(p):
355*2d543d20SAndroid Build Coastguard Worker    'policy_module_stmt : POLICY_MODULE OPAREN IDENTIFIER COMMA NUMBER CPAREN'
356*2d543d20SAndroid Build Coastguard Worker    m = refpolicy.ModuleDeclaration()
357*2d543d20SAndroid Build Coastguard Worker    m.name = p[3]
358*2d543d20SAndroid Build Coastguard Worker    m.version = p[5]
359*2d543d20SAndroid Build Coastguard Worker    m.refpolicy = True
360*2d543d20SAndroid Build Coastguard Worker    p[0] = m
361*2d543d20SAndroid Build Coastguard Worker
362*2d543d20SAndroid Build Coastguard Workerdef p_interface(p):
363*2d543d20SAndroid Build Coastguard Worker    '''interface : INTERFACE OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
364*2d543d20SAndroid Build Coastguard Worker    '''
365*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.Interface(p[4])
366*2d543d20SAndroid Build Coastguard Worker    collect(p[8], x)
367*2d543d20SAndroid Build Coastguard Worker    p[0] = x
368*2d543d20SAndroid Build Coastguard Worker
369*2d543d20SAndroid Build Coastguard Workerdef p_template(p):
370*2d543d20SAndroid Build Coastguard Worker    '''template : TEMPLATE OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
371*2d543d20SAndroid Build Coastguard Worker                | DEFINE OPAREN TICK IDENTIFIER SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
372*2d543d20SAndroid Build Coastguard Worker    '''
373*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.Template(p[4])
374*2d543d20SAndroid Build Coastguard Worker    collect(p[8], x)
375*2d543d20SAndroid Build Coastguard Worker    p[0] = x
376*2d543d20SAndroid Build Coastguard Worker
377*2d543d20SAndroid Build Coastguard Workerdef p_define(p):
378*2d543d20SAndroid Build Coastguard Worker    '''define : DEFINE OPAREN TICK IDENTIFIER SQUOTE CPAREN'''
379*2d543d20SAndroid Build Coastguard Worker    # This is for defining single M4 values (to be used later in ifdef statements).
380*2d543d20SAndroid Build Coastguard Worker    # Example: define(`sulogin_no_pam'). We don't currently do anything with these
381*2d543d20SAndroid Build Coastguard Worker    # but we should in the future when we correctly resolve ifdef statements.
382*2d543d20SAndroid Build Coastguard Worker    p[0] = None
383*2d543d20SAndroid Build Coastguard Worker
384*2d543d20SAndroid Build Coastguard Workerdef p_interface_stmts(p):
385*2d543d20SAndroid Build Coastguard Worker    '''interface_stmts : policy
386*2d543d20SAndroid Build Coastguard Worker                       | interface_stmts policy
387*2d543d20SAndroid Build Coastguard Worker                       | empty
388*2d543d20SAndroid Build Coastguard Worker    '''
389*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2 and p[1]:
390*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1]
391*2d543d20SAndroid Build Coastguard Worker    elif len(p) > 2:
392*2d543d20SAndroid Build Coastguard Worker        if not p[1]:
393*2d543d20SAndroid Build Coastguard Worker            if p[2]:
394*2d543d20SAndroid Build Coastguard Worker                p[0] = p[2]
395*2d543d20SAndroid Build Coastguard Worker        elif not p[2]:
396*2d543d20SAndroid Build Coastguard Worker            p[0] = p[1]
397*2d543d20SAndroid Build Coastguard Worker        else:
398*2d543d20SAndroid Build Coastguard Worker            p[0] = p[1] + p[2]
399*2d543d20SAndroid Build Coastguard Worker
400*2d543d20SAndroid Build Coastguard Workerdef p_optional_policy(p):
401*2d543d20SAndroid Build Coastguard Worker    '''optional_policy : OPT_POLICY OPAREN TICK interface_stmts SQUOTE CPAREN
402*2d543d20SAndroid Build Coastguard Worker                       | OPT_POLICY OPAREN TICK interface_stmts SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
403*2d543d20SAndroid Build Coastguard Worker    '''
404*2d543d20SAndroid Build Coastguard Worker    o = refpolicy.OptionalPolicy()
405*2d543d20SAndroid Build Coastguard Worker    collect(p[4], o, val=True)
406*2d543d20SAndroid Build Coastguard Worker    if len(p) > 7:
407*2d543d20SAndroid Build Coastguard Worker        collect(p[8], o, val=False)
408*2d543d20SAndroid Build Coastguard Worker    p[0] = [o]
409*2d543d20SAndroid Build Coastguard Worker
410*2d543d20SAndroid Build Coastguard Workerdef p_tunable_policy(p):
411*2d543d20SAndroid Build Coastguard Worker    '''tunable_policy : TUNABLE_POLICY OPAREN TICK cond_expr SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
412*2d543d20SAndroid Build Coastguard Worker                      | TUNABLE_POLICY OPAREN TICK cond_expr SQUOTE COMMA TICK interface_stmts SQUOTE COMMA TICK interface_stmts SQUOTE CPAREN
413*2d543d20SAndroid Build Coastguard Worker    '''
414*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.TunablePolicy()
415*2d543d20SAndroid Build Coastguard Worker    x.cond_expr = p[4]
416*2d543d20SAndroid Build Coastguard Worker    collect(p[8], x, val=True)
417*2d543d20SAndroid Build Coastguard Worker    if len(p) > 11:
418*2d543d20SAndroid Build Coastguard Worker        collect(p[12], x, val=False)
419*2d543d20SAndroid Build Coastguard Worker    p[0] = [x]
420*2d543d20SAndroid Build Coastguard Worker
421*2d543d20SAndroid Build Coastguard Workerdef p_ifelse_compare_value(p):
422*2d543d20SAndroid Build Coastguard Worker    '''ifelse_compare_value : TICK IDENTIFIER SQUOTE
423*2d543d20SAndroid Build Coastguard Worker                            | TICK TRUE       SQUOTE
424*2d543d20SAndroid Build Coastguard Worker                            | TICK FALSE      SQUOTE
425*2d543d20SAndroid Build Coastguard Worker                            | TICK            SQUOTE
426*2d543d20SAndroid Build Coastguard Worker                            | empty
427*2d543d20SAndroid Build Coastguard Worker    '''
428*2d543d20SAndroid Build Coastguard Worker    if len(p) == 4:
429*2d543d20SAndroid Build Coastguard Worker        p[0] = p[2]
430*2d543d20SAndroid Build Coastguard Worker    else:
431*2d543d20SAndroid Build Coastguard Worker        p[0] = None
432*2d543d20SAndroid Build Coastguard Worker
433*2d543d20SAndroid Build Coastguard Workerdef p_ifelse_section(p):
434*2d543d20SAndroid Build Coastguard Worker    '''ifelse_section : TICK IDENTIFIER SQUOTE COMMA ifelse_compare_value COMMA TICK interface_stmts SQUOTE
435*2d543d20SAndroid Build Coastguard Worker    '''
436*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.IfElse(p[2])
437*2d543d20SAndroid Build Coastguard Worker    collect(p[8], x, val=True)
438*2d543d20SAndroid Build Coastguard Worker    p[0] = [x]
439*2d543d20SAndroid Build Coastguard Worker
440*2d543d20SAndroid Build Coastguard Workerdef p_ifelse_sections(p):
441*2d543d20SAndroid Build Coastguard Worker    '''ifelse_sections : ifelse_sections COMMA ifelse_section
442*2d543d20SAndroid Build Coastguard Worker                       | ifelse_section
443*2d543d20SAndroid Build Coastguard Worker    '''
444*2d543d20SAndroid Build Coastguard Worker    if len(p) == 4:
445*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1] + p[3]
446*2d543d20SAndroid Build Coastguard Worker    else:
447*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1]
448*2d543d20SAndroid Build Coastguard Worker
449*2d543d20SAndroid Build Coastguard Workerdef p_ifelse(p):
450*2d543d20SAndroid Build Coastguard Worker    '''ifelse : IFELSE OPAREN ifelse_sections COMMA TICK interface_stmts SQUOTE CPAREN optional_semi
451*2d543d20SAndroid Build Coastguard Worker    '''
452*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.IfElse(p[3])
453*2d543d20SAndroid Build Coastguard Worker    collect(p[3], x, val=True)
454*2d543d20SAndroid Build Coastguard Worker    collect(p[6], x, val=False)
455*2d543d20SAndroid Build Coastguard Worker    p[0] = [x]
456*2d543d20SAndroid Build Coastguard Worker
457*2d543d20SAndroid Build Coastguard Workerdef p_ifdef(p):
458*2d543d20SAndroid Build Coastguard Worker    '''ifdef : IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi
459*2d543d20SAndroid Build Coastguard Worker             | IFNDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi
460*2d543d20SAndroid Build Coastguard Worker             | IFDEF OPAREN TICK IDENTIFIER SQUOTE COMMA TICK statements SQUOTE COMMA TICK statements SQUOTE CPAREN optional_semi
461*2d543d20SAndroid Build Coastguard Worker    '''
462*2d543d20SAndroid Build Coastguard Worker    x = refpolicy.IfDef(p[4])
463*2d543d20SAndroid Build Coastguard Worker    if p[1] == 'ifdef':
464*2d543d20SAndroid Build Coastguard Worker        v = True
465*2d543d20SAndroid Build Coastguard Worker    else:
466*2d543d20SAndroid Build Coastguard Worker        v = False
467*2d543d20SAndroid Build Coastguard Worker    collect(p[8], x, val=v)
468*2d543d20SAndroid Build Coastguard Worker    if len(p) > 12:
469*2d543d20SAndroid Build Coastguard Worker        collect(p[12], x, val=False)
470*2d543d20SAndroid Build Coastguard Worker    p[0] = [x]
471*2d543d20SAndroid Build Coastguard Worker
472*2d543d20SAndroid Build Coastguard Workerdef p_interface_call(p):
473*2d543d20SAndroid Build Coastguard Worker    '''interface_call : IDENTIFIER OPAREN interface_call_param_list CPAREN
474*2d543d20SAndroid Build Coastguard Worker                      | IDENTIFIER OPAREN CPAREN
475*2d543d20SAndroid Build Coastguard Worker                      | IDENTIFIER OPAREN interface_call_param_list CPAREN SEMI'''
476*2d543d20SAndroid Build Coastguard Worker    # Allow spurious semi-colons at the end of interface calls
477*2d543d20SAndroid Build Coastguard Worker    i = refpolicy.InterfaceCall(ifname=p[1])
478*2d543d20SAndroid Build Coastguard Worker    if len(p) > 4:
479*2d543d20SAndroid Build Coastguard Worker        i.args.extend(p[3])
480*2d543d20SAndroid Build Coastguard Worker    p[0] = i
481*2d543d20SAndroid Build Coastguard Worker
482*2d543d20SAndroid Build Coastguard Workerdef p_interface_call_param(p):
483*2d543d20SAndroid Build Coastguard Worker    '''interface_call_param : IDENTIFIER
484*2d543d20SAndroid Build Coastguard Worker                            | IDENTIFIER MINUS IDENTIFIER
485*2d543d20SAndroid Build Coastguard Worker                            | MINUS IDENTIFIER
486*2d543d20SAndroid Build Coastguard Worker                            | nested_id_set
487*2d543d20SAndroid Build Coastguard Worker                            | TRUE
488*2d543d20SAndroid Build Coastguard Worker                            | FALSE
489*2d543d20SAndroid Build Coastguard Worker                            | FILENAME
490*2d543d20SAndroid Build Coastguard Worker    '''
491*2d543d20SAndroid Build Coastguard Worker    # Intentionally let single identifiers pass through
492*2d543d20SAndroid Build Coastguard Worker    # List means set, non-list identifier
493*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2:
494*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1]
495*2d543d20SAndroid Build Coastguard Worker    elif len(p) == 3:
496*2d543d20SAndroid Build Coastguard Worker        p[0] = "-" + p[2]
497*2d543d20SAndroid Build Coastguard Worker    else:
498*2d543d20SAndroid Build Coastguard Worker        p[0] = [p[1], "-" + p[3]]
499*2d543d20SAndroid Build Coastguard Worker
500*2d543d20SAndroid Build Coastguard Workerdef p_interface_call_param_list(p):
501*2d543d20SAndroid Build Coastguard Worker    '''interface_call_param_list : interface_call_param
502*2d543d20SAndroid Build Coastguard Worker                                 | interface_call_param_list COMMA interface_call_param
503*2d543d20SAndroid Build Coastguard Worker    '''
504*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2:
505*2d543d20SAndroid Build Coastguard Worker        p[0] = [p[1]]
506*2d543d20SAndroid Build Coastguard Worker    else:
507*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1] + [p[3]]
508*2d543d20SAndroid Build Coastguard Worker
509*2d543d20SAndroid Build Coastguard Worker
510*2d543d20SAndroid Build Coastguard Workerdef p_obj_perm_set(p):
511*2d543d20SAndroid Build Coastguard Worker    'obj_perm_set : DEFINE OPAREN TICK IDENTIFIER SQUOTE COMMA TICK names SQUOTE CPAREN'
512*2d543d20SAndroid Build Coastguard Worker    s = refpolicy.ObjPermSet(p[4])
513*2d543d20SAndroid Build Coastguard Worker    s.perms = p[8]
514*2d543d20SAndroid Build Coastguard Worker    p[0] = s
515*2d543d20SAndroid Build Coastguard Worker
516*2d543d20SAndroid Build Coastguard Worker#
517*2d543d20SAndroid Build Coastguard Worker# Basic SELinux policy language
518*2d543d20SAndroid Build Coastguard Worker#
519*2d543d20SAndroid Build Coastguard Worker
520*2d543d20SAndroid Build Coastguard Workerdef p_policy(p):
521*2d543d20SAndroid Build Coastguard Worker    '''policy : policy_stmt
522*2d543d20SAndroid Build Coastguard Worker              | optional_policy
523*2d543d20SAndroid Build Coastguard Worker              | tunable_policy
524*2d543d20SAndroid Build Coastguard Worker              | ifdef
525*2d543d20SAndroid Build Coastguard Worker              | ifelse
526*2d543d20SAndroid Build Coastguard Worker              | conditional
527*2d543d20SAndroid Build Coastguard Worker    '''
528*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
529*2d543d20SAndroid Build Coastguard Worker
530*2d543d20SAndroid Build Coastguard Workerdef p_policy_stmt(p):
531*2d543d20SAndroid Build Coastguard Worker    '''policy_stmt : gen_require
532*2d543d20SAndroid Build Coastguard Worker                   | avrule_def
533*2d543d20SAndroid Build Coastguard Worker                   | typerule_def
534*2d543d20SAndroid Build Coastguard Worker                   | typebound_def
535*2d543d20SAndroid Build Coastguard Worker                   | typeattribute_def
536*2d543d20SAndroid Build Coastguard Worker                   | roleattribute_def
537*2d543d20SAndroid Build Coastguard Worker                   | interface_call
538*2d543d20SAndroid Build Coastguard Worker                   | role_def
539*2d543d20SAndroid Build Coastguard Worker                   | role_allow
540*2d543d20SAndroid Build Coastguard Worker                   | permissive
541*2d543d20SAndroid Build Coastguard Worker                   | type_def
542*2d543d20SAndroid Build Coastguard Worker                   | typealias_def
543*2d543d20SAndroid Build Coastguard Worker                   | attribute_def
544*2d543d20SAndroid Build Coastguard Worker                   | attribute_role_def
545*2d543d20SAndroid Build Coastguard Worker                   | range_transition_def
546*2d543d20SAndroid Build Coastguard Worker                   | role_transition_def
547*2d543d20SAndroid Build Coastguard Worker                   | bool
548*2d543d20SAndroid Build Coastguard Worker                   | gen_tunable
549*2d543d20SAndroid Build Coastguard Worker                   | define
550*2d543d20SAndroid Build Coastguard Worker                   | initial_sid
551*2d543d20SAndroid Build Coastguard Worker                   | genfscon
552*2d543d20SAndroid Build Coastguard Worker                   | fs_use
553*2d543d20SAndroid Build Coastguard Worker                   | portcon
554*2d543d20SAndroid Build Coastguard Worker                   | nodecon
555*2d543d20SAndroid Build Coastguard Worker                   | netifcon
556*2d543d20SAndroid Build Coastguard Worker                   | pirqcon
557*2d543d20SAndroid Build Coastguard Worker                   | iomemcon
558*2d543d20SAndroid Build Coastguard Worker                   | ioportcon
559*2d543d20SAndroid Build Coastguard Worker                   | pcidevicecon
560*2d543d20SAndroid Build Coastguard Worker                   | devicetreecon
561*2d543d20SAndroid Build Coastguard Worker    '''
562*2d543d20SAndroid Build Coastguard Worker    if p[1]:
563*2d543d20SAndroid Build Coastguard Worker        p[0] = [p[1]]
564*2d543d20SAndroid Build Coastguard Worker
565*2d543d20SAndroid Build Coastguard Workerdef p_module_stmt(p):
566*2d543d20SAndroid Build Coastguard Worker    'module_stmt : MODULE IDENTIFIER NUMBER SEMI'
567*2d543d20SAndroid Build Coastguard Worker    m = refpolicy.ModuleDeclaration()
568*2d543d20SAndroid Build Coastguard Worker    m.name = p[2]
569*2d543d20SAndroid Build Coastguard Worker    m.version = p[3]
570*2d543d20SAndroid Build Coastguard Worker    m.refpolicy = False
571*2d543d20SAndroid Build Coastguard Worker    p[0] = m
572*2d543d20SAndroid Build Coastguard Worker
573*2d543d20SAndroid Build Coastguard Workerdef p_gen_require(p):
574*2d543d20SAndroid Build Coastguard Worker    '''gen_require : GEN_REQ OPAREN TICK requires SQUOTE CPAREN
575*2d543d20SAndroid Build Coastguard Worker                   | REQUIRE OBRACE requires CBRACE'''
576*2d543d20SAndroid Build Coastguard Worker    # We ignore the require statements - they are redundant data from our point-of-view.
577*2d543d20SAndroid Build Coastguard Worker    # Checkmodule will verify them later anyway so we just assume that they match what
578*2d543d20SAndroid Build Coastguard Worker    # is in the rest of the interface.
579*2d543d20SAndroid Build Coastguard Worker    pass
580*2d543d20SAndroid Build Coastguard Worker
581*2d543d20SAndroid Build Coastguard Workerdef p_requires(p):
582*2d543d20SAndroid Build Coastguard Worker    '''requires : require
583*2d543d20SAndroid Build Coastguard Worker                | requires require
584*2d543d20SAndroid Build Coastguard Worker                | ifdef
585*2d543d20SAndroid Build Coastguard Worker                | requires ifdef
586*2d543d20SAndroid Build Coastguard Worker                | ifelse
587*2d543d20SAndroid Build Coastguard Worker                | requires ifelse
588*2d543d20SAndroid Build Coastguard Worker    '''
589*2d543d20SAndroid Build Coastguard Worker    pass
590*2d543d20SAndroid Build Coastguard Worker
591*2d543d20SAndroid Build Coastguard Workerdef p_require(p):
592*2d543d20SAndroid Build Coastguard Worker    '''require : TYPE comma_list SEMI
593*2d543d20SAndroid Build Coastguard Worker               | ROLE comma_list SEMI
594*2d543d20SAndroid Build Coastguard Worker               | ATTRIBUTE comma_list SEMI
595*2d543d20SAndroid Build Coastguard Worker               | ATTRIBUTE_ROLE comma_list SEMI
596*2d543d20SAndroid Build Coastguard Worker               | CLASS comma_list SEMI
597*2d543d20SAndroid Build Coastguard Worker               | BOOL comma_list SEMI
598*2d543d20SAndroid Build Coastguard Worker    '''
599*2d543d20SAndroid Build Coastguard Worker    pass
600*2d543d20SAndroid Build Coastguard Worker
601*2d543d20SAndroid Build Coastguard Workerdef p_security_context(p):
602*2d543d20SAndroid Build Coastguard Worker    '''security_context : IDENTIFIER COLON IDENTIFIER COLON IDENTIFIER
603*2d543d20SAndroid Build Coastguard Worker                        | IDENTIFIER COLON IDENTIFIER COLON IDENTIFIER COLON mls_range_def'''
604*2d543d20SAndroid Build Coastguard Worker    # This will likely need some updates to handle complex levels
605*2d543d20SAndroid Build Coastguard Worker    s = refpolicy.SecurityContext()
606*2d543d20SAndroid Build Coastguard Worker    s.user = p[1]
607*2d543d20SAndroid Build Coastguard Worker    s.role = p[3]
608*2d543d20SAndroid Build Coastguard Worker    s.type = p[5]
609*2d543d20SAndroid Build Coastguard Worker    if len(p) > 6:
610*2d543d20SAndroid Build Coastguard Worker        s.level = p[7]
611*2d543d20SAndroid Build Coastguard Worker
612*2d543d20SAndroid Build Coastguard Worker    p[0] = s
613*2d543d20SAndroid Build Coastguard Worker
614*2d543d20SAndroid Build Coastguard Workerdef p_gen_context(p):
615*2d543d20SAndroid Build Coastguard Worker    '''gen_context : GEN_CONTEXT OPAREN security_context COMMA mls_range_def CPAREN
616*2d543d20SAndroid Build Coastguard Worker    '''
617*2d543d20SAndroid Build Coastguard Worker    # We actually store gen_context statements in a SecurityContext
618*2d543d20SAndroid Build Coastguard Worker    # object - it knows how to output either a bare context or a
619*2d543d20SAndroid Build Coastguard Worker    # gen_context statement.
620*2d543d20SAndroid Build Coastguard Worker    s = p[3]
621*2d543d20SAndroid Build Coastguard Worker    s.level = p[5]
622*2d543d20SAndroid Build Coastguard Worker
623*2d543d20SAndroid Build Coastguard Worker    p[0] = s
624*2d543d20SAndroid Build Coastguard Worker
625*2d543d20SAndroid Build Coastguard Workerdef p_context(p):
626*2d543d20SAndroid Build Coastguard Worker    '''context : security_context
627*2d543d20SAndroid Build Coastguard Worker               | gen_context
628*2d543d20SAndroid Build Coastguard Worker    '''
629*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
630*2d543d20SAndroid Build Coastguard Worker
631*2d543d20SAndroid Build Coastguard Workerdef p_initial_sid(p):
632*2d543d20SAndroid Build Coastguard Worker    '''initial_sid : SID IDENTIFIER context'''
633*2d543d20SAndroid Build Coastguard Worker    s = refpolicy.InitialSid()
634*2d543d20SAndroid Build Coastguard Worker    s.name = p[2]
635*2d543d20SAndroid Build Coastguard Worker    s.context = p[3]
636*2d543d20SAndroid Build Coastguard Worker    p[0] = s
637*2d543d20SAndroid Build Coastguard Worker
638*2d543d20SAndroid Build Coastguard Workerdef p_genfscon(p):
639*2d543d20SAndroid Build Coastguard Worker    '''genfscon : GENFSCON IDENTIFIER PATH context
640*2d543d20SAndroid Build Coastguard Worker                | GENFSCON IDENTIFIER PATH MINUS IDENTIFIER context
641*2d543d20SAndroid Build Coastguard Worker                | GENFSCON IDENTIFIER PATH MINUS MINUS context
642*2d543d20SAndroid Build Coastguard Worker    '''
643*2d543d20SAndroid Build Coastguard Worker    g = refpolicy.GenfsCon()
644*2d543d20SAndroid Build Coastguard Worker    g.filesystem = p[2]
645*2d543d20SAndroid Build Coastguard Worker    g.path = p[3]
646*2d543d20SAndroid Build Coastguard Worker    if len(p) == 5:
647*2d543d20SAndroid Build Coastguard Worker        g.context = p[4]
648*2d543d20SAndroid Build Coastguard Worker    else:
649*2d543d20SAndroid Build Coastguard Worker        g.context = p[6]
650*2d543d20SAndroid Build Coastguard Worker
651*2d543d20SAndroid Build Coastguard Worker    p[0] = g
652*2d543d20SAndroid Build Coastguard Worker
653*2d543d20SAndroid Build Coastguard Workerdef p_fs_use(p):
654*2d543d20SAndroid Build Coastguard Worker    '''fs_use : FS_USE_XATTR IDENTIFIER context SEMI
655*2d543d20SAndroid Build Coastguard Worker              | FS_USE_TASK IDENTIFIER context SEMI
656*2d543d20SAndroid Build Coastguard Worker              | FS_USE_TRANS IDENTIFIER context SEMI
657*2d543d20SAndroid Build Coastguard Worker    '''
658*2d543d20SAndroid Build Coastguard Worker    f = refpolicy.FilesystemUse()
659*2d543d20SAndroid Build Coastguard Worker    if p[1] == "fs_use_xattr":
660*2d543d20SAndroid Build Coastguard Worker        f.type = refpolicy.FilesystemUse.XATTR
661*2d543d20SAndroid Build Coastguard Worker    elif p[1] == "fs_use_task":
662*2d543d20SAndroid Build Coastguard Worker        f.type = refpolicy.FilesystemUse.TASK
663*2d543d20SAndroid Build Coastguard Worker    elif p[1] == "fs_use_trans":
664*2d543d20SAndroid Build Coastguard Worker        f.type = refpolicy.FilesystemUse.TRANS
665*2d543d20SAndroid Build Coastguard Worker
666*2d543d20SAndroid Build Coastguard Worker    f.filesystem = p[2]
667*2d543d20SAndroid Build Coastguard Worker    f.context = p[3]
668*2d543d20SAndroid Build Coastguard Worker
669*2d543d20SAndroid Build Coastguard Worker    p[0] = f
670*2d543d20SAndroid Build Coastguard Worker
671*2d543d20SAndroid Build Coastguard Workerdef p_portcon(p):
672*2d543d20SAndroid Build Coastguard Worker    '''portcon : PORTCON IDENTIFIER NUMBER context
673*2d543d20SAndroid Build Coastguard Worker               | PORTCON IDENTIFIER NUMBER MINUS NUMBER context'''
674*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.PortCon()
675*2d543d20SAndroid Build Coastguard Worker    c.port_type = p[2]
676*2d543d20SAndroid Build Coastguard Worker    if len(p) == 5:
677*2d543d20SAndroid Build Coastguard Worker        c.port_number = p[3]
678*2d543d20SAndroid Build Coastguard Worker        c.context = p[4]
679*2d543d20SAndroid Build Coastguard Worker    else:
680*2d543d20SAndroid Build Coastguard Worker        c.port_number = p[3] + "-" + p[4]
681*2d543d20SAndroid Build Coastguard Worker        c.context = p[5]
682*2d543d20SAndroid Build Coastguard Worker
683*2d543d20SAndroid Build Coastguard Worker    p[0] = c
684*2d543d20SAndroid Build Coastguard Worker
685*2d543d20SAndroid Build Coastguard Workerdef p_nodecon(p):
686*2d543d20SAndroid Build Coastguard Worker    '''nodecon : NODECON NUMBER NUMBER context
687*2d543d20SAndroid Build Coastguard Worker               | NODECON IPV6_ADDR IPV6_ADDR context
688*2d543d20SAndroid Build Coastguard Worker    '''
689*2d543d20SAndroid Build Coastguard Worker    n = refpolicy.NodeCon()
690*2d543d20SAndroid Build Coastguard Worker    n.start = p[2]
691*2d543d20SAndroid Build Coastguard Worker    n.end = p[3]
692*2d543d20SAndroid Build Coastguard Worker    n.context = p[4]
693*2d543d20SAndroid Build Coastguard Worker
694*2d543d20SAndroid Build Coastguard Worker    p[0] = n
695*2d543d20SAndroid Build Coastguard Worker
696*2d543d20SAndroid Build Coastguard Workerdef p_netifcon(p):
697*2d543d20SAndroid Build Coastguard Worker    'netifcon : NETIFCON IDENTIFIER context context'
698*2d543d20SAndroid Build Coastguard Worker    n = refpolicy.NetifCon()
699*2d543d20SAndroid Build Coastguard Worker    n.interface = p[2]
700*2d543d20SAndroid Build Coastguard Worker    n.interface_context = p[3]
701*2d543d20SAndroid Build Coastguard Worker    n.packet_context = p[4]
702*2d543d20SAndroid Build Coastguard Worker
703*2d543d20SAndroid Build Coastguard Worker    p[0] = n
704*2d543d20SAndroid Build Coastguard Worker
705*2d543d20SAndroid Build Coastguard Workerdef p_pirqcon(p):
706*2d543d20SAndroid Build Coastguard Worker    'pirqcon : PIRQCON NUMBER context'
707*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.PirqCon()
708*2d543d20SAndroid Build Coastguard Worker    c.pirq_number = p[2]
709*2d543d20SAndroid Build Coastguard Worker    c.context = p[3]
710*2d543d20SAndroid Build Coastguard Worker
711*2d543d20SAndroid Build Coastguard Worker    p[0] = c
712*2d543d20SAndroid Build Coastguard Worker
713*2d543d20SAndroid Build Coastguard Workerdef p_iomemcon(p):
714*2d543d20SAndroid Build Coastguard Worker    '''iomemcon : IOMEMCON NUMBER context
715*2d543d20SAndroid Build Coastguard Worker                | IOMEMCON NUMBER MINUS NUMBER context'''
716*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.IomemCon()
717*2d543d20SAndroid Build Coastguard Worker    if len(p) == 4:
718*2d543d20SAndroid Build Coastguard Worker        c.device_mem = p[2]
719*2d543d20SAndroid Build Coastguard Worker        c.context = p[3]
720*2d543d20SAndroid Build Coastguard Worker    else:
721*2d543d20SAndroid Build Coastguard Worker        c.device_mem = p[2] + "-" + p[3]
722*2d543d20SAndroid Build Coastguard Worker        c.context = p[4]
723*2d543d20SAndroid Build Coastguard Worker
724*2d543d20SAndroid Build Coastguard Worker    p[0] = c
725*2d543d20SAndroid Build Coastguard Worker
726*2d543d20SAndroid Build Coastguard Workerdef p_ioportcon(p):
727*2d543d20SAndroid Build Coastguard Worker    '''ioportcon : IOPORTCON NUMBER context
728*2d543d20SAndroid Build Coastguard Worker                | IOPORTCON NUMBER MINUS NUMBER context'''
729*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.IoportCon()
730*2d543d20SAndroid Build Coastguard Worker    if len(p) == 4:
731*2d543d20SAndroid Build Coastguard Worker        c.ioport = p[2]
732*2d543d20SAndroid Build Coastguard Worker        c.context = p[3]
733*2d543d20SAndroid Build Coastguard Worker    else:
734*2d543d20SAndroid Build Coastguard Worker        c.ioport = p[2] + "-" + p[3]
735*2d543d20SAndroid Build Coastguard Worker        c.context = p[4]
736*2d543d20SAndroid Build Coastguard Worker
737*2d543d20SAndroid Build Coastguard Worker    p[0] = c
738*2d543d20SAndroid Build Coastguard Worker
739*2d543d20SAndroid Build Coastguard Workerdef p_pcidevicecon(p):
740*2d543d20SAndroid Build Coastguard Worker    'pcidevicecon : PCIDEVICECON NUMBER context'
741*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.PciDeviceCon()
742*2d543d20SAndroid Build Coastguard Worker    c.device = p[2]
743*2d543d20SAndroid Build Coastguard Worker    c.context = p[3]
744*2d543d20SAndroid Build Coastguard Worker
745*2d543d20SAndroid Build Coastguard Worker    p[0] = c
746*2d543d20SAndroid Build Coastguard Worker
747*2d543d20SAndroid Build Coastguard Workerdef p_devicetreecon(p):
748*2d543d20SAndroid Build Coastguard Worker    'devicetreecon : DEVICETREECON NUMBER context'
749*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.DevicetTeeCon()
750*2d543d20SAndroid Build Coastguard Worker    c.path = p[2]
751*2d543d20SAndroid Build Coastguard Worker    c.context = p[3]
752*2d543d20SAndroid Build Coastguard Worker
753*2d543d20SAndroid Build Coastguard Worker    p[0] = c
754*2d543d20SAndroid Build Coastguard Worker
755*2d543d20SAndroid Build Coastguard Workerdef p_mls_range_def(p):
756*2d543d20SAndroid Build Coastguard Worker    '''mls_range_def : mls_level_def MINUS mls_level_def
757*2d543d20SAndroid Build Coastguard Worker                     | mls_level_def
758*2d543d20SAndroid Build Coastguard Worker    '''
759*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
760*2d543d20SAndroid Build Coastguard Worker    if len(p) > 2:
761*2d543d20SAndroid Build Coastguard Worker        p[0] = p[0] + "-" + p[3]
762*2d543d20SAndroid Build Coastguard Worker
763*2d543d20SAndroid Build Coastguard Workerdef p_mls_level_def(p):
764*2d543d20SAndroid Build Coastguard Worker    '''mls_level_def : IDENTIFIER COLON comma_list
765*2d543d20SAndroid Build Coastguard Worker                     | IDENTIFIER
766*2d543d20SAndroid Build Coastguard Worker    '''
767*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
768*2d543d20SAndroid Build Coastguard Worker    if len(p) > 2:
769*2d543d20SAndroid Build Coastguard Worker        p[0] = p[0] + ":" + ",".join(p[3])
770*2d543d20SAndroid Build Coastguard Worker
771*2d543d20SAndroid Build Coastguard Workerdef p_type_def(p):
772*2d543d20SAndroid Build Coastguard Worker    '''type_def : TYPE IDENTIFIER COMMA comma_list SEMI
773*2d543d20SAndroid Build Coastguard Worker                | TYPE IDENTIFIER SEMI
774*2d543d20SAndroid Build Coastguard Worker                | TYPE IDENTIFIER ALIAS names SEMI
775*2d543d20SAndroid Build Coastguard Worker                | TYPE IDENTIFIER ALIAS names COMMA comma_list SEMI
776*2d543d20SAndroid Build Coastguard Worker    '''
777*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.Type(p[2])
778*2d543d20SAndroid Build Coastguard Worker    if len(p) == 6:
779*2d543d20SAndroid Build Coastguard Worker        if p[3] == ',':
780*2d543d20SAndroid Build Coastguard Worker            t.attributes.update(p[4])
781*2d543d20SAndroid Build Coastguard Worker        else:
782*2d543d20SAndroid Build Coastguard Worker            t.aliases = p[4]
783*2d543d20SAndroid Build Coastguard Worker    elif len(p) > 4:
784*2d543d20SAndroid Build Coastguard Worker        t.aliases = p[4]
785*2d543d20SAndroid Build Coastguard Worker        if len(p) == 8:
786*2d543d20SAndroid Build Coastguard Worker            t.attributes.update(p[6])
787*2d543d20SAndroid Build Coastguard Worker    p[0] = t
788*2d543d20SAndroid Build Coastguard Worker
789*2d543d20SAndroid Build Coastguard Workerdef p_attribute_def(p):
790*2d543d20SAndroid Build Coastguard Worker    'attribute_def : ATTRIBUTE IDENTIFIER SEMI'
791*2d543d20SAndroid Build Coastguard Worker    a = refpolicy.Attribute(p[2])
792*2d543d20SAndroid Build Coastguard Worker    p[0] = a
793*2d543d20SAndroid Build Coastguard Worker
794*2d543d20SAndroid Build Coastguard Workerdef p_attribute_role_def(p):
795*2d543d20SAndroid Build Coastguard Worker    'attribute_role_def : ATTRIBUTE_ROLE IDENTIFIER SEMI'
796*2d543d20SAndroid Build Coastguard Worker    a = refpolicy.Attribute_Role(p[2])
797*2d543d20SAndroid Build Coastguard Worker    p[0] = a
798*2d543d20SAndroid Build Coastguard Worker
799*2d543d20SAndroid Build Coastguard Workerdef p_typealias_def(p):
800*2d543d20SAndroid Build Coastguard Worker    'typealias_def : TYPEALIAS IDENTIFIER ALIAS names SEMI'
801*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.TypeAlias()
802*2d543d20SAndroid Build Coastguard Worker    t.type = p[2]
803*2d543d20SAndroid Build Coastguard Worker    t.aliases = p[4]
804*2d543d20SAndroid Build Coastguard Worker    p[0] = t
805*2d543d20SAndroid Build Coastguard Worker
806*2d543d20SAndroid Build Coastguard Workerdef p_role_def(p):
807*2d543d20SAndroid Build Coastguard Worker    '''role_def : ROLE IDENTIFIER TYPES comma_list SEMI
808*2d543d20SAndroid Build Coastguard Worker                | ROLE IDENTIFIER SEMI'''
809*2d543d20SAndroid Build Coastguard Worker    r = refpolicy.Role()
810*2d543d20SAndroid Build Coastguard Worker    r.role = p[2]
811*2d543d20SAndroid Build Coastguard Worker    if len(p) > 4:
812*2d543d20SAndroid Build Coastguard Worker        r.types.update(p[4])
813*2d543d20SAndroid Build Coastguard Worker    p[0] = r
814*2d543d20SAndroid Build Coastguard Worker
815*2d543d20SAndroid Build Coastguard Workerdef p_role_allow(p):
816*2d543d20SAndroid Build Coastguard Worker    'role_allow : ALLOW names names SEMI'
817*2d543d20SAndroid Build Coastguard Worker    r = refpolicy.RoleAllow()
818*2d543d20SAndroid Build Coastguard Worker    r.src_roles = p[2]
819*2d543d20SAndroid Build Coastguard Worker    r.tgt_roles = p[3]
820*2d543d20SAndroid Build Coastguard Worker    p[0] = r
821*2d543d20SAndroid Build Coastguard Worker
822*2d543d20SAndroid Build Coastguard Workerdef p_permissive(p):
823*2d543d20SAndroid Build Coastguard Worker    'permissive : PERMISSIVE names SEMI'
824*2d543d20SAndroid Build Coastguard Worker    pass
825*2d543d20SAndroid Build Coastguard Worker
826*2d543d20SAndroid Build Coastguard Workerdef p_avrule_def(p):
827*2d543d20SAndroid Build Coastguard Worker    '''avrule_def : ALLOW names names COLON names names SEMI
828*2d543d20SAndroid Build Coastguard Worker                  | DONTAUDIT names names COLON names names SEMI
829*2d543d20SAndroid Build Coastguard Worker                  | AUDITALLOW names names COLON names names SEMI
830*2d543d20SAndroid Build Coastguard Worker                  | NEVERALLOW names names COLON names names SEMI
831*2d543d20SAndroid Build Coastguard Worker    '''
832*2d543d20SAndroid Build Coastguard Worker    a = refpolicy.AVRule()
833*2d543d20SAndroid Build Coastguard Worker    if p[1] == 'dontaudit':
834*2d543d20SAndroid Build Coastguard Worker        a.rule_type = refpolicy.AVRule.DONTAUDIT
835*2d543d20SAndroid Build Coastguard Worker    elif p[1] == 'auditallow':
836*2d543d20SAndroid Build Coastguard Worker        a.rule_type = refpolicy.AVRule.AUDITALLOW
837*2d543d20SAndroid Build Coastguard Worker    elif p[1] == 'neverallow':
838*2d543d20SAndroid Build Coastguard Worker        a.rule_type = refpolicy.AVRule.NEVERALLOW
839*2d543d20SAndroid Build Coastguard Worker    a.src_types = p[2]
840*2d543d20SAndroid Build Coastguard Worker    a.tgt_types = p[3]
841*2d543d20SAndroid Build Coastguard Worker    a.obj_classes = p[5]
842*2d543d20SAndroid Build Coastguard Worker    a.perms = p[6]
843*2d543d20SAndroid Build Coastguard Worker    p[0] = a
844*2d543d20SAndroid Build Coastguard Worker
845*2d543d20SAndroid Build Coastguard Workerdef p_typerule_def(p):
846*2d543d20SAndroid Build Coastguard Worker    '''typerule_def : TYPE_TRANSITION names names COLON names IDENTIFIER SEMI
847*2d543d20SAndroid Build Coastguard Worker                    | TYPE_TRANSITION names names COLON names IDENTIFIER FILENAME SEMI
848*2d543d20SAndroid Build Coastguard Worker                    | TYPE_TRANSITION names names COLON names IDENTIFIER IDENTIFIER SEMI
849*2d543d20SAndroid Build Coastguard Worker                    | TYPE_CHANGE names names COLON names IDENTIFIER SEMI
850*2d543d20SAndroid Build Coastguard Worker                    | TYPE_MEMBER names names COLON names IDENTIFIER SEMI
851*2d543d20SAndroid Build Coastguard Worker    '''
852*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.TypeRule()
853*2d543d20SAndroid Build Coastguard Worker    if p[1] == 'type_change':
854*2d543d20SAndroid Build Coastguard Worker        t.rule_type = refpolicy.TypeRule.TYPE_CHANGE
855*2d543d20SAndroid Build Coastguard Worker    elif p[1] == 'type_member':
856*2d543d20SAndroid Build Coastguard Worker        t.rule_type = refpolicy.TypeRule.TYPE_MEMBER
857*2d543d20SAndroid Build Coastguard Worker    t.src_types = p[2]
858*2d543d20SAndroid Build Coastguard Worker    t.tgt_types = p[3]
859*2d543d20SAndroid Build Coastguard Worker    t.obj_classes = p[5]
860*2d543d20SAndroid Build Coastguard Worker    t.dest_type = p[6]
861*2d543d20SAndroid Build Coastguard Worker    t.file_name = p[7]
862*2d543d20SAndroid Build Coastguard Worker    p[0] = t
863*2d543d20SAndroid Build Coastguard Worker
864*2d543d20SAndroid Build Coastguard Workerdef p_typebound_def(p):
865*2d543d20SAndroid Build Coastguard Worker    '''typebound_def : TYPEBOUNDS IDENTIFIER comma_list SEMI'''
866*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.TypeBound()
867*2d543d20SAndroid Build Coastguard Worker    t.type = p[2]
868*2d543d20SAndroid Build Coastguard Worker    t.tgt_types.update(p[3])
869*2d543d20SAndroid Build Coastguard Worker    p[0] = t
870*2d543d20SAndroid Build Coastguard Worker
871*2d543d20SAndroid Build Coastguard Workerdef p_bool(p):
872*2d543d20SAndroid Build Coastguard Worker    '''bool : BOOL IDENTIFIER TRUE SEMI
873*2d543d20SAndroid Build Coastguard Worker            | BOOL IDENTIFIER FALSE SEMI'''
874*2d543d20SAndroid Build Coastguard Worker    b = refpolicy.Bool()
875*2d543d20SAndroid Build Coastguard Worker    b.name = p[2]
876*2d543d20SAndroid Build Coastguard Worker    if p[3] == "true":
877*2d543d20SAndroid Build Coastguard Worker        b.state = True
878*2d543d20SAndroid Build Coastguard Worker    else:
879*2d543d20SAndroid Build Coastguard Worker        b.state = False
880*2d543d20SAndroid Build Coastguard Worker    p[0] = b
881*2d543d20SAndroid Build Coastguard Worker
882*2d543d20SAndroid Build Coastguard Workerdef p_gen_tunable(p):
883*2d543d20SAndroid Build Coastguard Worker    '''gen_tunable : GEN_TUNABLE OPAREN IDENTIFIER COMMA TRUE CPAREN
884*2d543d20SAndroid Build Coastguard Worker                   | GEN_TUNABLE OPAREN IDENTIFIER COMMA FALSE CPAREN
885*2d543d20SAndroid Build Coastguard Worker                   | GEN_TUNABLE OPAREN TICK IDENTIFIER SQUOTE COMMA TRUE CPAREN
886*2d543d20SAndroid Build Coastguard Worker                   | GEN_TUNABLE OPAREN TICK IDENTIFIER SQUOTE COMMA FALSE CPAREN'''
887*2d543d20SAndroid Build Coastguard Worker    b = refpolicy.Bool()
888*2d543d20SAndroid Build Coastguard Worker    if len(p) == 7:
889*2d543d20SAndroid Build Coastguard Worker        id_pos = 3
890*2d543d20SAndroid Build Coastguard Worker        state_pos = 5
891*2d543d20SAndroid Build Coastguard Worker    else:
892*2d543d20SAndroid Build Coastguard Worker        id_pos = 4
893*2d543d20SAndroid Build Coastguard Worker        state_pos = 7
894*2d543d20SAndroid Build Coastguard Worker    b.name = p[id_pos]
895*2d543d20SAndroid Build Coastguard Worker    if p[state_pos] == "true":
896*2d543d20SAndroid Build Coastguard Worker        b.state = True
897*2d543d20SAndroid Build Coastguard Worker    else:
898*2d543d20SAndroid Build Coastguard Worker        b.state = False
899*2d543d20SAndroid Build Coastguard Worker    p[0] = b
900*2d543d20SAndroid Build Coastguard Worker
901*2d543d20SAndroid Build Coastguard Workerdef p_conditional(p):
902*2d543d20SAndroid Build Coastguard Worker    ''' conditional : IF OPAREN cond_expr CPAREN OBRACE interface_stmts CBRACE
903*2d543d20SAndroid Build Coastguard Worker                    | IF OPAREN cond_expr CPAREN OBRACE interface_stmts CBRACE ELSE OBRACE interface_stmts CBRACE
904*2d543d20SAndroid Build Coastguard Worker    '''
905*2d543d20SAndroid Build Coastguard Worker    c = refpolicy.Conditional()
906*2d543d20SAndroid Build Coastguard Worker    c.cond_expr = p[3]
907*2d543d20SAndroid Build Coastguard Worker    collect(p[6], c, val=True)
908*2d543d20SAndroid Build Coastguard Worker    if len(p) > 8:
909*2d543d20SAndroid Build Coastguard Worker        collect(p[10], c, val=False)
910*2d543d20SAndroid Build Coastguard Worker    p[0] = [c]
911*2d543d20SAndroid Build Coastguard Worker
912*2d543d20SAndroid Build Coastguard Workerdef p_typeattribute_def(p):
913*2d543d20SAndroid Build Coastguard Worker    '''typeattribute_def : TYPEATTRIBUTE IDENTIFIER comma_list SEMI'''
914*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.TypeAttribute()
915*2d543d20SAndroid Build Coastguard Worker    t.type = p[2]
916*2d543d20SAndroid Build Coastguard Worker    t.attributes.update(p[3])
917*2d543d20SAndroid Build Coastguard Worker    p[0] = t
918*2d543d20SAndroid Build Coastguard Worker
919*2d543d20SAndroid Build Coastguard Workerdef p_roleattribute_def(p):
920*2d543d20SAndroid Build Coastguard Worker    '''roleattribute_def : ROLEATTRIBUTE IDENTIFIER comma_list SEMI'''
921*2d543d20SAndroid Build Coastguard Worker    t = refpolicy.RoleAttribute()
922*2d543d20SAndroid Build Coastguard Worker    t.role = p[2]
923*2d543d20SAndroid Build Coastguard Worker    t.roleattributes.update(p[3])
924*2d543d20SAndroid Build Coastguard Worker    p[0] = t
925*2d543d20SAndroid Build Coastguard Worker
926*2d543d20SAndroid Build Coastguard Workerdef p_range_transition_def(p):
927*2d543d20SAndroid Build Coastguard Worker    '''range_transition_def : RANGE_TRANSITION names names COLON names mls_range_def SEMI
928*2d543d20SAndroid Build Coastguard Worker                            | RANGE_TRANSITION names names names SEMI'''
929*2d543d20SAndroid Build Coastguard Worker    pass
930*2d543d20SAndroid Build Coastguard Worker
931*2d543d20SAndroid Build Coastguard Workerdef p_role_transition_def(p):
932*2d543d20SAndroid Build Coastguard Worker    '''role_transition_def : ROLE_TRANSITION names names names SEMI'''
933*2d543d20SAndroid Build Coastguard Worker    pass
934*2d543d20SAndroid Build Coastguard Worker
935*2d543d20SAndroid Build Coastguard Workerdef p_cond_expr(p):
936*2d543d20SAndroid Build Coastguard Worker    '''cond_expr : IDENTIFIER
937*2d543d20SAndroid Build Coastguard Worker                 | EXPL cond_expr
938*2d543d20SAndroid Build Coastguard Worker                 | cond_expr AMP AMP cond_expr
939*2d543d20SAndroid Build Coastguard Worker                 | cond_expr BAR BAR cond_expr
940*2d543d20SAndroid Build Coastguard Worker                 | cond_expr EQUAL EQUAL cond_expr
941*2d543d20SAndroid Build Coastguard Worker                 | cond_expr EXPL EQUAL cond_expr
942*2d543d20SAndroid Build Coastguard Worker    '''
943*2d543d20SAndroid Build Coastguard Worker    l = len(p)
944*2d543d20SAndroid Build Coastguard Worker    if l == 2:
945*2d543d20SAndroid Build Coastguard Worker        p[0] = [p[1]]
946*2d543d20SAndroid Build Coastguard Worker    elif l == 3:
947*2d543d20SAndroid Build Coastguard Worker        p[0] = [p[1]] + p[2]
948*2d543d20SAndroid Build Coastguard Worker    else:
949*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1] + [p[2] + p[3]] + p[4]
950*2d543d20SAndroid Build Coastguard Worker
951*2d543d20SAndroid Build Coastguard Worker
952*2d543d20SAndroid Build Coastguard Worker#
953*2d543d20SAndroid Build Coastguard Worker# Basic terminals
954*2d543d20SAndroid Build Coastguard Worker#
955*2d543d20SAndroid Build Coastguard Worker
956*2d543d20SAndroid Build Coastguard Worker# Identifiers and lists of identifiers. These must
957*2d543d20SAndroid Build Coastguard Worker# be handled somewhat gracefully. Names returns an IdSet and care must
958*2d543d20SAndroid Build Coastguard Worker# be taken that this is _assigned_ to an object to correctly update
959*2d543d20SAndroid Build Coastguard Worker# all of the flags (as opposed to using update). The other terminals
960*2d543d20SAndroid Build Coastguard Worker# return list - this is to preserve ordering if it is important for
961*2d543d20SAndroid Build Coastguard Worker# parsing (for example, interface_call must retain the ordering). Other
962*2d543d20SAndroid Build Coastguard Worker# times the list should be used to update an IdSet.
963*2d543d20SAndroid Build Coastguard Worker
964*2d543d20SAndroid Build Coastguard Workerdef p_names(p):
965*2d543d20SAndroid Build Coastguard Worker    '''names : identifier
966*2d543d20SAndroid Build Coastguard Worker             | nested_id_set
967*2d543d20SAndroid Build Coastguard Worker             | asterisk
968*2d543d20SAndroid Build Coastguard Worker             | TILDE identifier
969*2d543d20SAndroid Build Coastguard Worker             | TILDE nested_id_set
970*2d543d20SAndroid Build Coastguard Worker             | IDENTIFIER MINUS IDENTIFIER
971*2d543d20SAndroid Build Coastguard Worker    '''
972*2d543d20SAndroid Build Coastguard Worker    s = refpolicy.IdSet()
973*2d543d20SAndroid Build Coastguard Worker    if len(p) < 3:
974*2d543d20SAndroid Build Coastguard Worker        expand(p[1], s)
975*2d543d20SAndroid Build Coastguard Worker    elif len(p) == 3:
976*2d543d20SAndroid Build Coastguard Worker        expand(p[2], s)
977*2d543d20SAndroid Build Coastguard Worker        s.compliment = True
978*2d543d20SAndroid Build Coastguard Worker    else:
979*2d543d20SAndroid Build Coastguard Worker        expand([p[1]])
980*2d543d20SAndroid Build Coastguard Worker        s.add("-" + p[3])
981*2d543d20SAndroid Build Coastguard Worker    p[0] = s
982*2d543d20SAndroid Build Coastguard Worker
983*2d543d20SAndroid Build Coastguard Workerdef p_identifier(p):
984*2d543d20SAndroid Build Coastguard Worker    'identifier : IDENTIFIER'
985*2d543d20SAndroid Build Coastguard Worker    p[0] = [p[1]]
986*2d543d20SAndroid Build Coastguard Worker
987*2d543d20SAndroid Build Coastguard Workerdef p_asterisk(p):
988*2d543d20SAndroid Build Coastguard Worker    'asterisk : ASTERISK'
989*2d543d20SAndroid Build Coastguard Worker    p[0] = [p[1]]
990*2d543d20SAndroid Build Coastguard Worker
991*2d543d20SAndroid Build Coastguard Workerdef p_nested_id_set(p):
992*2d543d20SAndroid Build Coastguard Worker    '''nested_id_set : OBRACE nested_id_list CBRACE
993*2d543d20SAndroid Build Coastguard Worker    '''
994*2d543d20SAndroid Build Coastguard Worker    p[0] = p[2]
995*2d543d20SAndroid Build Coastguard Worker
996*2d543d20SAndroid Build Coastguard Workerdef p_nested_id_list(p):
997*2d543d20SAndroid Build Coastguard Worker    '''nested_id_list : nested_id_element
998*2d543d20SAndroid Build Coastguard Worker                      | nested_id_list nested_id_element
999*2d543d20SAndroid Build Coastguard Worker    '''
1000*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2:
1001*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1]
1002*2d543d20SAndroid Build Coastguard Worker    else:
1003*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1] + p[2]
1004*2d543d20SAndroid Build Coastguard Worker
1005*2d543d20SAndroid Build Coastguard Workerdef p_nested_id_element(p):
1006*2d543d20SAndroid Build Coastguard Worker    '''nested_id_element : identifier
1007*2d543d20SAndroid Build Coastguard Worker                         | MINUS IDENTIFIER
1008*2d543d20SAndroid Build Coastguard Worker                         | nested_id_set
1009*2d543d20SAndroid Build Coastguard Worker    '''
1010*2d543d20SAndroid Build Coastguard Worker    if len(p) == 2:
1011*2d543d20SAndroid Build Coastguard Worker        p[0] = p[1]
1012*2d543d20SAndroid Build Coastguard Worker    else:
1013*2d543d20SAndroid Build Coastguard Worker        # For now just leave the '-'
1014*2d543d20SAndroid Build Coastguard Worker        str = "-" + p[2]
1015*2d543d20SAndroid Build Coastguard Worker        p[0] = [str]
1016*2d543d20SAndroid Build Coastguard Worker
1017*2d543d20SAndroid Build Coastguard Workerdef p_comma_list(p):
1018*2d543d20SAndroid Build Coastguard Worker    '''comma_list : nested_id_list
1019*2d543d20SAndroid Build Coastguard Worker                  | comma_list COMMA nested_id_list
1020*2d543d20SAndroid Build Coastguard Worker    '''
1021*2d543d20SAndroid Build Coastguard Worker    if len(p) > 2:
1022*2d543d20SAndroid Build Coastguard Worker        p[1] = p[1] + p[3]
1023*2d543d20SAndroid Build Coastguard Worker    p[0] = p[1]
1024*2d543d20SAndroid Build Coastguard Worker
1025*2d543d20SAndroid Build Coastguard Workerdef p_optional_semi(p):
1026*2d543d20SAndroid Build Coastguard Worker    '''optional_semi : SEMI
1027*2d543d20SAndroid Build Coastguard Worker                   | empty'''
1028*2d543d20SAndroid Build Coastguard Worker    pass
1029*2d543d20SAndroid Build Coastguard Worker
1030*2d543d20SAndroid Build Coastguard Worker
1031*2d543d20SAndroid Build Coastguard Worker#
1032*2d543d20SAndroid Build Coastguard Worker# Interface to the parser
1033*2d543d20SAndroid Build Coastguard Worker#
1034*2d543d20SAndroid Build Coastguard Worker
1035*2d543d20SAndroid Build Coastguard Workerdef p_error(tok):
1036*2d543d20SAndroid Build Coastguard Worker    global error, parse_file, success, parser
1037*2d543d20SAndroid Build Coastguard Worker    error = "%s: Syntax error on line %d %s [type=%s]" % (parse_file, tok.lineno, tok.value, tok.type)
1038*2d543d20SAndroid Build Coastguard Worker    print(error)
1039*2d543d20SAndroid Build Coastguard Worker    success = False
1040*2d543d20SAndroid Build Coastguard Worker
1041*2d543d20SAndroid Build Coastguard Workerdef prep_spt(spt):
1042*2d543d20SAndroid Build Coastguard Worker    if not spt:
1043*2d543d20SAndroid Build Coastguard Worker        return { }
1044*2d543d20SAndroid Build Coastguard Worker    map = {}
1045*2d543d20SAndroid Build Coastguard Worker    for x in spt:
1046*2d543d20SAndroid Build Coastguard Worker        map[x.name] = x
1047*2d543d20SAndroid Build Coastguard Worker
1048*2d543d20SAndroid Build Coastguard Workerparser = None
1049*2d543d20SAndroid Build Coastguard Workerlexer = None
1050*2d543d20SAndroid Build Coastguard Workerdef create_globals(module, support, debug):
1051*2d543d20SAndroid Build Coastguard Worker    global parser, lexer, m, spt
1052*2d543d20SAndroid Build Coastguard Worker
1053*2d543d20SAndroid Build Coastguard Worker    if not parser:
1054*2d543d20SAndroid Build Coastguard Worker        lexer = lex.lex()
1055*2d543d20SAndroid Build Coastguard Worker        parser = yacc.yacc(method="LALR", debug=debug, write_tables=0)
1056*2d543d20SAndroid Build Coastguard Worker
1057*2d543d20SAndroid Build Coastguard Worker    if module is not None:
1058*2d543d20SAndroid Build Coastguard Worker        m = module
1059*2d543d20SAndroid Build Coastguard Worker    else:
1060*2d543d20SAndroid Build Coastguard Worker        m = refpolicy.Module()
1061*2d543d20SAndroid Build Coastguard Worker
1062*2d543d20SAndroid Build Coastguard Worker    if not support:
1063*2d543d20SAndroid Build Coastguard Worker        spt = refpolicy.SupportMacros()
1064*2d543d20SAndroid Build Coastguard Worker    else:
1065*2d543d20SAndroid Build Coastguard Worker        spt = support
1066*2d543d20SAndroid Build Coastguard Worker
1067*2d543d20SAndroid Build Coastguard Workerdef parse(text, module=None, support=None, debug=False):
1068*2d543d20SAndroid Build Coastguard Worker    create_globals(module, support, debug)
1069*2d543d20SAndroid Build Coastguard Worker    global error, parser, lexer, success
1070*2d543d20SAndroid Build Coastguard Worker
1071*2d543d20SAndroid Build Coastguard Worker    lexer.lineno = 1
1072*2d543d20SAndroid Build Coastguard Worker    success = True
1073*2d543d20SAndroid Build Coastguard Worker
1074*2d543d20SAndroid Build Coastguard Worker    try:
1075*2d543d20SAndroid Build Coastguard Worker        parser.parse(text, debug=debug, lexer=lexer)
1076*2d543d20SAndroid Build Coastguard Worker    except Exception as e:
1077*2d543d20SAndroid Build Coastguard Worker        parser = None
1078*2d543d20SAndroid Build Coastguard Worker        lexer = None
1079*2d543d20SAndroid Build Coastguard Worker        error = "internal parser error: %s" % str(e) + "\n" + traceback.format_exc()
1080*2d543d20SAndroid Build Coastguard Worker
1081*2d543d20SAndroid Build Coastguard Worker    if not success:
1082*2d543d20SAndroid Build Coastguard Worker        # force the parser and lexer to be rebuilt - we have some problems otherwise
1083*2d543d20SAndroid Build Coastguard Worker        parser = None
1084*2d543d20SAndroid Build Coastguard Worker        msg = 'could not parse text: "%s"' % error
1085*2d543d20SAndroid Build Coastguard Worker        raise ValueError(msg)
1086*2d543d20SAndroid Build Coastguard Worker    return m
1087*2d543d20SAndroid Build Coastguard Worker
1088*2d543d20SAndroid Build Coastguard Workerdef list_headers(root):
1089*2d543d20SAndroid Build Coastguard Worker    modules = []
1090*2d543d20SAndroid Build Coastguard Worker    support_macros = None
1091*2d543d20SAndroid Build Coastguard Worker
1092*2d543d20SAndroid Build Coastguard Worker    for dirpath, dirnames, filenames in os.walk(root):
1093*2d543d20SAndroid Build Coastguard Worker        for name in filenames:
1094*2d543d20SAndroid Build Coastguard Worker            modname = os.path.splitext(name)
1095*2d543d20SAndroid Build Coastguard Worker            filename = os.path.join(dirpath, name)
1096*2d543d20SAndroid Build Coastguard Worker
1097*2d543d20SAndroid Build Coastguard Worker            if modname[1] == '.spt':
1098*2d543d20SAndroid Build Coastguard Worker                if name == "obj_perm_sets.spt":
1099*2d543d20SAndroid Build Coastguard Worker                    support_macros = filename
1100*2d543d20SAndroid Build Coastguard Worker                elif len(re.findall("patterns", modname[0])):
1101*2d543d20SAndroid Build Coastguard Worker                    modules.append((modname[0], filename))
1102*2d543d20SAndroid Build Coastguard Worker            elif modname[1] == '.if':
1103*2d543d20SAndroid Build Coastguard Worker                modules.append((modname[0], filename))
1104*2d543d20SAndroid Build Coastguard Worker
1105*2d543d20SAndroid Build Coastguard Worker    return (modules, support_macros)
1106*2d543d20SAndroid Build Coastguard Worker
1107*2d543d20SAndroid Build Coastguard Worker
1108*2d543d20SAndroid Build Coastguard Workerdef parse_headers(root, output=None, expand=True, debug=False):
1109*2d543d20SAndroid Build Coastguard Worker    from . import util
1110*2d543d20SAndroid Build Coastguard Worker
1111*2d543d20SAndroid Build Coastguard Worker    headers = refpolicy.Headers()
1112*2d543d20SAndroid Build Coastguard Worker
1113*2d543d20SAndroid Build Coastguard Worker    modules = []
1114*2d543d20SAndroid Build Coastguard Worker    support_macros = None
1115*2d543d20SAndroid Build Coastguard Worker
1116*2d543d20SAndroid Build Coastguard Worker    if os.path.isfile(root):
1117*2d543d20SAndroid Build Coastguard Worker        name = os.path.split(root)[1]
1118*2d543d20SAndroid Build Coastguard Worker        if name == '':
1119*2d543d20SAndroid Build Coastguard Worker            raise ValueError("Invalid file name %s" % root)
1120*2d543d20SAndroid Build Coastguard Worker        modname = os.path.splitext(name)
1121*2d543d20SAndroid Build Coastguard Worker        modules.append((modname[0], root))
1122*2d543d20SAndroid Build Coastguard Worker        all_modules, support_macros = list_headers(defaults.headers())
1123*2d543d20SAndroid Build Coastguard Worker    else:
1124*2d543d20SAndroid Build Coastguard Worker        modules, support_macros = list_headers(root)
1125*2d543d20SAndroid Build Coastguard Worker
1126*2d543d20SAndroid Build Coastguard Worker    if expand and not support_macros:
1127*2d543d20SAndroid Build Coastguard Worker        raise ValueError("could not find support macros (obj_perm_sets.spt)")
1128*2d543d20SAndroid Build Coastguard Worker
1129*2d543d20SAndroid Build Coastguard Worker    def o(msg):
1130*2d543d20SAndroid Build Coastguard Worker        if output:
1131*2d543d20SAndroid Build Coastguard Worker            output.write(msg)
1132*2d543d20SAndroid Build Coastguard Worker
1133*2d543d20SAndroid Build Coastguard Worker    def parse_file(f, module, spt=None):
1134*2d543d20SAndroid Build Coastguard Worker        global parse_file
1135*2d543d20SAndroid Build Coastguard Worker        if debug:
1136*2d543d20SAndroid Build Coastguard Worker            o("parsing file %s\n" % f)
1137*2d543d20SAndroid Build Coastguard Worker        try:
1138*2d543d20SAndroid Build Coastguard Worker            fd = open(f)
1139*2d543d20SAndroid Build Coastguard Worker            txt = fd.read()
1140*2d543d20SAndroid Build Coastguard Worker            fd.close()
1141*2d543d20SAndroid Build Coastguard Worker            parse_file = f
1142*2d543d20SAndroid Build Coastguard Worker            parse(txt, module, spt, debug)
1143*2d543d20SAndroid Build Coastguard Worker        except IOError as e:
1144*2d543d20SAndroid Build Coastguard Worker            return
1145*2d543d20SAndroid Build Coastguard Worker        except ValueError as e:
1146*2d543d20SAndroid Build Coastguard Worker            raise ValueError("error parsing file %s: %s" % (f, str(e)))
1147*2d543d20SAndroid Build Coastguard Worker
1148*2d543d20SAndroid Build Coastguard Worker    spt = None
1149*2d543d20SAndroid Build Coastguard Worker    if support_macros:
1150*2d543d20SAndroid Build Coastguard Worker        o("Parsing support macros (%s): " % support_macros)
1151*2d543d20SAndroid Build Coastguard Worker        spt = refpolicy.SupportMacros()
1152*2d543d20SAndroid Build Coastguard Worker        parse_file(support_macros, spt)
1153*2d543d20SAndroid Build Coastguard Worker
1154*2d543d20SAndroid Build Coastguard Worker        headers.children.append(spt)
1155*2d543d20SAndroid Build Coastguard Worker
1156*2d543d20SAndroid Build Coastguard Worker        # FIXME: Total hack - add in can_exec rather than parse the insanity
1157*2d543d20SAndroid Build Coastguard Worker        # of misc_macros. We are just going to pretend that this is an interface
1158*2d543d20SAndroid Build Coastguard Worker        # to make the expansion work correctly.
1159*2d543d20SAndroid Build Coastguard Worker        can_exec = refpolicy.Interface("can_exec")
1160*2d543d20SAndroid Build Coastguard Worker        av = access.AccessVector(["$1","$2","file","execute_no_trans","open", "read",
1161*2d543d20SAndroid Build Coastguard Worker                                  "getattr","lock","execute","ioctl"])
1162*2d543d20SAndroid Build Coastguard Worker
1163*2d543d20SAndroid Build Coastguard Worker        can_exec.children.append(refpolicy.AVRule(av))
1164*2d543d20SAndroid Build Coastguard Worker        headers.children.append(can_exec)
1165*2d543d20SAndroid Build Coastguard Worker
1166*2d543d20SAndroid Build Coastguard Worker        o("done.\n")
1167*2d543d20SAndroid Build Coastguard Worker
1168*2d543d20SAndroid Build Coastguard Worker    if output and not debug:
1169*2d543d20SAndroid Build Coastguard Worker        status = util.ConsoleProgressBar(sys.stdout, steps=len(modules))
1170*2d543d20SAndroid Build Coastguard Worker        status.start("Parsing interface files")
1171*2d543d20SAndroid Build Coastguard Worker
1172*2d543d20SAndroid Build Coastguard Worker    failures = []
1173*2d543d20SAndroid Build Coastguard Worker    for x in modules:
1174*2d543d20SAndroid Build Coastguard Worker        m = refpolicy.Module()
1175*2d543d20SAndroid Build Coastguard Worker        m.name = x[0]
1176*2d543d20SAndroid Build Coastguard Worker        try:
1177*2d543d20SAndroid Build Coastguard Worker            if expand:
1178*2d543d20SAndroid Build Coastguard Worker                parse_file(x[1], m, spt)
1179*2d543d20SAndroid Build Coastguard Worker            else:
1180*2d543d20SAndroid Build Coastguard Worker                parse_file(x[1], m)
1181*2d543d20SAndroid Build Coastguard Worker        except ValueError as e:
1182*2d543d20SAndroid Build Coastguard Worker            o(str(e) + "\n")
1183*2d543d20SAndroid Build Coastguard Worker            failures.append(x[1])
1184*2d543d20SAndroid Build Coastguard Worker            continue
1185*2d543d20SAndroid Build Coastguard Worker
1186*2d543d20SAndroid Build Coastguard Worker        headers.children.append(m)
1187*2d543d20SAndroid Build Coastguard Worker        if output and not debug:
1188*2d543d20SAndroid Build Coastguard Worker            status.step()
1189*2d543d20SAndroid Build Coastguard Worker
1190*2d543d20SAndroid Build Coastguard Worker    if len(failures):
1191*2d543d20SAndroid Build Coastguard Worker        o("failed to parse some headers: %s\n" % ", ".join(failures))
1192*2d543d20SAndroid Build Coastguard Worker
1193*2d543d20SAndroid Build Coastguard Worker    return headers
1194