Skip to content

Commit 4c24601

Browse files
cgzonesbachradsusi
authored andcommitted
checkpolicy: clear queue between parser passes
Clear the identifier queue after pass 1 to void unhandled identifiers from pass 1 leaking into pass 2 and leading to confusing error messages. For example for the following policy the error changes from 'no user name' to 'unknown role j': class C sid S class C { P } ; user U roles j; sid S s:l:q:q:q While on it call set_source_file() from init_parser(). Signed-off-by: Christian Göttsche <[email protected]>
1 parent fdb7090 commit 4c24601

File tree

5 files changed

+30
-15
lines changed

5 files changed

+30
-15
lines changed

checkpolicy/fuzz/checkpolicy-fuzzer.c

+3-7
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ extern unsigned int policydb_errors;
2525

2626
extern int yynerrs;
2727
extern FILE *yyin;
28-
extern void init_parser(int);
28+
extern void init_parser(int pass, const char *input_name);
2929
extern int yyparse(void);
3030
extern void yyrestart(FILE *);
3131
extern int yylex_destroy(void);
32-
extern void set_source_file(const char *name);
3332

3433
jmp_buf fuzzing_pre_parse_stack_state;
3534

@@ -87,8 +86,6 @@ static int read_source_policy(policydb_t *p, const uint8_t *data, size_t size)
8786

8887
rewind(yyin);
8988

90-
set_source_file("fuzz-input");
91-
9289
id_queue = queue_create();
9390
if (id_queue == NULL) {
9491
fclose(yyin);
@@ -99,7 +96,7 @@ static int read_source_policy(policydb_t *p, const uint8_t *data, size_t size)
9996
policydbp = p;
10097
mlspol = p->mls;
10198

102-
init_parser(1);
99+
init_parser(1, "fuzz-input-1");
103100

104101
if (setjmp(fuzzing_pre_parse_stack_state) != 0) {
105102
queue_destroy(id_queue);
@@ -119,8 +116,7 @@ static int read_source_policy(policydb_t *p, const uint8_t *data, size_t size)
119116
}
120117

121118
rewind(yyin);
122-
init_parser(2);
123-
set_source_file("fuzz-input");
119+
init_parser(2, "fuzz-input-2");
124120
yyrestart(yyin);
125121

126122
rc = yyparse();

checkpolicy/parse_util.c

+3-6
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@
2323

2424
/* these are defined in policy_parse.y and are needed for read_source_policy */
2525
extern FILE *yyin;
26-
extern void init_parser(int);
26+
extern void init_parser(int pass, const char *input_name);
2727
extern int yyparse(void);
2828
extern void yyrestart(FILE *);
2929
extern int yylex_destroy(void);
3030
extern queue_t id_queue;
3131
extern unsigned int policydb_errors;
3232
extern policydb_t *policydbp;
3333
extern int mlspol;
34-
extern void set_source_file(const char *name);
3534

3635
int read_source_policy(policydb_t * p, const char *file, const char *progname)
3736
{
@@ -42,7 +41,6 @@ int read_source_policy(policydb_t * p, const char *file, const char *progname)
4241
fprintf(stderr, "%s: unable to open %s: %s\n", progname, file, strerror(errno));
4342
return -1;
4443
}
45-
set_source_file(file);
4644

4745
id_queue = queue_create();
4846
if (id_queue == NULL) {
@@ -58,16 +56,15 @@ int read_source_policy(policydb_t * p, const char *file, const char *progname)
5856
goto cleanup;
5957
}
6058

61-
init_parser(1);
59+
init_parser(1, file);
6260
if (yyparse() || policydb_errors) {
6361
fprintf(stderr,
6462
"%s: error(s) encountered while parsing configuration\n",
6563
progname);
6664
goto cleanup;
6765
}
6866
rewind(yyin);
69-
init_parser(2);
70-
set_source_file(file);
67+
init_parser(2, file);
7168
yyrestart(yyin);
7269
if (yyparse() || policydb_errors) {
7370
fprintf(stderr,

checkpolicy/policy_define.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
#include "module_compiler.h"
5959
#include "policy_define.h"
6060

61-
extern void init_parser(int pass_number);
61+
extern void init_parser(int pass_number, const char *input_name);
6262
__attribute__ ((format(printf, 1, 2)))
6363
extern void yyerror2(const char *fmt, ...);
6464

@@ -71,17 +71,20 @@ extern unsigned long policydb_lineno;
7171
extern unsigned long source_lineno;
7272
extern unsigned int policydb_errors;
7373
extern char source_file[PATH_MAX];
74+
extern void set_source_file(const char *name);
7475

7576
extern int yywarn(const char *msg);
7677
extern int yyerror(const char *msg);
7778

7879
/* initialize all of the state variables for the scanner/parser */
79-
void init_parser(int pass_number)
80+
void init_parser(int pass_number, const char *input_name)
8081
{
8182
policydb_lineno = 1;
8283
source_lineno = 1;
8384
policydb_errors = 0;
8485
pass = pass_number;
86+
set_source_file(input_name);
87+
queue_clear(id_queue);
8588
}
8689

8790
void yyerror2(const char *fmt, ...)

checkpolicy/queue.c

+18
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ queue_element_t queue_head(queue_t q)
104104
return q->head->element;
105105
}
106106

107+
void queue_clear(queue_t q)
108+
{
109+
queue_node_ptr_t p, temp;
110+
111+
if (!q)
112+
return;
113+
114+
p = q->head;
115+
while (p != NULL) {
116+
free(p->element);
117+
temp = p;
118+
p = p->next;
119+
free(temp);
120+
}
121+
122+
q->head = q->tail = NULL;
123+
}
124+
107125
void queue_destroy(queue_t q)
108126
{
109127
queue_node_ptr_t p, temp;

checkpolicy/queue.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ int queue_insert(queue_t, queue_element_t);
3333
int queue_push(queue_t, queue_element_t);
3434
queue_element_t queue_remove(queue_t);
3535
queue_element_t queue_head(queue_t);
36+
void queue_clear(queue_t);
3637
void queue_destroy(queue_t);
3738

3839
/*

0 commit comments

Comments
 (0)