mirror of
https://github.com/topjohnwu/selinux.git
synced 2025-01-26 05:16:19 +00:00
libsepol/cil: Add cil_tree_log() and supporting functions
Provide more detailed log messages containing all relevant CIL and high-level language source file information through cil_tree_log(). cil_tree_log() uses two new functions: cil_tree_get_next_path() and cil_tree_get_cil_path(). cil_tree_get_next_path() traverses up the parse tree or AST until it finds the next CIL or high-level language source information nodes. It will return the path and whether or not the path is for a CIL file. cil_tree_get_cil_path() uses cil_tree_get_next_path() to return the CIL path. Example cil_tree_log() message: Problem at policy.cil:21 from foo.hll:11 from bar.hll:2 Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
This commit is contained in:
parent
681341f2f4
commit
73aac8fc1e
@ -59,6 +59,92 @@ __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_e
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil)
|
||||
{
|
||||
if (!node) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = node->parent;
|
||||
|
||||
while (node) {
|
||||
if (node->flavor == CIL_NODE && node->data == NULL) {
|
||||
if (node->cl_head->data == CIL_KEY_SRC_INFO) {
|
||||
/* Parse Tree */
|
||||
*path = node->cl_head->next->next->data;
|
||||
*is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL);
|
||||
return node;
|
||||
}
|
||||
node = node->parent;
|
||||
} else if (node->flavor == CIL_SRC_INFO) {
|
||||
/* AST */
|
||||
struct cil_src_info *info = node->data;
|
||||
*path = info->path;
|
||||
*is_cil = info->is_cil;
|
||||
return node;
|
||||
} else {
|
||||
if (node->flavor == CIL_CALL) {
|
||||
struct cil_call *call = node->data;
|
||||
node = NODE(call->macro);
|
||||
} else if (node->flavor == CIL_BLOCKINHERIT) {
|
||||
struct cil_blockinherit *inherit = node->data;
|
||||
node = NODE(inherit->block);
|
||||
} else {
|
||||
node = node->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *cil_tree_get_cil_path(struct cil_tree_node *node)
|
||||
{
|
||||
char *path = NULL;
|
||||
int is_cil;
|
||||
|
||||
while (node) {
|
||||
node = cil_tree_get_next_path(node, &path, &is_cil);
|
||||
if (node && is_cil) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
cil_vlog(lvl, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (node) {
|
||||
char *path = NULL;
|
||||
int is_cil;
|
||||
unsigned hll_line = node->hll_line;
|
||||
|
||||
path = cil_tree_get_cil_path(node);
|
||||
|
||||
if (path != NULL) {
|
||||
cil_log(lvl, " at %s:%d", path, node->line);
|
||||
}
|
||||
|
||||
while (node) {
|
||||
node = cil_tree_get_next_path(node, &path, &is_cil);
|
||||
if (node && !is_cil) {
|
||||
cil_log(lvl," from %s:%d", path, hll_line);
|
||||
path = NULL;
|
||||
hll_line = node->hll_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cil_log(lvl,"\n");
|
||||
}
|
||||
|
||||
int cil_tree_init(struct cil_tree **tree)
|
||||
{
|
||||
struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree));
|
||||
|
@ -51,6 +51,10 @@ struct cil_tree_node {
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil);
|
||||
char *cil_tree_get_cil_path(struct cil_tree_node *node);
|
||||
__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...);
|
||||
|
||||
int cil_tree_init(struct cil_tree **tree);
|
||||
void cil_tree_destroy(struct cil_tree **tree);
|
||||
void cil_tree_subtree_destroy(struct cil_tree_node *node);
|
||||
|
Loading…
x
Reference in New Issue
Block a user