Skip to content

Commit f0460f1

Browse files
cgzonesdburgener
authored andcommitted
Refactor yyparse_wrapper()
Check that the expected file type got parsed
1 parent 8195109 commit f0460f1

File tree

5 files changed

+79
-59
lines changed

5 files changed

+79
-59
lines changed

src/parse.y

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@
3737
// local variables
3838
static const char *parsing_filename;
3939
static struct policy_node *cur;
40+
static enum node_flavor expected_node_flavor;
4041
%}
4142

4243
%code provides {
4344
// global prototype
44-
int yyparse_wrapper(FILE *filefd, const char *filename, struct policy_node **ast);
45+
struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor);
4546
}
4647

4748
%union {
@@ -194,9 +195,19 @@ comment:
194195

195196

196197
header:
197-
POLICY_MODULE OPEN_PAREN STRING COMMA header_version CLOSE_PAREN { insert_header(&cur, $3, HEADER_MACRO, yylineno); free($3); } // Version number isn't needed
198+
POLICY_MODULE OPEN_PAREN STRING COMMA header_version CLOSE_PAREN {
199+
if (expected_node_flavor != NODE_TE_FILE) {
200+
free($3);
201+
yyerror("Error: Unexpected te-file parsed"); YYERROR;
202+
}
203+
insert_header(&cur, $3, HEADER_MACRO, yylineno); free($3); } // Version number isn't needed
198204
|
199-
MODULE STRING header_version SEMICOLON { insert_header(&cur, $2, HEADER_BARE, yylineno); free($2); }
205+
MODULE STRING header_version SEMICOLON {
206+
if (expected_node_flavor != NODE_TE_FILE) {
207+
free($2);
208+
yyerror("Error: Unexpected te-file parsed"); YYERROR;
209+
}
210+
insert_header(&cur, $2, HEADER_BARE, yylineno); free($2); }
200211
;
201212

202213
header_version:
@@ -776,9 +787,11 @@ if_line:
776787
;
777788

778789
interface_def:
779-
start_interface lines end_interface
790+
start_interface { if (expected_node_flavor != NODE_IF_FILE) { yyerror("Error: Unexpected if-file parsed"); YYERROR; } }
791+
lines end_interface
780792
|
781-
start_interface end_interface
793+
start_interface { if (expected_node_flavor != NODE_IF_FILE) { yyerror("Error: Unexpected if-file parsed"); YYERROR; } }
794+
end_interface
782795
;
783796

784797
start_interface:
@@ -816,6 +829,10 @@ spt_line:
816829

817830
support_def:
818831
DEFINE OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK string_list SINGLE_QUOTE CLOSE_PAREN {
832+
if (expected_node_flavor != NODE_SPT_FILE) {
833+
free($4); free_string_list($8);
834+
yyerror("Error: Unexpected spt-file parsed"); YYERROR;
835+
}
819836
if (ends_with($4, strlen($4), "_perms", strlen("_perms"))) {
820837
insert_into_permmacros_map($4, $8);
821838
} else {
@@ -824,6 +841,10 @@ support_def:
824841
free($4); }
825842
|
826843
DEFINE OPEN_PAREN BACKTICK STRING SINGLE_QUOTE COMMA BACKTICK string_list refpolicywarn SINGLE_QUOTE CLOSE_PAREN {
844+
if (expected_node_flavor != NODE_SPT_FILE) {
845+
free($4); free_string_list($8);
846+
yyerror("Error: Unexpected spt-file parsed"); YYERROR;
847+
}
827848
free($4); free_string_list($8); } // do not import
828849
;
829850

@@ -844,11 +865,19 @@ void yyerror(const char* s) {
844865
free_check_result(res);
845866
}
846867

847-
int yyparse_wrapper(FILE *filefd, const char *filename, struct policy_node **ast) {
868+
struct policy_node *yyparse_wrapper(FILE *filefd, const char *filename, enum node_flavor expected_flavor) {
869+
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
870+
ast->flavor = expected_node_flavor = expected_flavor;
848871
yyrestart(filefd);
849872
yylineno = 1;
850873
parsing_filename = filename;
851-
cur = *ast;
874+
cur = ast;
875+
876+
if (0 != yyparse()) {
877+
// parser will have printed an error message
878+
free_policy_node(ast);
879+
return NULL;
880+
}
852881

853-
return yyparse();
882+
return ast;
854883
}

src/runner.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
struct policy_node *parse_one_file(const char *filename, enum node_flavor flavor)
3333
{
3434

35-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
36-
ast->flavor = flavor;
3735
char *copy = strdup(filename);
3836
char *mod_name = basename(copy);
3937
mod_name[strlen(mod_name) - 3] = '\0'; // Remove suffix
@@ -43,14 +41,10 @@ struct policy_node *parse_one_file(const char *filename, enum node_flavor flavor
4341
FILE *f = fopen(filename, "r");
4442
if (!f) {
4543
printf("Error opening %s\n", filename);
46-
free_policy_node(ast);
47-
return NULL;
48-
}
49-
if (0 != yyparse_wrapper(f, filename, &ast)) {
50-
free_policy_node(ast);
51-
fclose(f);
5244
return NULL;
5345
}
46+
47+
struct policy_node *ast = yyparse_wrapper(f, filename, flavor);
5448
fclose(f);
5549

5650
// dont run cleanup_parsing until everything is done because it frees the maps

src/startup.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,24 +137,19 @@ enum selint_error load_modules_source(const char *modules_conf_path)
137137

138138
enum selint_error load_obj_perm_sets_source(const char *obj_perm_sets_path)
139139
{
140-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
141-
ast->flavor = NODE_SPT_FILE;
142-
143140
FILE *f = fopen(obj_perm_sets_path, "r");
144141
if (!f) {
145-
free_policy_node(ast);
146142
return SELINT_IO_ERROR;
147143
}
148144

149-
if (0 != yyparse_wrapper(f, obj_perm_sets_path, &ast)) {
150-
free_policy_node(ast);
151-
fclose(f);
145+
struct policy_node *ast = yyparse_wrapper(f, obj_perm_sets_path, NODE_SPT_FILE);
146+
fclose(f);
147+
148+
if (ast == NULL) {
152149
return SELINT_PARSE_ERROR;
153150
}
154151

155152
free_policy_node(ast);
156-
fclose(f);
157-
158153
return SELINT_SUCCESS;
159154
}
160155

tests/check_parsing.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,12 @@
3434

3535
START_TEST (test_parse_basic_te) {
3636

37-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
38-
ast->flavor = NODE_TE_FILE;
3937
set_current_module_name("basic");
4038

4139
FILE *f = fopen(BASIC_TE_FILENAME, "r");
4240
ck_assert_ptr_nonnull(f);
43-
ck_assert_int_eq(0, yyparse_wrapper(f, BASIC_TE_FILENAME, &ast));
41+
struct policy_node *ast = yyparse_wrapper(f, BASIC_TE_FILENAME, NODE_TE_FILE);
42+
ck_assert_ptr_nonnull(ast);
4443

4544
struct policy_node *current = ast;
4645

@@ -100,13 +99,12 @@ END_TEST
10099

101100
START_TEST (test_parse_basic_if) {
102101

103-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
104-
ast->flavor = NODE_IF_FILE;
105102
set_current_module_name("basic");
106103

107104
FILE *f = fopen(BASIC_IF_FILENAME, "r");
108105
ck_assert_ptr_nonnull(f);
109-
ck_assert_int_eq(0, yyparse_wrapper(f, BASIC_IF_FILENAME, &ast));
106+
struct policy_node *ast = yyparse_wrapper(f, BASIC_IF_FILENAME, NODE_IF_FILE);
107+
ck_assert_ptr_nonnull(ast);
110108

111109
struct policy_node *current = ast;
112110

@@ -180,12 +178,12 @@ END_TEST
180178

181179
START_TEST (test_parse_uncommon_constructs) {
182180

183-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
184181
set_current_module_name("uncommon");
185182

186183
FILE *f = fopen(UNCOMMON_TE_FILENAME, "r");
187184
ck_assert_ptr_nonnull(f);
188-
ck_assert_int_eq(0, yyparse_wrapper(f, UNCOMMON_TE_FILENAME, &ast));
185+
struct policy_node *ast = yyparse_wrapper(f, UNCOMMON_TE_FILENAME, NODE_TE_FILE);
186+
ck_assert_ptr_nonnull(ast);
189187

190188
ck_assert_ptr_nonnull(ast);
191189

@@ -197,12 +195,12 @@ END_TEST
197195

198196
START_TEST (test_parse_blocks) {
199197

200-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
201198
set_current_module_name("blocks");
202199

203200
FILE *f = fopen(BLOCKS_TE_FILENAME, "r");
204201
ck_assert_ptr_nonnull(f);
205-
ck_assert_int_eq(0, yyparse_wrapper(f, BLOCKS_TE_FILENAME, &ast));
202+
struct policy_node *ast = yyparse_wrapper(f, BLOCKS_TE_FILENAME, NODE_TE_FILE);
203+
ck_assert_ptr_nonnull(ast);
206204

207205
ck_assert_ptr_nonnull(ast);
208206

@@ -234,13 +232,11 @@ END_TEST
234232

235233
START_TEST (test_parse_empty_file) {
236234

237-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
238235
set_current_module_name("empty");
239236

240237
FILE *f = fopen(EMPTY_TE_FILENAME, "r");
241238
ck_assert_ptr_nonnull(f);
242-
ck_assert_int_eq(0, yyparse_wrapper(f, EMPTY_TE_FILENAME, &ast));
243-
239+
struct policy_node *ast = yyparse_wrapper(f, EMPTY_TE_FILENAME, NODE_TE_FILE);
244240
ck_assert_ptr_nonnull(ast);
245241

246242
ck_assert_int_eq(NODE_EMPTY, ast->flavor);
@@ -256,14 +252,12 @@ END_TEST
256252

257253
START_TEST (test_syntax_error) {
258254

259-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
260255
set_current_module_name("syntax_error");
261256

262257
FILE *f = fopen(SYNTAX_ERROR_FILENAME, "r");
263258
ck_assert_ptr_nonnull(f);
264-
ck_assert_int_eq(1, yyparse_wrapper(f, SYNTAX_ERROR_FILENAME, &ast));
259+
ck_assert_ptr_null(yyparse_wrapper(f, SYNTAX_ERROR_FILENAME, NODE_TE_FILE));
265260

266-
free_policy_node(ast);
267261
cleanup_parsing();
268262
fclose(f);
269263

@@ -272,14 +266,12 @@ END_TEST
272266

273267
START_TEST (test_parse_bad_role_allow) {
274268

275-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
276269
set_current_module_name("bad_ra");
277270

278271
FILE *f = fopen(BAD_RA_FILENAME, "r");
279272
ck_assert_ptr_nonnull(f);
280-
ck_assert_int_eq(1, yyparse_wrapper(f, BAD_RA_FILENAME, &ast));
273+
ck_assert_ptr_null(yyparse_wrapper(f, BAD_RA_FILENAME, NODE_TE_FILE));
281274

282-
free_policy_node(ast);
283275
cleanup_parsing();
284276
fclose(f);
285277

@@ -288,12 +280,12 @@ END_TEST
288280

289281
START_TEST (test_disable_comment) {
290282

291-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
292283
set_current_module_name("disable_comment");
293284

294285
FILE *f = fopen(DISABLE_COMMENT_FILENAME, "r");
295286
ck_assert_ptr_nonnull(f);
296-
ck_assert_int_eq(0, yyparse_wrapper(f, DISABLE_COMMENT_FILENAME, &ast));
287+
struct policy_node *ast = yyparse_wrapper(f, DISABLE_COMMENT_FILENAME, NODE_TE_FILE);
288+
ck_assert_ptr_nonnull(ast);
297289

298290
ck_assert_ptr_nonnull(ast);
299291
ck_assert_int_eq(NODE_TE_FILE, ast->flavor);
@@ -314,12 +306,12 @@ END_TEST
314306

315307
START_TEST (test_bool_declarations) {
316308

317-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
318309
set_current_module_name("bool_declarations");
319310

320311
FILE *f = fopen(BOOL_DECLARATION_FILENAME, "r");
321312
ck_assert_ptr_nonnull(f);
322-
ck_assert_int_eq(0, yyparse_wrapper(f, BOOL_DECLARATION_FILENAME, &ast));
313+
struct policy_node *ast = yyparse_wrapper(f, BOOL_DECLARATION_FILENAME, NODE_TE_FILE);
314+
ck_assert_ptr_nonnull(ast);
323315

324316
struct policy_node *current = ast;
325317

@@ -435,6 +427,20 @@ START_TEST (test_bool_declarations) {
435427
}
436428
END_TEST
437429

430+
START_TEST (test_file_flavor_mismatch) {
431+
432+
set_current_module_name("basic");
433+
434+
FILE *f = fopen(BASIC_TE_FILENAME, "r");
435+
ck_assert_ptr_nonnull(f);
436+
ck_assert_ptr_null(yyparse_wrapper(f, BASIC_TE_FILENAME, NODE_IF_FILE));
437+
438+
cleanup_parsing();
439+
fclose(f);
440+
441+
}
442+
END_TEST
443+
438444
Suite *parsing_suite(void) {
439445
Suite *s;
440446
TCase *tc_core;
@@ -452,6 +458,7 @@ Suite *parsing_suite(void) {
452458
tcase_add_test(tc_core, test_parse_bad_role_allow);
453459
tcase_add_test(tc_core, test_disable_comment);
454460
tcase_add_test(tc_core, test_bool_declarations);
461+
tcase_add_test(tc_core, test_file_flavor_mismatch);
455462
suite_add_tcase(s, tc_core);
456463

457464
return s;

tests/check_template.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,12 @@ END_TEST
169169

170170
START_TEST (test_nested_template_declarations) {
171171

172-
struct policy_node *ast = calloc(1, sizeof(struct policy_node));
173-
ast->flavor = NODE_IF_FILE;
174172
set_current_module_name("nested");
175173

176174
FILE *f = fopen(NESTED_IF_FILENAME, "r");
177175
ck_assert_ptr_nonnull(f);
178-
ck_assert_int_eq(0, yyparse_wrapper(f, NESTED_IF_FILENAME, &ast));
176+
struct policy_node *ast = yyparse_wrapper(f, NESTED_IF_FILENAME, NODE_IF_FILE);
177+
ck_assert_ptr_nonnull(ast);
179178
fclose(f);
180179

181180
struct string_list *called_args = calloc(1,sizeof(struct string_list));
@@ -204,24 +203,20 @@ END_TEST
204203
START_TEST (test_declaring_template) {
205204

206205
// setup
207-
struct policy_node *ast_if = calloc(1, sizeof(struct policy_node));
208-
ck_assert_ptr_nonnull(ast_if);
209-
ast_if->flavor = NODE_IF_FILE;
210206
set_current_module_name("declaring_template_if");
211207

212208
FILE *f_if = fopen(DECLARING_IF_FILENAME, "r");
213209
ck_assert_ptr_nonnull(f_if);
214-
ck_assert_int_eq(0, yyparse_wrapper(f_if, DECLARING_IF_FILENAME, &ast_if));
210+
struct policy_node *ast_if = yyparse_wrapper(f_if, DECLARING_IF_FILENAME, NODE_IF_FILE);
211+
ck_assert_ptr_nonnull(ast_if);
215212
fclose(f_if);
216213

217-
struct policy_node *ast_te = calloc(1, sizeof(struct policy_node));
218-
ck_assert_ptr_nonnull(ast_te);
219-
ast_te->flavor = NODE_IF_FILE;
220214
set_current_module_name("declaring_template_te");
221215

222216
FILE *f_te = fopen(DECLARING_TE_FILENAME, "r");
223217
ck_assert_ptr_nonnull(f_te);
224-
ck_assert_int_eq(0, yyparse_wrapper(f_te, DECLARING_TE_FILENAME, &ast_te));
218+
struct policy_node *ast_te = yyparse_wrapper(f_te, DECLARING_TE_FILENAME, NODE_TE_FILE);
219+
ck_assert_ptr_nonnull(ast_te);
225220
fclose(f_te);
226221

227222
// checks

0 commit comments

Comments
 (0)