mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
parser: remove length restriction in convert_aaregex_to_pcre usage
This patch removes the string length limit in convert_aaregex_to_pcre() usage. One of the benefits to moving to C++ is the ability to use std::strings, which dynamically resize themselves. While it's a large patch, a non-trivial amount is due to needing to get a char * string back out via the c_str() method. The unit tests are modified to include checks to ensure that convert_aaregex_to_pcre only appends to the passed pcre string, it never resets it. As the test case with overlong alternations added in the previous patch now passes, the TODO status is removed from it. (Note: there's a couple of FIXME comments related to converting typebuf to std::string that are added by this patch that are addressed in the next patch. I kept that conversion separate to try to reduce the size of this patch a little.) Signed-off-by: Steve Beattie <steve@nxnw.org> Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
parent
62c13f66b0
commit
cc1a6f0e55
2 changed files with 173 additions and 189 deletions
|
@ -24,6 +24,8 @@
|
|||
#include <apparmor.h>
|
||||
#define _(s) gettext(s)
|
||||
|
||||
#include <string>
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#include "parser.h"
|
||||
|
@ -81,17 +83,11 @@ static void filter_slashes(char *path)
|
|||
*dptr = 0;
|
||||
}
|
||||
|
||||
/* converts the apparmor regex in aare and appends pcre regex output
|
||||
* to pcre string */
|
||||
static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
||||
char *pcre, size_t pcre_size,
|
||||
int *first_re_pos)
|
||||
std::string& pcre, int *first_re_pos)
|
||||
{
|
||||
#define STORE(_src, _dest, _len) \
|
||||
if ((const char*)_dest + _len > (pcre + pcre_size)){ \
|
||||
error = e_buffer_overflow; \
|
||||
} else { \
|
||||
memcpy(_dest, _src, _len); \
|
||||
_dest += _len; \
|
||||
}
|
||||
#define update_re_pos(X) if (!(*first_re_pos)) { *first_re_pos = (X); }
|
||||
#define MAX_ALT_DEPTH 50
|
||||
*first_re_pos = 0;
|
||||
|
@ -101,7 +97,6 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
enum error_type error;
|
||||
|
||||
const char *sptr;
|
||||
char *dptr;
|
||||
pattern_t ptype;
|
||||
|
||||
BOOL bEscape = 0; /* flag to indicate escape */
|
||||
|
@ -113,14 +108,13 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
ptype = ePatternBasic; /* assume no regex */
|
||||
|
||||
sptr = aare;
|
||||
dptr = pcre;
|
||||
|
||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
||||
fprintf(stderr, "aare: %s -> ", aare);
|
||||
|
||||
if (anchor)
|
||||
/* anchor beginning of regular expression */
|
||||
*dptr++ = '^';
|
||||
pcre.append("^");
|
||||
|
||||
while (error == e_no_error && *sptr) {
|
||||
switch (*sptr) {
|
||||
|
@ -135,7 +129,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
* this is done by stripping later
|
||||
*/
|
||||
if (bEscape) {
|
||||
STORE("\\\\", dptr, 2);
|
||||
pcre.append("\\\\");
|
||||
} else {
|
||||
bEscape = TRUE;
|
||||
++sptr;
|
||||
|
@ -149,9 +143,9 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
* end up using this regex buffer (i.e another
|
||||
* non-escaped regex follows)
|
||||
*/
|
||||
STORE("\\*", dptr, 2);
|
||||
pcre.append("\\*");
|
||||
} else {
|
||||
if ((dptr > pcre) && *(dptr - 1) == '/') {
|
||||
if ((pcre.length() > 0) && pcre[pcre.length() - 1] == '/') {
|
||||
#if 0
|
||||
// handle comment containing use
|
||||
// of C comment characters
|
||||
|
@ -177,7 +171,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
while (*s == '*')
|
||||
s++;
|
||||
if (*s == '/' || !*s) {
|
||||
STORE("[^/\\x00]", dptr, 8);
|
||||
pcre.append("[^/\\x00]");
|
||||
}
|
||||
}
|
||||
if (*(sptr + 1) == '*') {
|
||||
|
@ -195,12 +189,12 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
ptype = ePatternRegex;
|
||||
}
|
||||
|
||||
STORE("[^\\x00]*", dptr, 8);
|
||||
pcre.append("[^\\x00]*");
|
||||
sptr++;
|
||||
} else {
|
||||
update_re_pos(sptr - aare);
|
||||
ptype = ePatternRegex;
|
||||
STORE("[^/\\x00]*", dptr, 9);
|
||||
pcre.append("[^/\\x00]*");
|
||||
} /* *(sptr+1) == '*' */
|
||||
} /* bEscape */
|
||||
|
||||
|
@ -212,48 +206,48 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
* so no need to escape, just skip
|
||||
* transform
|
||||
*/
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
} else {
|
||||
update_re_pos(sptr - aare);
|
||||
ptype = ePatternRegex;
|
||||
STORE("[^/\\x00]", dptr, 8);
|
||||
pcre.append("[^/\\x00]");
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
if (bEscape) {
|
||||
/* [ is a PCRE special character */
|
||||
STORE("\\[", dptr, 2);
|
||||
pcre.append("\\[");
|
||||
} else {
|
||||
update_re_pos(sptr - aare);
|
||||
incharclass = 1;
|
||||
ptype = ePatternRegex;
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case ']':
|
||||
if (bEscape) {
|
||||
/* ] is a PCRE special character */
|
||||
STORE("\\]", dptr, 2);
|
||||
pcre.append("\\]");
|
||||
} else {
|
||||
if (incharclass == 0) {
|
||||
error = e_parse_error;
|
||||
PERROR(_("%s: Regex grouping error: Invalid close ], no matching open [ detected\n"), progname);
|
||||
}
|
||||
incharclass = 0;
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case '{':
|
||||
if (bEscape) {
|
||||
/* { is a PCRE special character */
|
||||
STORE("\\{", dptr, 2);
|
||||
pcre.append("\\{");
|
||||
} else {
|
||||
if (incharclass) {
|
||||
/* don't expand inside [] */
|
||||
STORE("{", dptr, 1);
|
||||
pcre.append("{");
|
||||
} else {
|
||||
update_re_pos(sptr - aare);
|
||||
ingrouping++;
|
||||
|
@ -264,7 +258,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
} else {
|
||||
grouping_count[ingrouping] = 0;
|
||||
ptype = ePatternRegex;
|
||||
STORE("(", dptr, 1);
|
||||
pcre.append("(");
|
||||
}
|
||||
} /* incharclass */
|
||||
}
|
||||
|
@ -273,11 +267,11 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
case '}':
|
||||
if (bEscape) {
|
||||
/* { is a PCRE special character */
|
||||
STORE("\\}", dptr, 2);
|
||||
pcre.append("\\}");
|
||||
} else {
|
||||
if (incharclass) {
|
||||
/* don't expand inside [] */
|
||||
STORE("}", dptr, 1);
|
||||
pcre.append("}");
|
||||
} else {
|
||||
if (grouping_count[ingrouping] == 0) {
|
||||
error = e_parse_error;
|
||||
|
@ -290,7 +284,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
PERROR(_("%s: Regex grouping error: Invalid close }, no matching open { detected\n"), progname);
|
||||
ingrouping = 0;
|
||||
}
|
||||
STORE(")", dptr, 1);
|
||||
pcre.append(")");
|
||||
} /* incharclass */
|
||||
} /* bEscape */
|
||||
|
||||
|
@ -302,20 +296,20 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
/* escape inside char class is a
|
||||
* valid matching char for '\'
|
||||
*/
|
||||
STORE("\\,", dptr, 2);
|
||||
pcre.append("\\,");
|
||||
} else {
|
||||
/* ',' is not a PCRE regex character
|
||||
* so no need to escape, just skip
|
||||
* transform
|
||||
*/
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
}
|
||||
} else {
|
||||
if (ingrouping && !incharclass) {
|
||||
grouping_count[ingrouping]++;
|
||||
STORE("|", dptr, 1);
|
||||
pcre.append("|");
|
||||
} else {
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -325,10 +319,10 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
case '^':
|
||||
case '$':
|
||||
if (incharclass) {
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
} else {
|
||||
STORE("\\", dptr, 1);
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append("\\");
|
||||
pcre.append(1, *sptr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -343,7 +337,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
case '|':
|
||||
case '(':
|
||||
case ')':
|
||||
STORE("\\", dptr, 1);
|
||||
pcre.append("\\");
|
||||
// fall through to default
|
||||
|
||||
default:
|
||||
|
@ -353,7 +347,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
pwarn("Character %c was quoted unnecessarily, "
|
||||
"dropped preceding quote ('\\') character\n", *sptr);
|
||||
}
|
||||
STORE(sptr, dptr, 1);
|
||||
pcre.append(1, *sptr);
|
||||
break;
|
||||
} /* switch (*sptr) */
|
||||
|
||||
|
@ -376,10 +370,7 @@ static pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
|
|||
}
|
||||
/* anchor end and terminate pattern string */
|
||||
if ((error == e_no_error) && anchor) {
|
||||
STORE("$" , dptr, 1);
|
||||
}
|
||||
if (error == e_no_error) {
|
||||
STORE("", dptr, 1);
|
||||
pcre.append("$");
|
||||
}
|
||||
/* check error again, as above STORE may have set it */
|
||||
if (error != e_no_error) {
|
||||
|
@ -400,7 +391,7 @@ out:
|
|||
ptype = ePatternInvalid;
|
||||
|
||||
if (dfaflags & DFA_DUMP_RULE_EXPR)
|
||||
fprintf(stderr, "%s\n", pcre);
|
||||
fprintf(stderr, "%s\n", pcre.c_str());
|
||||
|
||||
return ptype;
|
||||
}
|
||||
|
@ -417,7 +408,7 @@ static const char *local_name(const char *name)
|
|||
|
||||
static int process_profile_name_xmatch(Profile *prof)
|
||||
{
|
||||
char tbuf[PATH_MAX + 3]; /* +3 for ^, $ and \0 */
|
||||
std::string tbuf;
|
||||
pattern_t ptype;
|
||||
const char *name;
|
||||
|
||||
|
@ -426,7 +417,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||
name = prof->attachment;
|
||||
else
|
||||
name = local_name(prof->name);
|
||||
ptype = convert_aaregex_to_pcre(name, 0, tbuf, PATH_MAX + 3,
|
||||
ptype = convert_aaregex_to_pcre(name, 0, tbuf,
|
||||
&prof->xmatch_len);
|
||||
if (ptype == ePatternBasic)
|
||||
prof->xmatch_len = strlen(name);
|
||||
|
@ -444,7 +435,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||
aare_ruleset_t *rule = aare_new_ruleset(0);
|
||||
if (!rule)
|
||||
return FALSE;
|
||||
if (!aare_add_rule(rule, tbuf, 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
if (!aare_add_rule(rule, tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
aare_delete_ruleset(rule);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -452,15 +443,15 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||
struct alt_name *alt;
|
||||
list_for_each(prof->altnames, alt) {
|
||||
int len;
|
||||
tbuf.clear();
|
||||
ptype = convert_aaregex_to_pcre(alt->name, 0,
|
||||
tbuf,
|
||||
PATH_MAX + 3,
|
||||
&len);
|
||||
if (ptype == ePatternBasic)
|
||||
len = strlen(alt->name);
|
||||
if (len < prof->xmatch_len)
|
||||
prof->xmatch_len = len;
|
||||
if (!aare_add_rule(rule, tbuf, 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
if (!aare_add_rule(rule, tbuf.c_str(), 0, AA_MAY_EXEC, 0, dfaflags)) {
|
||||
aare_delete_ruleset(rule);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -478,7 +469,7 @@ static int process_profile_name_xmatch(Profile *prof)
|
|||
|
||||
static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
||||
{
|
||||
char tbuf[PATH_MAX + 3]; /* +3 for ^, $ and \0 */
|
||||
std::string tbuf;
|
||||
pattern_t ptype;
|
||||
int pos;
|
||||
|
||||
|
@ -488,7 +479,7 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
|||
|
||||
if (entry->mode & ~AA_CHANGE_PROFILE)
|
||||
filter_slashes(entry->name);
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 0, tbuf, PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 0, tbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
return FALSE;
|
||||
|
||||
|
@ -510,30 +501,30 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
|||
* entry of the pair
|
||||
*/
|
||||
if (entry->deny && (entry->mode & AA_LINK_BITS)) {
|
||||
if (!aare_add_rule(dfarules, tbuf, entry->deny,
|
||||
if (!aare_add_rule(dfarules, tbuf.c_str(), entry->deny,
|
||||
entry->mode & ~AA_LINK_BITS,
|
||||
entry->audit & ~AA_LINK_BITS, dfaflags))
|
||||
return FALSE;
|
||||
} else if (entry->mode & ~AA_CHANGE_PROFILE) {
|
||||
if (!aare_add_rule(dfarules, tbuf, entry->deny, entry->mode,
|
||||
if (!aare_add_rule(dfarules, tbuf.c_str(), entry->deny, entry->mode,
|
||||
entry->audit, dfaflags))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (entry->mode & (AA_LINK_BITS)) {
|
||||
/* add the pair rule */
|
||||
char lbuf[PATH_MAX + 8];
|
||||
std::string lbuf;
|
||||
int perms = AA_LINK_BITS & entry->mode;
|
||||
const char *vec[2];
|
||||
int pos;
|
||||
vec[0] = tbuf;
|
||||
vec[0] = tbuf.c_str();
|
||||
if (entry->link_name) {
|
||||
ptype = convert_aaregex_to_pcre(entry->link_name, 0, lbuf, PATH_MAX + 8, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->link_name, 0, lbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
return FALSE;
|
||||
if (entry->subset)
|
||||
perms |= LINK_TO_LINK_SUBSET(perms);
|
||||
vec[1] = lbuf;
|
||||
vec[1] = lbuf.c_str();
|
||||
} else {
|
||||
perms |= LINK_TO_LINK_SUBSET(perms);
|
||||
vec[1] = "/[^/].*";
|
||||
|
@ -543,7 +534,7 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
|||
}
|
||||
if (entry->mode & AA_CHANGE_PROFILE) {
|
||||
const char *vec[3];
|
||||
char lbuf[PATH_MAX + 8];
|
||||
std::string lbuf;
|
||||
int index = 1;
|
||||
|
||||
/* allow change_profile for all execs */
|
||||
|
@ -551,10 +542,10 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
|
|||
|
||||
if (entry->ns) {
|
||||
int pos;
|
||||
ptype = convert_aaregex_to_pcre(entry->ns, 0, lbuf, PATH_MAX + 8, &pos);
|
||||
vec[index++] = lbuf;
|
||||
ptype = convert_aaregex_to_pcre(entry->ns, 0, lbuf, &pos);
|
||||
vec[index++] = lbuf.c_str();
|
||||
}
|
||||
vec[index++] = tbuf;
|
||||
vec[index++] = tbuf.c_str();
|
||||
|
||||
/* regular change_profile rule */
|
||||
if (!aare_add_rule_vec(dfarules, 0, AA_CHANGE_PROFILE | AA_ONEXEC, 0, index - 1, &vec[1], dfaflags))
|
||||
|
@ -639,7 +630,7 @@ out:
|
|||
static int build_list_val_expr(char *buffer, int size, struct value_list *list)
|
||||
{
|
||||
struct value_list *ent;
|
||||
char tmp[PATH_MAX + 3];
|
||||
std::string tmp;
|
||||
char *p;
|
||||
int len;
|
||||
pattern_t ptype;
|
||||
|
@ -656,28 +647,28 @@ static int build_list_val_expr(char *buffer, int size, struct value_list *list)
|
|||
if (p > buffer + size)
|
||||
goto fail;
|
||||
|
||||
ptype = convert_aaregex_to_pcre(list->value, 0, tmp, PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(list->value, 0, tmp, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
|
||||
len = strlen(tmp);
|
||||
len = tmp.length();
|
||||
if (len > size - (p - buffer))
|
||||
goto fail;
|
||||
strcpy(p, tmp);
|
||||
strcpy(p, tmp.c_str());
|
||||
p += len;
|
||||
|
||||
list_for_each(list->next, ent) {
|
||||
ptype = convert_aaregex_to_pcre(ent->value, 0, tmp,
|
||||
PATH_MAX+3, &pos);
|
||||
tmp.clear();
|
||||
ptype = convert_aaregex_to_pcre(ent->value, 0, tmp, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
|
||||
strncpy(p, "|", size - (p - buffer));
|
||||
p++;
|
||||
len = strlen(tmp);
|
||||
len = tmp.length();
|
||||
if (len > size - (p - buffer))
|
||||
goto fail;
|
||||
strcpy(p, tmp);
|
||||
strcpy(p, tmp.c_str());
|
||||
p += len;
|
||||
}
|
||||
strncpy(p, ")", size - (p - buffer));
|
||||
|
@ -690,22 +681,19 @@ fail:
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static int convert_entry(char *buffer, int size, char *entry)
|
||||
static int convert_entry(std::string& buffer, char *entry)
|
||||
{
|
||||
pattern_t ptype;
|
||||
int pos;
|
||||
|
||||
if (entry) {
|
||||
ptype = convert_aaregex_to_pcre(entry, 0, buffer, size, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry, 0, buffer, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
return FALSE;
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
if (size < 8)
|
||||
return FALSE;
|
||||
|
||||
strcpy(buffer, "[^\\000]*");
|
||||
buffer.append("[^\\000]*");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -750,38 +738,24 @@ static int build_mnt_flags(char *buffer, int size, unsigned int flags,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static int build_mnt_opts(char *buffer, int size, struct value_list *opts)
|
||||
static int build_mnt_opts(std::string& buffer, struct value_list *opts)
|
||||
{
|
||||
struct value_list *ent;
|
||||
char tmp[PATH_MAX + 3];
|
||||
char *p;
|
||||
int len;
|
||||
pattern_t ptype;
|
||||
int pos;
|
||||
|
||||
if (!opts) {
|
||||
if (size < 8)
|
||||
return FALSE;
|
||||
strncpy(buffer, "[^\\000]*", size);
|
||||
buffer.append("[^\\000]*");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
p = buffer;
|
||||
list_for_each(opts, ent) {
|
||||
ptype = convert_aaregex_to_pcre(ent->value, 0, tmp,
|
||||
PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(ent->value, 0, buffer, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
|
||||
len = strlen(tmp);
|
||||
if (len > size - (p - buffer))
|
||||
goto fail;
|
||||
strcpy(p, tmp);
|
||||
p += len;
|
||||
if (ent->next && size - (p - buffer) > 1) {
|
||||
*p++ = ',';
|
||||
*p = 0;
|
||||
}
|
||||
if (ent->next)
|
||||
buffer.append(",");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -792,16 +766,18 @@ fail:
|
|||
|
||||
static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
||||
{
|
||||
char mntbuf[PATH_MAX + 3];
|
||||
char devbuf[PATH_MAX + 3];
|
||||
std::string mntbuf;
|
||||
std::string devbuf;
|
||||
char typebuf[PATH_MAX + 3];
|
||||
char flagsbuf[PATH_MAX + 3];
|
||||
char optsbuf[PATH_MAX + 3];
|
||||
char *p;
|
||||
std::string optsbuf;
|
||||
char class_mount_hdr[64];
|
||||
const char *vec[5];
|
||||
int count = 0;
|
||||
unsigned int flags, inv_flags;
|
||||
|
||||
sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT);
|
||||
|
||||
/* a single mount rule may result in multiple matching rules being
|
||||
* created in the backend to cover all the possible choices
|
||||
*/
|
||||
|
@ -810,25 +786,25 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
&& !entry->device && !entry->dev_type) {
|
||||
int allow;
|
||||
/* remount can't be conditional on device and type */
|
||||
p = mntbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (entry->mnt_point) {
|
||||
/* both device && mnt_point or just mnt_point */
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
vec[0] = mntbuf.c_str();
|
||||
} else {
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->device))
|
||||
if (!convert_entry(mntbuf, entry->device))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
vec[0] = mntbuf.c_str();
|
||||
}
|
||||
/* skip device */
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, NULL))
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, NULL))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
vec[1] = devbuf.c_str();
|
||||
/* skip type */
|
||||
vec[2] = devbuf;
|
||||
vec[2] = devbuf.c_str();
|
||||
|
||||
flags = entry->flags;
|
||||
inv_flags = entry->inv_flags;
|
||||
|
@ -839,8 +815,6 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
if (!build_mnt_flags(flagsbuf, PATH_MAX, flags, inv_flags))
|
||||
goto fail;
|
||||
vec[3] = flagsbuf;
|
||||
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
|
||||
goto fail;
|
||||
|
||||
if (entry->opts)
|
||||
allow = AA_MATCH_CONT;
|
||||
|
@ -856,9 +830,10 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
|
||||
if (entry->opts) {
|
||||
/* rule with data match required */
|
||||
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
|
||||
optsbuf.clear();
|
||||
if (!build_mnt_opts(optsbuf, entry->opts))
|
||||
goto fail;
|
||||
vec[4] = optsbuf;
|
||||
vec[4] = optsbuf.c_str();
|
||||
if (!aare_add_rule_vec(dfarules, entry->deny,
|
||||
entry->allow,
|
||||
entry->audit | AA_AUDIT_MNT_DATA,
|
||||
|
@ -870,18 +845,21 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
if ((entry->allow & AA_MAY_MOUNT) && (entry->flags & MS_BIND)
|
||||
&& !entry->dev_type && !entry->opts) {
|
||||
/* bind mount rules can't be conditional on dev_type or data */
|
||||
p = mntbuf;
|
||||
std::string tmpbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, entry->device))
|
||||
vec[0] = mntbuf.c_str();
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, entry->device))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
if (!convert_entry(typebuf, PATH_MAX +3, NULL))
|
||||
vec[1] = devbuf.c_str();
|
||||
/* FIXME: when typebuf gets converted to std::string,
|
||||
* switch tmpbuf back to typebuf */
|
||||
if (!convert_entry(tmpbuf, NULL))
|
||||
goto fail;
|
||||
vec[2] = typebuf;
|
||||
vec[2] = tmpbuf.c_str();
|
||||
|
||||
flags = entry->flags;
|
||||
inv_flags = entry->inv_flags;
|
||||
|
@ -903,17 +881,17 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
/* change type base rules can not be conditional on device,
|
||||
* device type or data
|
||||
*/
|
||||
p = mntbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
vec[0] = mntbuf.c_str();
|
||||
/* skip device and type */
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, NULL))
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, NULL))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
vec[2] = devbuf;
|
||||
vec[1] = devbuf.c_str();
|
||||
vec[2] = devbuf.c_str();
|
||||
|
||||
flags = entry->flags;
|
||||
inv_flags = entry->inv_flags;
|
||||
|
@ -934,19 +912,22 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
/* mount move rules can not be conditional on dev_type,
|
||||
* or data
|
||||
*/
|
||||
p = mntbuf;
|
||||
std::string tmpbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, entry->device))
|
||||
vec[0] = mntbuf.c_str();
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, entry->device))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
vec[1] = devbuf.c_str();
|
||||
/* skip type */
|
||||
if (!convert_entry(typebuf, PATH_MAX +3, NULL))
|
||||
/* FIXME: when typebuf gets converted to std::string,
|
||||
* switch tmpbuf back to typebuf */
|
||||
if (!convert_entry(tmpbuf, NULL))
|
||||
goto fail;
|
||||
vec[2] = typebuf;
|
||||
vec[2] = tmpbuf.c_str();
|
||||
|
||||
flags = entry->flags;
|
||||
inv_flags = entry->inv_flags;
|
||||
|
@ -968,15 +949,15 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
/* generic mount if flags are set that are not covered by
|
||||
* above commands
|
||||
*/
|
||||
p = mntbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, entry->device))
|
||||
vec[0] = mntbuf.c_str();
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, entry->device))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
vec[1] = devbuf.c_str();
|
||||
if (!build_list_val_expr(typebuf, PATH_MAX+2, entry->dev_type))
|
||||
goto fail;
|
||||
vec[2] = typebuf;
|
||||
|
@ -1005,9 +986,10 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
|
||||
if (entry->opts) {
|
||||
/* rule with data match required */
|
||||
if (!build_mnt_opts(optsbuf, PATH_MAX, entry->opts))
|
||||
optsbuf.clear();
|
||||
if (!build_mnt_opts(optsbuf, entry->opts))
|
||||
goto fail;
|
||||
vec[4] = optsbuf;
|
||||
vec[4] = optsbuf.c_str();
|
||||
if (!aare_add_rule_vec(dfarules, entry->deny,
|
||||
entry->allow,
|
||||
entry->audit | AA_AUDIT_MNT_DATA,
|
||||
|
@ -1017,27 +999,26 @@ static int process_mnt_entry(aare_ruleset_t *dfarules, struct mnt_entry *entry)
|
|||
}
|
||||
}
|
||||
if (entry->allow & AA_MAY_UMOUNT) {
|
||||
p = mntbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
vec[0] = mntbuf.c_str();
|
||||
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
|
||||
entry->audit, 1, vec, dfaflags))
|
||||
goto fail;
|
||||
count++;
|
||||
}
|
||||
if (entry->allow & AA_MAY_PIVOTROOT) {
|
||||
p = mntbuf;
|
||||
/* rule class single byte header */
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_MOUNT);
|
||||
if (!convert_entry(p, PATH_MAX +3, entry->mnt_point))
|
||||
mntbuf.assign(class_mount_hdr);
|
||||
if (!convert_entry(mntbuf, entry->mnt_point))
|
||||
goto fail;
|
||||
vec[0] = mntbuf;
|
||||
if (!convert_entry(devbuf, PATH_MAX +3, entry->device))
|
||||
vec[0] = mntbuf.c_str();
|
||||
devbuf.clear();
|
||||
if (!convert_entry(devbuf, entry->device))
|
||||
goto fail;
|
||||
vec[1] = devbuf;
|
||||
vec[1] = devbuf.c_str();
|
||||
if (!aare_add_rule_vec(dfarules, entry->deny, entry->allow,
|
||||
entry->audit, 2, vec, dfaflags))
|
||||
goto fail;
|
||||
|
@ -1058,13 +1039,13 @@ fail:
|
|||
|
||||
static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry)
|
||||
{
|
||||
char busbuf[PATH_MAX + 3];
|
||||
char namebuf[PATH_MAX + 3];
|
||||
char peer_labelbuf[PATH_MAX + 3];
|
||||
char pathbuf[PATH_MAX + 3];
|
||||
char ifacebuf[PATH_MAX + 3];
|
||||
char memberbuf[PATH_MAX + 3];
|
||||
char *p;
|
||||
std::string busbuf;
|
||||
std::string namebuf;
|
||||
std::string peer_labelbuf;
|
||||
std::string pathbuf;
|
||||
std::string ifacebuf;
|
||||
std::string memberbuf;
|
||||
char buffer[128];
|
||||
const char *vec[6];
|
||||
|
||||
pattern_t ptype;
|
||||
|
@ -1073,26 +1054,24 @@ static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry
|
|||
if (!entry) /* shouldn't happen */
|
||||
return TRUE;
|
||||
|
||||
p = busbuf;
|
||||
p += sprintf(p, "\\x%02x", AA_CLASS_DBUS);
|
||||
sprintf(buffer, "\\x%02x", AA_CLASS_DBUS);
|
||||
busbuf.append(buffer);
|
||||
|
||||
if (entry->bus) {
|
||||
ptype = convert_aaregex_to_pcre(entry->bus, 0, p,
|
||||
PATH_MAX+3 - (p - busbuf), &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->bus, 0, busbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
strcpy(p, "[^\\000]*");
|
||||
busbuf.append("[^\\000]*");
|
||||
}
|
||||
vec[0] = busbuf;
|
||||
vec[0] = busbuf.c_str();
|
||||
|
||||
if (entry->name) {
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf,
|
||||
PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
vec[1] = namebuf;
|
||||
vec[1] = namebuf.c_str();
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
vec[1] = "[^\\000]*";
|
||||
|
@ -1100,44 +1079,40 @@ static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry
|
|||
|
||||
if (entry->peer_label) {
|
||||
ptype = convert_aaregex_to_pcre(entry->peer_label, 0,
|
||||
peer_labelbuf, PATH_MAX+3,
|
||||
&pos);
|
||||
peer_labelbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
vec[2] = peer_labelbuf;
|
||||
vec[2] = peer_labelbuf.c_str();
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
vec[2] = "[^\\000]*";
|
||||
}
|
||||
|
||||
if (entry->path) {
|
||||
ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf,
|
||||
PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
vec[3] = pathbuf;
|
||||
vec[3] = pathbuf.c_str();
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
vec[3] = "[^\\000]*";
|
||||
}
|
||||
|
||||
if (entry->interface) {
|
||||
ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf,
|
||||
PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
vec[4] = ifacebuf;
|
||||
vec[4] = ifacebuf.c_str();
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
vec[4] = "[^\\000]*";
|
||||
}
|
||||
|
||||
if (entry->member) {
|
||||
ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf,
|
||||
PATH_MAX+3, &pos);
|
||||
ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf, &pos);
|
||||
if (ptype == ePatternInvalid)
|
||||
goto fail;
|
||||
vec[5] = memberbuf;
|
||||
vec[5] = memberbuf.c_str();
|
||||
} else {
|
||||
/* match any char except \000 0 or more times */
|
||||
vec[5] = "[^\\000]*";
|
||||
|
@ -1305,31 +1280,41 @@ static int test_filter_slashes(void)
|
|||
|
||||
#define MY_REGEX_TEST(input, expected_str, expected_type) \
|
||||
do { \
|
||||
char tbuf[PATH_MAX + 3]; \
|
||||
std::string tbuf; \
|
||||
std::string tbuf2 = "testprefix"; \
|
||||
char *test_string; \
|
||||
char* output_string = NULL; \
|
||||
char *output_string = NULL; \
|
||||
std::string expected_str2; \
|
||||
pattern_t ptype; \
|
||||
int pos; \
|
||||
\
|
||||
test_string = strdup((input)); \
|
||||
ptype = convert_aaregex_to_pcre(test_string, 0, tbuf, PATH_MAX + 3, &pos); \
|
||||
ptype = convert_aaregex_to_pcre(test_string, 0, tbuf, &pos); \
|
||||
asprintf(&output_string, "simple regex conversion for '%s'\texpected = '%s'\tresult = '%s'", \
|
||||
(input), expected_str, tbuf); \
|
||||
MY_TEST(strcmp(tbuf, (expected_str)) == 0, output_string); \
|
||||
(input), expected_str, tbuf.c_str()); \
|
||||
MY_TEST(strcmp(tbuf.c_str(), (expected_str)) == 0, output_string); \
|
||||
MY_TEST(ptype == (expected_type), "simple regex conversion type check for '" input "'"); \
|
||||
free(output_string); \
|
||||
/* ensure convert_aaregex_to_pcre appends only to passed ref string */ \
|
||||
expected_str2 = tbuf2; \
|
||||
expected_str2.append((expected_str)); \
|
||||
ptype = convert_aaregex_to_pcre(test_string, 0, tbuf2, &pos); \
|
||||
asprintf(&output_string, "simple regex conversion for '%s'\texpected = '%s'\tresult = '%s'", \
|
||||
(input), expected_str2.c_str(), tbuf2.c_str()); \
|
||||
MY_TEST((tbuf2 == expected_str2), output_string); \
|
||||
free(test_string); free(output_string); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define MY_REGEX_FAIL_TEST(input) \
|
||||
do { \
|
||||
char tbuf[PATH_MAX + 3]; \
|
||||
std::string tbuf; \
|
||||
char *test_string; \
|
||||
pattern_t ptype; \
|
||||
int pos; \
|
||||
\
|
||||
test_string = strdup((input)); \
|
||||
ptype = convert_aaregex_to_pcre(test_string, 0, tbuf, PATH_MAX + 3, &pos); \
|
||||
ptype = convert_aaregex_to_pcre(test_string, 0, tbuf, &pos); \
|
||||
MY_TEST(ptype == ePatternInvalid, "simple regex conversion invalid type check for '" input "'"); \
|
||||
free(test_string); \
|
||||
} \
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue