871
871
for (States::iterator i = states.begin(); i != states.end(); i++) {
872
872
uint32_t accept = accept_perms(*i);
873
873
if (*i == start || accept) {
874
if ((accept & AA_EXEC_MODIFIERS) &&
875
!AA_EXEC_SINGLE_MODIFIER_SET(accept))
874
if (accept & AA_ERROR_BIT)
1496
#define ACCUMULATING_FLAGS \
1497
(AA_MAY_READ | AA_MAY_WRITE | AA_MAY_APPEND | AA_MAY_EXEC | \
1498
AA_MAY_LINK | AA_MAY_LOCK | AA_EXEC_MMAP | AA_CHANGE_PROFILE)
1495
static inline int diff_qualifiers(uint32_t perm1, uint32_t perm2)
1497
return ((perm1 & AA_EXEC_MODIFIERS) && (perm2 & AA_EXEC_MODIFIERS) &&
1498
(perm1 & AA_EXEC_MODIFIERS) != (perm2 & AA_EXEC_MODIFIERS));
1501
1502
* Compute the permission flags that this state corresponds to. If we
1507
1508
uint32_t perms = 0, exact_match_perms = 0;
1509
1510
for (State::iterator i = state->begin(); i != state->end(); i++) {
1510
if (MatchFlag *match = dynamic_cast<MatchFlag *>(*i)) {
1511
perms |= match->flag;
1512
if (dynamic_cast<ExactMatchFlag *>(match))
1513
exact_match_perms |= match->flag;
1512
if (!(match= dynamic_cast<MatchFlag *>(*i)))
1514
if (dynamic_cast<ExactMatchFlag *>(match)) {
1515
if (!is_merged_x_consistent(exact_match_perms,
1517
exact_match_perms |= AA_ERROR_BIT;
1518
exact_match_perms |= match->flag;
1520
if (!is_merged_x_consistent(perms, match->flag))
1521
perms |= AA_ERROR_BIT;
1522
perms |= match->flag;
1517
if (exact_match_perms & ~ACCUMULATING_FLAGS)
1518
perms = (exact_match_perms & ~ACCUMULATING_FLAGS) |
1519
(perms & ACCUMULATING_FLAGS);
1526
perms |= exact_match_perms &
1527
~(AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE);
1529
if (exact_match_perms & AA_USER_EXEC_TYPE)
1530
perms = (exact_match_perms & AA_USER_EXEC_TYPE) |
1531
(perms & ~AA_USER_EXEC_TYPE);
1533
if (exact_match_perms & AA_OTHER_EXEC_TYPE)
1534
perms = (exact_match_perms & AA_OTHER_EXEC_TYPE) |
1535
(perms & ~AA_OTHER_EXEC_TYPE);
1537
if (perms & AA_ERROR_BIT) {
1538
fprintf(stderr, "error bit 0x%x\n", perms);
1542
if (perms & ~AA_VALID_PERMS)
1543
yyerror(_("Internal error accumulated invalid perm 0x%llx\n"), perms);
1524
1548
extern "C" int aare_add_rule(aare_ruleset_t *rules, char *rule, uint32_t perms)
1526
static MatchFlag *match_flags[sizeof(perms) * 8];
1527
static ExactMatchFlag *exact_match_flags[sizeof(perms) * 8];
1550
static MatchFlag *match_flags[sizeof(perms) * 8 - 1];
1551
static MatchFlag *exec_match_flags[8 * 2];
1552
static ExactMatchFlag *exact_match_flags[8 * 2];
1528
1553
Node *tree, *accept;
1529
1554
int exact_match;
1551
1576
if (rules->reverse)
1552
1577
flip_tree(tree);
1579
#define ALL_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE)
1580
#define EXTRACT_X_INDEX(perm, shift) (((perm) >> (shift + 7)) & 0x7)
1582
if (perms & ALL_EXEC_TYPE && (!perms & AA_EXEC_BITS))
1583
fprintf(stderr, "adding X rule without MAY_EXEC: 0x%x %s\n", perms, rule);
1555
for (unsigned int n = 0; perms && n < sizeof(perms) * 8; n++) {
1586
for (unsigned int n = 0; perms && n < (sizeof(perms) * 8) - 1; n++) {
1556
1587
uint32_t mask = 1 << n;
1558
1589
if (perms & mask) {
1559
1590
perms &= ~mask;
1562
if (exact_match && (mask & ~ACCUMULATING_FLAGS)) {
1563
if (exact_match_flags[n])
1564
flag = exact_match_flags[n]->dup();
1566
exact_match_flags[n] = new ExactMatchFlag(mask);
1567
flag = exact_match_flags[n];
1593
if (mask & AA_EXEC_BITS) {
1596
if (mask & AA_USER_EXEC_TYPE) {
1597
eperm = mask | (perms & AA_USER_EXEC_TYPE);
1598
index = EXTRACT_X_INDEX(eperm, AA_USER_SHIFT);
1600
eperm = mask | (perms & AA_OTHER_EXEC_TYPE);
1601
index = EXTRACT_X_INDEX(eperm, AA_OTHER_SHIFT) + 8;
1604
if (exact_match_flags[index]) {
1605
flag = exact_match_flags[index]->dup();
1607
exact_match_flags[index] = new ExactMatchFlag(eperm);
1608
flag = exact_match_flags[index];
1611
if (exec_match_flags[index]) {
1612
flag = exec_match_flags[index]->dup();
1614
exec_match_flags[index] = new MatchFlag(eperm);
1615
flag = exec_match_flags[index];
1618
} else if (mask & ALL_EXEC_TYPE) {
1619
/* these cases are covered by EXEC_BITS */
1622
if (match_flags[n]) {
1571
1623
flag = match_flags[n]->dup();
1573
1625
match_flags[n] = new MatchFlag(mask);
1574
1626
flag = match_flags[n];
1583
1636
rules->root = new AltNode(rules->root, new CatNode(tree, accept));
1588
#undef ACCUMULATING_FLAGS
1590
1642
/* create a dfa from the ruleset
1591
1643
* returns: buffer contain dfa tables, @size set to the size of the tables
1592
1644
* else NULL on failure