MXS-1301: function matches functionless queries in accept mode

A function type rule matches a query if the query uses a function defined
in the rule. This is the desired behavior for blacklist mode operation
with `action=block`.

When in whitelist mode, all queries must match a rule to be allowed
through. For function type rules, this fact is problematic as queries that
don't use functions are blocked. The desired behavior is to allow the use
of certain functions while preventing the use of others.

The allowed set of functions should always contain the "empty set" (no
functions are used) when the filter is in whitelist mode.
This commit is contained in:
Markus Mäkelä 2017-06-28 21:00:08 +03:00
parent 902013e4f8
commit 674b3887c9
3 changed files with 18 additions and 2 deletions

View File

@ -165,6 +165,10 @@ matched. The symbolic comparison operators (`<`, `>`, `>=` etc.) are also
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
not considered functions.
When the filter is in whitelist mode (`action=allow`) the function rule
will match any query that does not use a function. This means that queries
that do not use functions will be allowed through a function type rule.
##### Example
Deny SUM and COUNT functions:

View File

@ -54,6 +54,12 @@ The `match` and `exclude` parameters were changed to use PCRE2 syntax for the
regular expressions. The regular expression should be enclosed by slashes
e.g. `match=/select.*from.*test/`.
### Dbfwfilter
The `function` type rule will now match a query that does not use a function
when the filter is in whitelist mode (`action=allow`). This means that queries
that don't use functions are allowed though in whitelist mode.
## Dropped Features
### MaxAdmin

View File

@ -2082,12 +2082,18 @@ void match_column(RULE_BOOK *rulebook, GWBUF *queue, bool *matches, char **msg)
}
}
void match_function(RULE_BOOK *rulebook, GWBUF *queue, bool *matches, char **msg)
void match_function(RULE_BOOK *rulebook, GWBUF *queue, enum fw_actions mode,
bool *matches, char **msg)
{
const QC_FUNCTION_INFO* infos;
size_t n_infos;
qc_get_function_info(queue, &infos, &n_infos);
if (n_infos == 0 && mode == FW_ACTION_ALLOW)
{
*matches = true;
}
for (size_t i = 0; i < n_infos; ++i)
{
const char* tok = infos[i].name;
@ -2219,7 +2225,7 @@ bool rule_matches(FW_INSTANCE* my_instance,
case RT_FUNCTION:
if (is_sql)
{
match_function(rulebook, queue, &matches, &msg);
match_function(rulebook, queue, my_instance->action, &matches, &msg);
}
break;