From: Florent Bruneau Date: Wed, 17 Sep 2008 10:18:04 +0000 (+0200) Subject: Check configuration for internal loops. X-Git-Url: http://git.madism.org/?p=apps%2Fpfixtools.git;a=commitdiff_plain;h=4e8709f2fc6338d2774c24c9c353deca1990f600 Check configuration for internal loops. Signed-off-by: Florent Bruneau --- diff --git a/postlicyd/config.c b/postlicyd/config.c index d964aaa..20716b2 100644 --- a/postlicyd/config.c +++ b/postlicyd/config.c @@ -111,6 +111,9 @@ static bool config_second_pass(config_t *config) if (!ok) { return false; } + if (!filter_check_safety(&config->filters)) { + return false; + } ok = false; foreach (filter_param_t *param, config->params) { diff --git a/postlicyd/filter.c b/postlicyd/filter.c index 4bab4c9..a067ef3 100644 --- a/postlicyd/filter.c +++ b/postlicyd/filter.c @@ -129,6 +129,42 @@ bool filter_update_references(filter_t *filter, A(filter_t) *filter_list) return true; } +static inline bool filter_check_loop(filter_t *filter, A(filter_t) *array, bool cleanup) +{ + if (cleanup) { + foreach (filter_t *filter2, *array) { + filter2->seen = false; + }} + } else if (filter->seen) { + return false; + } + if (filter->safe) { + return true; + } + filter->seen = true; + foreach (filter_hook_t *hook, filter->hooks) { + if (hook->postfix) { + continue; + } + if (!filter_check_loop(array_ptr(*array, hook->filter_id), array, false)) { + return false; + } + }} + filter->safe = true; + return true; +} + +bool filter_check_safety(A(filter_t) *array) +{ + foreach (filter_t *filter, *array) { + if (!filter_check_loop(filter, array, true)) { + syslog(LOG_ERR, "the filter tree contains a loop"); + return false; + } + }} + return true; +} + void filter_wipe(filter_t *filter) { filter_destructor_t destructor = destructors[filter->type]; diff --git a/postlicyd/filter.h b/postlicyd/filter.h index abfb5af..e8319d3 100644 --- a/postlicyd/filter.h +++ b/postlicyd/filter.h @@ -70,10 +70,15 @@ typedef struct filter_t { void *data; A(filter_param_t) params; + + /* Internal: to check the filter tree structure. + */ + unsigned safe :1; + unsigned seen :1; } filter_t; ARRAY(filter_t) -#define FILTER_INIT { NULL, FTK_UNKNOWN, ARRAY_INIT, NULL, ARRAY_INIT } +#define FILTER_INIT { NULL, FTK_UNKNOWN, ARRAY_INIT, NULL, ARRAY_INIT, false, false } #define CHECK_FILTER(Filter) \ assert(Filter != FTK_UNKNOWN && Filter != FTK_count \ && "Unknown filter type") @@ -147,6 +152,9 @@ static inline int filter_find_with_name(A(filter_t) *array, const char *name) __attribute__((nonnull(1,2))) bool filter_update_references(filter_t *filter, A(filter_t) *array); +__attribute__((nonnull(1))) +bool filter_check_safety(A(filter_t) *array); + __attribute__((nonnull(1))) static inline void filter_hook_wipe(filter_hook_t *hook) {