xref: /aosp_15_r20/external/selinux/libsepol/cil/src/cil_parser.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker /*
2*2d543d20SAndroid Build Coastguard Worker  * Copyright 2011 Tresys Technology, LLC. All rights reserved.
3*2d543d20SAndroid Build Coastguard Worker  *
4*2d543d20SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
5*2d543d20SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
6*2d543d20SAndroid Build Coastguard Worker  *
7*2d543d20SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright notice,
8*2d543d20SAndroid Build Coastguard Worker  *       this list of conditions and the following disclaimer.
9*2d543d20SAndroid Build Coastguard Worker  *
10*2d543d20SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright notice,
11*2d543d20SAndroid Build Coastguard Worker  *       this list of conditions and the following disclaimer in the documentation
12*2d543d20SAndroid Build Coastguard Worker  *       and/or other materials provided with the distribution.
13*2d543d20SAndroid Build Coastguard Worker  *
14*2d543d20SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
15*2d543d20SAndroid Build Coastguard Worker  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16*2d543d20SAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17*2d543d20SAndroid Build Coastguard Worker  * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18*2d543d20SAndroid Build Coastguard Worker  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19*2d543d20SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*2d543d20SAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21*2d543d20SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
22*2d543d20SAndroid Build Coastguard Worker  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23*2d543d20SAndroid Build Coastguard Worker  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*2d543d20SAndroid Build Coastguard Worker  *
25*2d543d20SAndroid Build Coastguard Worker  * The views and conclusions contained in the software and documentation are those
26*2d543d20SAndroid Build Coastguard Worker  * of the authors and should not be interpreted as representing official policies,
27*2d543d20SAndroid Build Coastguard Worker  * either expressed or implied, of Tresys Technology, LLC.
28*2d543d20SAndroid Build Coastguard Worker  */
29*2d543d20SAndroid Build Coastguard Worker 
30*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
31*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
32*2d543d20SAndroid Build Coastguard Worker #include <string.h>
33*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
34*2d543d20SAndroid Build Coastguard Worker #include <sepol/errcodes.h>
35*2d543d20SAndroid Build Coastguard Worker 
36*2d543d20SAndroid Build Coastguard Worker #include "cil_internal.h"
37*2d543d20SAndroid Build Coastguard Worker #include "cil_log.h"
38*2d543d20SAndroid Build Coastguard Worker #include "cil_mem.h"
39*2d543d20SAndroid Build Coastguard Worker #include "cil_tree.h"
40*2d543d20SAndroid Build Coastguard Worker #include "cil_lexer.h"
41*2d543d20SAndroid Build Coastguard Worker #include "cil_parser.h"
42*2d543d20SAndroid Build Coastguard Worker #include "cil_strpool.h"
43*2d543d20SAndroid Build Coastguard Worker #include "cil_stack.h"
44*2d543d20SAndroid Build Coastguard Worker 
45*2d543d20SAndroid Build Coastguard Worker #define CIL_PARSER_MAX_EXPR_DEPTH (0x1 << 12)
46*2d543d20SAndroid Build Coastguard Worker 
47*2d543d20SAndroid Build Coastguard Worker struct hll_info {
48*2d543d20SAndroid Build Coastguard Worker 	uint32_t hll_offset;
49*2d543d20SAndroid Build Coastguard Worker 	uint32_t hll_expand;
50*2d543d20SAndroid Build Coastguard Worker };
51*2d543d20SAndroid Build Coastguard Worker 
push_hll_info(struct cil_stack * stack,uint32_t hll_offset,uint32_t hll_expand)52*2d543d20SAndroid Build Coastguard Worker static void push_hll_info(struct cil_stack *stack, uint32_t hll_offset, uint32_t hll_expand)
53*2d543d20SAndroid Build Coastguard Worker {
54*2d543d20SAndroid Build Coastguard Worker 	struct hll_info *new = cil_malloc(sizeof(*new));
55*2d543d20SAndroid Build Coastguard Worker 
56*2d543d20SAndroid Build Coastguard Worker 	new->hll_offset = hll_offset;
57*2d543d20SAndroid Build Coastguard Worker 	new->hll_expand = hll_expand;
58*2d543d20SAndroid Build Coastguard Worker 
59*2d543d20SAndroid Build Coastguard Worker 	cil_stack_push(stack, CIL_NONE, new);
60*2d543d20SAndroid Build Coastguard Worker }
61*2d543d20SAndroid Build Coastguard Worker 
pop_hll_info(struct cil_stack * stack,uint32_t * hll_offset,uint32_t * hll_expand)62*2d543d20SAndroid Build Coastguard Worker static void pop_hll_info(struct cil_stack *stack, uint32_t *hll_offset, uint32_t *hll_expand)
63*2d543d20SAndroid Build Coastguard Worker {
64*2d543d20SAndroid Build Coastguard Worker 	struct cil_stack_item *curr = cil_stack_pop(stack);
65*2d543d20SAndroid Build Coastguard Worker 	struct hll_info *info;
66*2d543d20SAndroid Build Coastguard Worker 
67*2d543d20SAndroid Build Coastguard Worker 	if (!curr) {
68*2d543d20SAndroid Build Coastguard Worker 		return;
69*2d543d20SAndroid Build Coastguard Worker 	}
70*2d543d20SAndroid Build Coastguard Worker 	info = curr->data;
71*2d543d20SAndroid Build Coastguard Worker 	*hll_expand = info->hll_expand;
72*2d543d20SAndroid Build Coastguard Worker 	*hll_offset = info->hll_offset;
73*2d543d20SAndroid Build Coastguard Worker 	free(curr->data);
74*2d543d20SAndroid Build Coastguard Worker }
75*2d543d20SAndroid Build Coastguard Worker 
create_node(struct cil_tree_node ** node,struct cil_tree_node * current,uint32_t line,uint32_t hll_offset,void * value)76*2d543d20SAndroid Build Coastguard Worker static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, uint32_t line, uint32_t hll_offset, void *value)
77*2d543d20SAndroid Build Coastguard Worker {
78*2d543d20SAndroid Build Coastguard Worker 	cil_tree_node_init(node);
79*2d543d20SAndroid Build Coastguard Worker 	(*node)->parent = current;
80*2d543d20SAndroid Build Coastguard Worker 	(*node)->flavor = CIL_NODE;
81*2d543d20SAndroid Build Coastguard Worker 	(*node)->line = line;
82*2d543d20SAndroid Build Coastguard Worker 	(*node)->hll_offset = hll_offset;
83*2d543d20SAndroid Build Coastguard Worker 	(*node)->data = value;
84*2d543d20SAndroid Build Coastguard Worker }
85*2d543d20SAndroid Build Coastguard Worker 
insert_node(struct cil_tree_node * node,struct cil_tree_node * current)86*2d543d20SAndroid Build Coastguard Worker static void insert_node(struct cil_tree_node *node, struct cil_tree_node *current)
87*2d543d20SAndroid Build Coastguard Worker {
88*2d543d20SAndroid Build Coastguard Worker 	if (current->cl_head == NULL) {
89*2d543d20SAndroid Build Coastguard Worker 		current->cl_head = node;
90*2d543d20SAndroid Build Coastguard Worker 	} else {
91*2d543d20SAndroid Build Coastguard Worker 		current->cl_tail->next = node;
92*2d543d20SAndroid Build Coastguard Worker 	}
93*2d543d20SAndroid Build Coastguard Worker 	current->cl_tail = node;
94*2d543d20SAndroid Build Coastguard Worker }
95*2d543d20SAndroid Build Coastguard Worker 
add_hll_linemark(struct cil_tree_node ** current,uint32_t * hll_offset,uint32_t * hll_expand,struct cil_stack * stack,char * path)96*2d543d20SAndroid Build Coastguard Worker static int add_hll_linemark(struct cil_tree_node **current, uint32_t *hll_offset, uint32_t *hll_expand, struct cil_stack *stack, char *path)
97*2d543d20SAndroid Build Coastguard Worker {
98*2d543d20SAndroid Build Coastguard Worker 	char *hll_type;
99*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *node;
100*2d543d20SAndroid Build Coastguard Worker 	struct token tok;
101*2d543d20SAndroid Build Coastguard Worker 	uint32_t prev_hll_expand, prev_hll_offset;
102*2d543d20SAndroid Build Coastguard Worker 
103*2d543d20SAndroid Build Coastguard Worker 	cil_lexer_next(&tok);
104*2d543d20SAndroid Build Coastguard Worker 	if (tok.type != SYMBOL) {
105*2d543d20SAndroid Build Coastguard Worker 		cil_log(CIL_ERR, "Invalid line mark syntax\n");
106*2d543d20SAndroid Build Coastguard Worker 		goto exit;
107*2d543d20SAndroid Build Coastguard Worker 	}
108*2d543d20SAndroid Build Coastguard Worker 	hll_type = cil_strpool_add(tok.value);
109*2d543d20SAndroid Build Coastguard Worker 	if (hll_type != CIL_KEY_SRC_HLL_LME && hll_type != CIL_KEY_SRC_HLL_LMS && hll_type != CIL_KEY_SRC_HLL_LMX) {
110*2d543d20SAndroid Build Coastguard Worker 		cil_log(CIL_ERR, "Invalid line mark syntax\n");
111*2d543d20SAndroid Build Coastguard Worker 		goto exit;
112*2d543d20SAndroid Build Coastguard Worker 	}
113*2d543d20SAndroid Build Coastguard Worker 	if (hll_type == CIL_KEY_SRC_HLL_LME) {
114*2d543d20SAndroid Build Coastguard Worker 		if (cil_stack_is_empty(stack)) {
115*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Line mark end without start\n");
116*2d543d20SAndroid Build Coastguard Worker 			goto exit;
117*2d543d20SAndroid Build Coastguard Worker 		}
118*2d543d20SAndroid Build Coastguard Worker 		prev_hll_expand = *hll_expand;
119*2d543d20SAndroid Build Coastguard Worker 		prev_hll_offset = *hll_offset;
120*2d543d20SAndroid Build Coastguard Worker 		pop_hll_info(stack, hll_offset, hll_expand);
121*2d543d20SAndroid Build Coastguard Worker 		if (!*hll_expand) {
122*2d543d20SAndroid Build Coastguard Worker 			/* This is needed if not going back to an lmx section. */
123*2d543d20SAndroid Build Coastguard Worker 			*hll_offset = prev_hll_offset;
124*2d543d20SAndroid Build Coastguard Worker 		}
125*2d543d20SAndroid Build Coastguard Worker 		if (prev_hll_expand && !*hll_expand) {
126*2d543d20SAndroid Build Coastguard Worker 			/* This is needed to count the lme at the end of an lmx section
127*2d543d20SAndroid Build Coastguard Worker 			 * within an lms section (or within no hll section).
128*2d543d20SAndroid Build Coastguard Worker 			 */
129*2d543d20SAndroid Build Coastguard Worker 			(*hll_offset)++;
130*2d543d20SAndroid Build Coastguard Worker 		}
131*2d543d20SAndroid Build Coastguard Worker 		*current = (*current)->parent;
132*2d543d20SAndroid Build Coastguard Worker 	} else {
133*2d543d20SAndroid Build Coastguard Worker 		push_hll_info(stack, *hll_offset, *hll_expand);
134*2d543d20SAndroid Build Coastguard Worker 		if (cil_stack_number_of_items(stack) > CIL_PARSER_MAX_EXPR_DEPTH) {
135*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Number of active line marks exceeds limit of %d\n", CIL_PARSER_MAX_EXPR_DEPTH);
136*2d543d20SAndroid Build Coastguard Worker 			goto exit;
137*2d543d20SAndroid Build Coastguard Worker 		}
138*2d543d20SAndroid Build Coastguard Worker 
139*2d543d20SAndroid Build Coastguard Worker 		create_node(&node, *current, tok.line, *hll_offset, NULL);
140*2d543d20SAndroid Build Coastguard Worker 		insert_node(node, *current);
141*2d543d20SAndroid Build Coastguard Worker 		*current = node;
142*2d543d20SAndroid Build Coastguard Worker 
143*2d543d20SAndroid Build Coastguard Worker 		create_node(&node, *current, tok.line, *hll_offset, CIL_KEY_SRC_INFO);
144*2d543d20SAndroid Build Coastguard Worker 		insert_node(node, *current);
145*2d543d20SAndroid Build Coastguard Worker 
146*2d543d20SAndroid Build Coastguard Worker 		create_node(&node, *current, tok.line, *hll_offset, hll_type);
147*2d543d20SAndroid Build Coastguard Worker 		insert_node(node, *current);
148*2d543d20SAndroid Build Coastguard Worker 
149*2d543d20SAndroid Build Coastguard Worker 		cil_lexer_next(&tok);
150*2d543d20SAndroid Build Coastguard Worker 		if (tok.type != SYMBOL) {
151*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Invalid line mark syntax\n");
152*2d543d20SAndroid Build Coastguard Worker 			goto exit;
153*2d543d20SAndroid Build Coastguard Worker 		}
154*2d543d20SAndroid Build Coastguard Worker 
155*2d543d20SAndroid Build Coastguard Worker 		create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value));
156*2d543d20SAndroid Build Coastguard Worker 		insert_node(node, *current);
157*2d543d20SAndroid Build Coastguard Worker 
158*2d543d20SAndroid Build Coastguard Worker 		cil_lexer_next(&tok);
159*2d543d20SAndroid Build Coastguard Worker 		if (tok.type != SYMBOL && tok.type != QSTRING) {
160*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Invalid line mark syntax\n");
161*2d543d20SAndroid Build Coastguard Worker 			goto exit;
162*2d543d20SAndroid Build Coastguard Worker 		}
163*2d543d20SAndroid Build Coastguard Worker 
164*2d543d20SAndroid Build Coastguard Worker 		if (tok.type == QSTRING) {
165*2d543d20SAndroid Build Coastguard Worker 			tok.value[strlen(tok.value) - 1] = '\0';
166*2d543d20SAndroid Build Coastguard Worker 			tok.value = tok.value+1;
167*2d543d20SAndroid Build Coastguard Worker 		}
168*2d543d20SAndroid Build Coastguard Worker 
169*2d543d20SAndroid Build Coastguard Worker 		create_node(&node, *current, tok.line, *hll_offset, cil_strpool_add(tok.value));
170*2d543d20SAndroid Build Coastguard Worker 		insert_node(node, *current);
171*2d543d20SAndroid Build Coastguard Worker 
172*2d543d20SAndroid Build Coastguard Worker 		*hll_expand = (hll_type == CIL_KEY_SRC_HLL_LMX) ? 1 : 0;
173*2d543d20SAndroid Build Coastguard Worker 	}
174*2d543d20SAndroid Build Coastguard Worker 
175*2d543d20SAndroid Build Coastguard Worker 	cil_lexer_next(&tok);
176*2d543d20SAndroid Build Coastguard Worker 	if (tok.type != NEWLINE) {
177*2d543d20SAndroid Build Coastguard Worker 		cil_log(CIL_ERR, "Invalid line mark syntax\n");
178*2d543d20SAndroid Build Coastguard Worker 		goto exit;
179*2d543d20SAndroid Build Coastguard Worker 	}
180*2d543d20SAndroid Build Coastguard Worker 
181*2d543d20SAndroid Build Coastguard Worker 	if (!*hll_expand) {
182*2d543d20SAndroid Build Coastguard Worker 		/* Need to increment because of the NEWLINE */
183*2d543d20SAndroid Build Coastguard Worker 		(*hll_offset)++;
184*2d543d20SAndroid Build Coastguard Worker 	}
185*2d543d20SAndroid Build Coastguard Worker 
186*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_OK;
187*2d543d20SAndroid Build Coastguard Worker 
188*2d543d20SAndroid Build Coastguard Worker exit:
189*2d543d20SAndroid Build Coastguard Worker 	cil_log(CIL_ERR, "Problem with high-level line mark at line %u of %s\n", tok.line, path);
190*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_ERR;
191*2d543d20SAndroid Build Coastguard Worker }
192*2d543d20SAndroid Build Coastguard Worker 
add_cil_path(struct cil_tree_node ** current,char * path)193*2d543d20SAndroid Build Coastguard Worker static void add_cil_path(struct cil_tree_node **current, char *path)
194*2d543d20SAndroid Build Coastguard Worker {
195*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *node;
196*2d543d20SAndroid Build Coastguard Worker 
197*2d543d20SAndroid Build Coastguard Worker 	create_node(&node, *current, 0, 0, NULL);
198*2d543d20SAndroid Build Coastguard Worker 	insert_node(node, *current);
199*2d543d20SAndroid Build Coastguard Worker 	*current = node;
200*2d543d20SAndroid Build Coastguard Worker 
201*2d543d20SAndroid Build Coastguard Worker 	create_node(&node, *current, 0, 0, CIL_KEY_SRC_INFO);
202*2d543d20SAndroid Build Coastguard Worker 	insert_node(node, *current);
203*2d543d20SAndroid Build Coastguard Worker 
204*2d543d20SAndroid Build Coastguard Worker 	create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL);
205*2d543d20SAndroid Build Coastguard Worker 	insert_node(node, *current);
206*2d543d20SAndroid Build Coastguard Worker 
207*2d543d20SAndroid Build Coastguard Worker 	create_node(&node, *current, 0, 0, cil_strpool_add("1"));
208*2d543d20SAndroid Build Coastguard Worker 	insert_node(node, *current);
209*2d543d20SAndroid Build Coastguard Worker 
210*2d543d20SAndroid Build Coastguard Worker 	create_node(&node, *current, 0, 0, path);
211*2d543d20SAndroid Build Coastguard Worker 	insert_node(node, *current);
212*2d543d20SAndroid Build Coastguard Worker }
213*2d543d20SAndroid Build Coastguard Worker 
cil_parser(const char * _path,char * buffer,uint32_t size,struct cil_tree ** parse_tree)214*2d543d20SAndroid Build Coastguard Worker int cil_parser(const char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree)
215*2d543d20SAndroid Build Coastguard Worker {
216*2d543d20SAndroid Build Coastguard Worker 
217*2d543d20SAndroid Build Coastguard Worker 	int paren_count = 0;
218*2d543d20SAndroid Build Coastguard Worker 
219*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree *tree = NULL;
220*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *node = NULL;
221*2d543d20SAndroid Build Coastguard Worker 	struct cil_tree_node *current = NULL;
222*2d543d20SAndroid Build Coastguard Worker 	char *path = cil_strpool_add(_path);
223*2d543d20SAndroid Build Coastguard Worker 	struct cil_stack *stack;
224*2d543d20SAndroid Build Coastguard Worker 	uint32_t hll_offset = 1;
225*2d543d20SAndroid Build Coastguard Worker 	uint32_t hll_expand = 0;
226*2d543d20SAndroid Build Coastguard Worker 	struct token tok;
227*2d543d20SAndroid Build Coastguard Worker 	int rc = SEPOL_OK;
228*2d543d20SAndroid Build Coastguard Worker 
229*2d543d20SAndroid Build Coastguard Worker 	cil_stack_init(&stack);
230*2d543d20SAndroid Build Coastguard Worker 
231*2d543d20SAndroid Build Coastguard Worker 	cil_lexer_setup(buffer, size);
232*2d543d20SAndroid Build Coastguard Worker 
233*2d543d20SAndroid Build Coastguard Worker 	tree = *parse_tree;
234*2d543d20SAndroid Build Coastguard Worker 	current = tree->root;
235*2d543d20SAndroid Build Coastguard Worker 
236*2d543d20SAndroid Build Coastguard Worker 	add_cil_path(&current, path);
237*2d543d20SAndroid Build Coastguard Worker 
238*2d543d20SAndroid Build Coastguard Worker 	do {
239*2d543d20SAndroid Build Coastguard Worker 		cil_lexer_next(&tok);
240*2d543d20SAndroid Build Coastguard Worker 		switch (tok.type) {
241*2d543d20SAndroid Build Coastguard Worker 		case HLL_LINEMARK:
242*2d543d20SAndroid Build Coastguard Worker 			rc = add_hll_linemark(&current, &hll_offset, &hll_expand, stack, path);
243*2d543d20SAndroid Build Coastguard Worker 			if (rc != SEPOL_OK) {
244*2d543d20SAndroid Build Coastguard Worker 				goto exit;
245*2d543d20SAndroid Build Coastguard Worker 			}
246*2d543d20SAndroid Build Coastguard Worker 			break;
247*2d543d20SAndroid Build Coastguard Worker 		case OPAREN:
248*2d543d20SAndroid Build Coastguard Worker 			paren_count++;
249*2d543d20SAndroid Build Coastguard Worker 			if (paren_count > CIL_PARSER_MAX_EXPR_DEPTH) {
250*2d543d20SAndroid Build Coastguard Worker 				cil_log(CIL_ERR, "Number of open parenthesis exceeds limit of %d at line %d of %s\n", CIL_PARSER_MAX_EXPR_DEPTH, tok.line, path);
251*2d543d20SAndroid Build Coastguard Worker 				goto exit;
252*2d543d20SAndroid Build Coastguard Worker 			}
253*2d543d20SAndroid Build Coastguard Worker 			create_node(&node, current, tok.line, hll_offset, NULL);
254*2d543d20SAndroid Build Coastguard Worker 			insert_node(node, current);
255*2d543d20SAndroid Build Coastguard Worker 			current = node;
256*2d543d20SAndroid Build Coastguard Worker 			break;
257*2d543d20SAndroid Build Coastguard Worker 		case CPAREN:
258*2d543d20SAndroid Build Coastguard Worker 			paren_count--;
259*2d543d20SAndroid Build Coastguard Worker 			if (paren_count < 0) {
260*2d543d20SAndroid Build Coastguard Worker 				cil_log(CIL_ERR, "Close parenthesis without matching open at line %d of %s\n", tok.line, path);
261*2d543d20SAndroid Build Coastguard Worker 				goto exit;
262*2d543d20SAndroid Build Coastguard Worker 			}
263*2d543d20SAndroid Build Coastguard Worker 			current = current->parent;
264*2d543d20SAndroid Build Coastguard Worker 			break;
265*2d543d20SAndroid Build Coastguard Worker 		case QSTRING:
266*2d543d20SAndroid Build Coastguard Worker 			tok.value[strlen(tok.value) - 1] = '\0';
267*2d543d20SAndroid Build Coastguard Worker 			tok.value = tok.value+1;
268*2d543d20SAndroid Build Coastguard Worker 			/* FALLTHRU */
269*2d543d20SAndroid Build Coastguard Worker 		case SYMBOL:
270*2d543d20SAndroid Build Coastguard Worker 			if (paren_count == 0) {
271*2d543d20SAndroid Build Coastguard Worker 				cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path);
272*2d543d20SAndroid Build Coastguard Worker 				goto exit;
273*2d543d20SAndroid Build Coastguard Worker 			}
274*2d543d20SAndroid Build Coastguard Worker 
275*2d543d20SAndroid Build Coastguard Worker 			create_node(&node, current, tok.line, hll_offset, cil_strpool_add(tok.value));
276*2d543d20SAndroid Build Coastguard Worker 			insert_node(node, current);
277*2d543d20SAndroid Build Coastguard Worker 			break;
278*2d543d20SAndroid Build Coastguard Worker 		case NEWLINE :
279*2d543d20SAndroid Build Coastguard Worker 			if (!hll_expand) {
280*2d543d20SAndroid Build Coastguard Worker 				hll_offset++;
281*2d543d20SAndroid Build Coastguard Worker 			}
282*2d543d20SAndroid Build Coastguard Worker 			break;
283*2d543d20SAndroid Build Coastguard Worker 		case COMMENT:
284*2d543d20SAndroid Build Coastguard Worker 			while (tok.type != NEWLINE && tok.type != END_OF_FILE) {
285*2d543d20SAndroid Build Coastguard Worker 				cil_lexer_next(&tok);
286*2d543d20SAndroid Build Coastguard Worker 			}
287*2d543d20SAndroid Build Coastguard Worker 			if (!hll_expand) {
288*2d543d20SAndroid Build Coastguard Worker 				hll_offset++;
289*2d543d20SAndroid Build Coastguard Worker 			}
290*2d543d20SAndroid Build Coastguard Worker 			if (tok.type != END_OF_FILE) {
291*2d543d20SAndroid Build Coastguard Worker 				break;
292*2d543d20SAndroid Build Coastguard Worker 			}
293*2d543d20SAndroid Build Coastguard Worker 			/* FALLTHRU */
294*2d543d20SAndroid Build Coastguard Worker 			// Fall through if EOF
295*2d543d20SAndroid Build Coastguard Worker 		case END_OF_FILE:
296*2d543d20SAndroid Build Coastguard Worker 			if (paren_count > 0) {
297*2d543d20SAndroid Build Coastguard Worker 				cil_log(CIL_ERR, "Open parenthesis without matching close at line %d of %s\n", tok.line, path);
298*2d543d20SAndroid Build Coastguard Worker 				goto exit;
299*2d543d20SAndroid Build Coastguard Worker 			}
300*2d543d20SAndroid Build Coastguard Worker 			if (!cil_stack_is_empty(stack)) {
301*2d543d20SAndroid Build Coastguard Worker 				cil_log(CIL_ERR, "High-level language line marker start without close at line %d of %s\n", tok.line, path);
302*2d543d20SAndroid Build Coastguard Worker 				goto exit;
303*2d543d20SAndroid Build Coastguard Worker 			}
304*2d543d20SAndroid Build Coastguard Worker 			break;
305*2d543d20SAndroid Build Coastguard Worker 		case UNKNOWN:
306*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path);
307*2d543d20SAndroid Build Coastguard Worker 			goto exit;
308*2d543d20SAndroid Build Coastguard Worker 		default:
309*2d543d20SAndroid Build Coastguard Worker 			cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path);
310*2d543d20SAndroid Build Coastguard Worker 			goto exit;
311*2d543d20SAndroid Build Coastguard Worker 		}
312*2d543d20SAndroid Build Coastguard Worker 	}
313*2d543d20SAndroid Build Coastguard Worker 	while (tok.type != END_OF_FILE);
314*2d543d20SAndroid Build Coastguard Worker 
315*2d543d20SAndroid Build Coastguard Worker 	cil_lexer_destroy();
316*2d543d20SAndroid Build Coastguard Worker 
317*2d543d20SAndroid Build Coastguard Worker 	cil_stack_destroy(&stack);
318*2d543d20SAndroid Build Coastguard Worker 
319*2d543d20SAndroid Build Coastguard Worker 	*parse_tree = tree;
320*2d543d20SAndroid Build Coastguard Worker 
321*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_OK;
322*2d543d20SAndroid Build Coastguard Worker 
323*2d543d20SAndroid Build Coastguard Worker exit:
324*2d543d20SAndroid Build Coastguard Worker 	while (!cil_stack_is_empty(stack)) {
325*2d543d20SAndroid Build Coastguard Worker 		pop_hll_info(stack, &hll_offset, &hll_expand);
326*2d543d20SAndroid Build Coastguard Worker 	}
327*2d543d20SAndroid Build Coastguard Worker 	cil_lexer_destroy();
328*2d543d20SAndroid Build Coastguard Worker 	cil_stack_destroy(&stack);
329*2d543d20SAndroid Build Coastguard Worker 
330*2d543d20SAndroid Build Coastguard Worker 	return SEPOL_ERR;
331*2d543d20SAndroid Build Coastguard Worker }
332