mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-02 07:15:18 +00:00
dfa patches for the parser
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
/* #define DEBUG */
|
||||
|
||||
#include "parser.h"
|
||||
#include "libapparmor_re/apparmor_re.h"
|
||||
|
||||
enum error_type {
|
||||
e_no_error,
|
||||
@@ -113,10 +114,11 @@ static void filter_slashes(char *path)
|
||||
}
|
||||
}
|
||||
|
||||
static int process_regex_entry(struct cod_entry *entry)
|
||||
static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
||||
char *pcre, size_t pcre_size)
|
||||
{
|
||||
#define STORE(_src, _dest, _len) \
|
||||
if ((const char*)_dest + _len > tbufend){ \
|
||||
if ((const char*)_dest + _len > (pcre + pcre_size)){ \
|
||||
error = e_buffer_overflow; \
|
||||
} else { \
|
||||
memcpy(_dest, _src, _len); \
|
||||
@@ -128,9 +130,6 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
/* flag to indicate input error */
|
||||
enum error_type error;
|
||||
|
||||
char tbuf[PATH_MAX + 3]; /* +3 for ^, $ and \0 */
|
||||
const char *tbufend = &tbuf[PATH_MAX];
|
||||
|
||||
const char *sptr;
|
||||
char *dptr;
|
||||
pattern_t ptype;
|
||||
@@ -142,14 +141,12 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
error = e_no_error;
|
||||
ptype = ePatternBasic; /* assume no regex */
|
||||
|
||||
if (!entry) /* shouldn't happen */
|
||||
return TRUE;
|
||||
sptr = aare;
|
||||
dptr = pcre;
|
||||
|
||||
sptr = entry->name;
|
||||
dptr = tbuf;
|
||||
|
||||
/* anchor beginning of regular expression */
|
||||
*dptr++ = '^';
|
||||
if (anchor)
|
||||
/* anchor beginning of regular expression */
|
||||
*dptr++ = '^';
|
||||
|
||||
while (error == e_no_error && *sptr) {
|
||||
switch (*sptr) {
|
||||
@@ -170,6 +167,7 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
++sptr;
|
||||
continue; /*skip turning bEscape off */
|
||||
} /* bEscape */
|
||||
break;
|
||||
case '*':
|
||||
if (bEscape) {
|
||||
/* '*' is a PCRE special character */
|
||||
@@ -341,10 +339,10 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
}
|
||||
|
||||
/* anchor end and terminate pattern string */
|
||||
if (error == e_no_error && anchor)
|
||||
STORE("$" , dptr, 1);
|
||||
if (error == e_no_error) {
|
||||
char buf[2] = { '$', 0 };
|
||||
|
||||
STORE(buf, dptr, 2);
|
||||
STORE("", dptr, 1);
|
||||
}
|
||||
|
||||
/* check error again, as above STORE may have set it */
|
||||
@@ -355,12 +353,31 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
}
|
||||
|
||||
PERROR(_("%s: Unable to parse input line '%s'\n"),
|
||||
progname, entry->name);
|
||||
progname, aare);
|
||||
|
||||
ret = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret == FALSE)
|
||||
ptype = ePatternInvalid;
|
||||
return ptype;
|
||||
}
|
||||
|
||||
static int process_pcre_entry(struct cod_entry *entry)
|
||||
{
|
||||
char tbuf[PATH_MAX + 3]; /* +3 for ^, $ and \0 */
|
||||
int ret = TRUE;
|
||||
pattern_t ptype;
|
||||
|
||||
if (!entry) /* shouldn't happen */
|
||||
return TRUE;
|
||||
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 1, tbuf, PATH_MAX + 3);
|
||||
if (ptype == ePatternInvalid)
|
||||
return FALSE;
|
||||
|
||||
entry->pattern_type = ptype;
|
||||
|
||||
/*
|
||||
@@ -421,33 +438,89 @@ static int process_regex_entry(struct cod_entry *entry)
|
||||
filter_escapes(entry->name);
|
||||
} /* ptype == ePatternRegex */
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int post_process_entries(struct cod_entry *entry_list)
|
||||
static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
||||
{
|
||||
char tbuf[PATH_MAX + 3]; /* +3 for ^, $ and \0 */
|
||||
int ret = TRUE;
|
||||
pattern_t ptype;
|
||||
|
||||
if (!entry) /* shouldn't happen */
|
||||
return TRUE;
|
||||
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 0, tbuf, PATH_MAX + 3);
|
||||
if (ptype == ePatternInvalid)
|
||||
return FALSE;
|
||||
|
||||
entry->pattern_type = ptype;
|
||||
|
||||
/* ix implies m but the apparmor module does not add m bit to
|
||||
* dfa states like it does for pcre
|
||||
*/
|
||||
if (entry->mode & KERN_COD_EXEC_INHERIT)
|
||||
entry->mode |= KERN_COD_EXEC_MMAP;
|
||||
if (!aare_add_rule(dfarules, tbuf, entry->mode))
|
||||
ret = FALSE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int post_process_entries(struct codomain *cod)
|
||||
{
|
||||
int ret = TRUE, rc;
|
||||
struct cod_entry *entry;
|
||||
int count = 0;
|
||||
|
||||
for (entry = entry_list; entry; entry = entry->next) {
|
||||
for (entry = cod->entries; entry; entry = entry->next) {
|
||||
filter_slashes(entry->name);
|
||||
rc = process_regex_entry(entry);
|
||||
if (regex_type == AARE_DFA)
|
||||
rc = process_dfa_entry(cod->dfarules, entry);
|
||||
else
|
||||
rc = process_pcre_entry(entry);
|
||||
if (!rc)
|
||||
ret = FALSE;
|
||||
count++;
|
||||
}
|
||||
|
||||
code->dfarule_count = count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int process_regex(struct codomain *cod)
|
||||
{
|
||||
int error = 0;
|
||||
int error = -1;
|
||||
|
||||
if (!post_process_entries(cod->entries)) {
|
||||
error = -1;
|
||||
if (regex_type == AARE_DFA) {
|
||||
cod->dfarules = aare_new_ruleset(0);
|
||||
if (!cod->dfarules)
|
||||
goto out;
|
||||
}
|
||||
if (!post_process_entries(cod))
|
||||
{
|
||||
fprintf(stderr, "Failed post_process_entries\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (regex_type == AARE_DFA && cod->dfarule_count > 0) {
|
||||
cod->dfa = aare_create_dfa(cod->dfarules, 0, &cod->dfa_size);
|
||||
if (!cod->dfa)
|
||||
{
|
||||
fprintf(stderr, "Failed create dfa\n");
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
if (cod->dfa_size == 0) {
|
||||
PERROR(_("profile %s: has merged rules (%s) with "
|
||||
"multiple x modifiers\n"),
|
||||
cod->name, (char *) cod->dfa);
|
||||
free(cod->dfa);
|
||||
cod->dfa = NULL;
|
||||
goto out;
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* Post process subdomain(s):
|
||||
*
|
||||
@@ -463,8 +536,11 @@ int process_regex(struct codomain *cod)
|
||||
* }
|
||||
*/
|
||||
if (process_hat_regex(cod) != 0)
|
||||
error = -1;
|
||||
goto out;
|
||||
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user