Skip to content

Commit

Permalink
checkpolicy: clear queue between parser passes
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
cgzones authored and bachradsusi committed Jan 15, 2025
1 parent fdb7090 commit 4c24601
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 15 deletions.
10 changes: 3 additions & 7 deletions checkpolicy/fuzz/checkpolicy-fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ extern unsigned int policydb_errors;

extern int yynerrs;
extern FILE *yyin;
extern void init_parser(int);
extern void init_parser(int pass, const char *input_name);
extern int yyparse(void);
extern void yyrestart(FILE *);
extern int yylex_destroy(void);
extern void set_source_file(const char *name);

jmp_buf fuzzing_pre_parse_stack_state;

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

rewind(yyin);

set_source_file("fuzz-input");

id_queue = queue_create();
if (id_queue == NULL) {
fclose(yyin);
Expand All @@ -99,7 +96,7 @@ static int read_source_policy(policydb_t *p, const uint8_t *data, size_t size)
policydbp = p;
mlspol = p->mls;

init_parser(1);
init_parser(1, "fuzz-input-1");

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

rewind(yyin);
init_parser(2);
set_source_file("fuzz-input");
init_parser(2, "fuzz-input-2");
yyrestart(yyin);

rc = yyparse();
Expand Down
9 changes: 3 additions & 6 deletions checkpolicy/parse_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@

/* these are defined in policy_parse.y and are needed for read_source_policy */
extern FILE *yyin;
extern void init_parser(int);
extern void init_parser(int pass, const char *input_name);
extern int yyparse(void);
extern void yyrestart(FILE *);
extern int yylex_destroy(void);
extern queue_t id_queue;
extern unsigned int policydb_errors;
extern policydb_t *policydbp;
extern int mlspol;
extern void set_source_file(const char *name);

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

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

init_parser(1);
init_parser(1, file);
if (yyparse() || policydb_errors) {
fprintf(stderr,
"%s: error(s) encountered while parsing configuration\n",
progname);
goto cleanup;
}
rewind(yyin);
init_parser(2);
set_source_file(file);
init_parser(2, file);
yyrestart(yyin);
if (yyparse() || policydb_errors) {
fprintf(stderr,
Expand Down
7 changes: 5 additions & 2 deletions checkpolicy/policy_define.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
#include "module_compiler.h"
#include "policy_define.h"

extern void init_parser(int pass_number);
extern void init_parser(int pass_number, const char *input_name);
__attribute__ ((format(printf, 1, 2)))
extern void yyerror2(const char *fmt, ...);

Expand All @@ -71,17 +71,20 @@ extern unsigned long policydb_lineno;
extern unsigned long source_lineno;
extern unsigned int policydb_errors;
extern char source_file[PATH_MAX];
extern void set_source_file(const char *name);

extern int yywarn(const char *msg);
extern int yyerror(const char *msg);

/* initialize all of the state variables for the scanner/parser */
void init_parser(int pass_number)
void init_parser(int pass_number, const char *input_name)
{
policydb_lineno = 1;
source_lineno = 1;
policydb_errors = 0;
pass = pass_number;
set_source_file(input_name);
queue_clear(id_queue);
}

void yyerror2(const char *fmt, ...)
Expand Down
18 changes: 18 additions & 0 deletions checkpolicy/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,24 @@ queue_element_t queue_head(queue_t q)
return q->head->element;
}

void queue_clear(queue_t q)
{
queue_node_ptr_t p, temp;

if (!q)
return;

p = q->head;
while (p != NULL) {
free(p->element);
temp = p;
p = p->next;
free(temp);
}

q->head = q->tail = NULL;
}

void queue_destroy(queue_t q)
{
queue_node_ptr_t p, temp;
Expand Down
1 change: 1 addition & 0 deletions checkpolicy/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ int queue_insert(queue_t, queue_element_t);
int queue_push(queue_t, queue_element_t);
queue_element_t queue_remove(queue_t);
queue_element_t queue_head(queue_t);
void queue_clear(queue_t);
void queue_destroy(queue_t);

/*
Expand Down

0 comments on commit 4c24601

Please sign in to comment.