2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 01:57:43 +00:00

Merge fix xtable generation and drop unusd perm32 v1 support

The xtable on perms32 capable systems is being padded to the size of
the accept state tables. This was a hack to get around issue in a buggy
perms32 v1. We do not support any system using perms 32 v1 so we can
drop the hack.

Similarly since we don't support perms32v1 we don't support prompt
compat dev or perms32v1, so drop them as well

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1750
Approved-by: Ryan Lee <rlee287@yahoo.com>
Merged-by: John Johansen <john@jjmx.net>
This commit is contained in:
John Johansen 2025-07-31 18:08:06 +00:00
commit ea97cbedef
13 changed files with 40 additions and 365 deletions

View File

@ -203,7 +203,7 @@ bool aare_rules::append_rule(const char *rule, bool oob, bool with_perm,
CHFA *aare_rules::create_chfa(int *min_match_len, CHFA *aare_rules::create_chfa(int *min_match_len,
vector <aa_perms> &perms_table, vector <aa_perms> &perms_table,
optflags const &opts, bool filedfa, optflags const &opts, bool filedfa,
bool extended_perms, bool prompt) bool extended_perms)
{ {
/* finish constructing the expr tree from the different permission /* finish constructing the expr tree from the different permission
* set nodes */ * set nodes */
@ -315,7 +315,7 @@ CHFA *aare_rules::create_chfa(int *min_match_len,
//cerr << "Checking extended perms " << extended_perms << "\n"; //cerr << "Checking extended perms " << extended_perms << "\n";
if (extended_perms) { if (extended_perms) {
//cerr << "creating permstable\n"; //cerr << "creating permstable\n";
dfa.compute_perms_table(perms_table, prompt); dfa.compute_perms_table(perms_table);
// TODO: move perms table to a class // TODO: move perms table to a class
if (opts.dump & DUMP_DFA_TRANS_TABLE && perms_table.size()) { if (opts.dump & DUMP_DFA_TRANS_TABLE && perms_table.size()) {
cerr << "Perms Table size: " << perms_table.size() << "\n"; cerr << "Perms Table size: " << perms_table.size() << "\n";
@ -329,7 +329,7 @@ CHFA *aare_rules::create_chfa(int *min_match_len,
cerr << "\n"; cerr << "\n";
} }
} }
chfa = new CHFA(dfa, eq, opts, extended_perms, prompt); chfa = new CHFA(dfa, eq, opts, extended_perms);
if (opts.dump & DUMP_DFA_TRANS_TABLE) if (opts.dump & DUMP_DFA_TRANS_TABLE)
chfa->dump(cerr); chfa->dump(cerr);
if (opts.dump & DUMP_DFA_COMPTRESSED_STATES) if (opts.dump & DUMP_DFA_COMPTRESSED_STATES)
@ -350,15 +350,14 @@ CHFA *aare_rules::create_chfa(int *min_match_len,
void *aare_rules::create_dfablob(size_t *size, int *min_match_len, void *aare_rules::create_dfablob(size_t *size, int *min_match_len,
vector <aa_perms> &perms_table, vector <aa_perms> &perms_table,
optflags const &opts, bool filedfa, optflags const &opts, bool filedfa,
bool extended_perms, bool prompt) bool extended_perms)
{ {
char *buffer = NULL; char *buffer = NULL;
stringstream stream; stringstream stream;
try { try {
CHFA *chfa = create_chfa(min_match_len, perms_table, CHFA *chfa = create_chfa(min_match_len, perms_table,
opts, filedfa, extended_perms, opts, filedfa, extended_perms);
prompt);
if (!chfa) { if (!chfa) {
*size = 0; *size = 0;
return NULL; return NULL;
@ -383,82 +382,3 @@ void *aare_rules::create_dfablob(size_t *size, int *min_match_len,
return buffer; return buffer;
} }
/* create a dfa from the ruleset
* returns: buffer contain dfa tables, @size set to the size of the tables
* else NULL on failure, @min_match_len set to the shortest string
* that can match the dfa for determining xmatch priority.
*/
void *aare_rules::create_welded_dfablob(aare_rules *file_rules,
size_t *size, int *min_match_len,
size_t *new_start,
vector <aa_perms> &perms_table,
optflags const &opts,
bool extended_perms, bool prompt)
{
int file_min_len;
vector <aa_perms> file_perms;
CHFA *file_chfa;
try {
file_chfa = file_rules->create_chfa(&file_min_len,
file_perms, opts,
true, extended_perms, prompt);
if (!file_chfa) {
*size = 0;
return NULL;
}
}
catch(int error) {
*size = 0;
return NULL;
}
CHFA *policy_chfa;
try {
policy_chfa = create_chfa(min_match_len,
perms_table, opts,
false, extended_perms, prompt);
if (!policy_chfa) {
delete file_chfa;
*size = 0;
return NULL;
}
}
catch(int error) {
delete file_chfa;
*size = 0;
return NULL;
}
stringstream stream;
try {
policy_chfa->weld_file_to_policy(*file_chfa, *new_start,
extended_perms, prompt,
perms_table, file_perms);
policy_chfa->flex_table(stream, opts);
}
catch(int error) {
delete (file_chfa);
delete (policy_chfa);
*size = 0;
return NULL;
}
delete file_chfa;
delete policy_chfa;
/* write blob to buffer */
stringbuf *buf = stream.rdbuf();
buf->pubseekpos(0);
*size = buf->in_avail();
if (file_min_len < *min_match_len)
*min_match_len = file_min_len;
char *buffer = (char *)malloc(*size);
if (!buffer)
return NULL;
buf->sgetn(buffer, *size);
return buffer;
}

View File

@ -123,17 +123,11 @@ class aare_rules {
CHFA *create_chfa(int *min_match_len, CHFA *create_chfa(int *min_match_len,
std::vector <aa_perms> &perms_table, std::vector <aa_perms> &perms_table,
optflags const &opts, bool filedfa, optflags const &opts, bool filedfa,
bool extended_perms, bool prompt); bool extended_perms);
void *create_dfablob(size_t *size, int *min_match_len, void *create_dfablob(size_t *size, int *min_match_len,
std::vector <aa_perms> &perms_table, std::vector <aa_perms> &perms_table,
optflags const &opts, optflags const &opts,
bool filedfa, bool extended_perms, bool prompt); bool filedfa, bool extended_perms);
void *create_welded_dfablob(aare_rules *file_rules,
size_t *size, int *min_match_len,
size_t *new_start,
std::vector <aa_perms> &perms_table,
optflags const &opts,
bool extended_perms, bool prompt);
}; };
#endif /* __LIBAA_RE_RULES_H */ #endif /* __LIBAA_RE_RULES_H */

View File

@ -59,7 +59,7 @@ void CHFA::init_free_list(vector<pair<size_t, size_t> > &free_list,
* permtable index flag * permtable index flag
*/ */
CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts, CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
bool permindex, bool prompt): eq(eq) bool permindex): eq(eq)
{ {
if (opts.dump & DUMP_DFA_TRANS_PROGRESS) if (opts.dump & DUMP_DFA_TRANS_PROGRESS)
fprintf(stderr, "Compressing HFA:\r"); fprintf(stderr, "Compressing HFA:\r");
@ -118,12 +118,10 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
accept2.resize(max(dfa.states.size(), (size_t) 2)); accept2.resize(max(dfa.states.size(), (size_t) 2));
dfa.nonmatching->map_perms_to_accept(accept[0], dfa.nonmatching->map_perms_to_accept(accept[0],
accept2[0], accept2[0],
accept3, accept3);
prompt);
dfa.start->map_perms_to_accept(accept[1], dfa.start->map_perms_to_accept(accept[1],
accept2[1], accept2[1],
accept3, accept3);
prompt);
} }
next_check.resize(max(optimal, (size_t) dfa.max_range)); next_check.resize(max(optimal, (size_t) dfa.max_range));
free_list.resize(next_check.size()); free_list.resize(next_check.size());
@ -147,8 +145,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
else else
(*i)->map_perms_to_accept(accept[num.size()], (*i)->map_perms_to_accept(accept[num.size()],
accept2[num.size()], accept2[num.size()],
accept3, accept3);
prompt);
num.insert(make_pair(*i, num.size())); num.insert(make_pair(*i, num.size()));
} }
if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) { if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) {
@ -170,8 +167,7 @@ CHFA::CHFA(DFA &dfa, map<transchar, transchar> &eq, optflags const &opts,
else else
i->second->map_perms_to_accept(accept[num.size()], i->second->map_perms_to_accept(accept[num.size()],
accept2[num.size()], accept2[num.size()],
accept3, accept3);
prompt);
num.insert(make_pair(i->second, num.size())); num.insert(make_pair(i->second, num.size()));
} }
if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) { if (opts.dump & (DUMP_DFA_TRANS_PROGRESS)) {
@ -519,116 +515,3 @@ void CHFA::flex_table(ostream &os, optflags const &opts) {
flex_table_serialize<uint16_t>(*this, os, (1 << 16) - 1); flex_table_serialize<uint16_t>(*this, os, (1 << 16) - 1);
} }
} }
/*
* @file_chfa: chfa to add on to the policy chfa
* @new_start: new start state for where the @file_dfa is in the new chfa
*
* Make a new chfa that is a combination of policy and file chfas. It
* assumes policy is built with AA_CLASS_FILE support transition. The
* resultant chfa will have file states and indexes offset except for
* start and null states.
*
* NOTE:
* - modifies chfa
* requires:
* - no ec
* - policy chfa has transitions state[start].next[AA_CLASS_FILE]
* - policy perms table is build if using permstable
*/
void CHFA::weld_file_to_policy(CHFA &file_chfa, size_t &new_start,
bool accept_idx, bool prompt,
vector <aa_perms> &policy_perms,
vector <aa_perms> &file_perms)
{
// doesn't support remapping eq classes yet
if (eq.size() > 0 || file_chfa.eq.size() > 0)
throw 1;
size_t old_base_size = default_base.size();
size_t old_next_size = next_check.size();
const State *nonmatching = default_base[0].first;
//const State *start = default_base[1].first;
const State *file_nonmatching = file_chfa.default_base[0].first;
// renumber states from file_dfa by appending to policy dfa
num.insert(make_pair(file_nonmatching, 0)); // remap to policy nonmatching
for (map<const State *, size_t>::iterator i = file_chfa.num.begin(); i != file_chfa.num.end() ; i++) {
if (i->first == file_nonmatching)
continue;
num.insert(make_pair(i->first, i->second + old_base_size));
}
// handle default and base table expansion, and setup renumbering
// while we remap file_nonmatch within the table, we still keep its
// slot.
bool first = true;
for (DefaultBase::iterator i = file_chfa.default_base.begin(); i != file_chfa.default_base.end(); i++) {
const State *def;
size_t base;
if (first) {
first = false;
// remap file_nonmatch to nonmatch
def = nonmatching;
base = 0;
} else {
def = i->first;
base = i->second + old_next_size;
}
default_base.push_back(make_pair(def, base));
}
// mapping for these are handled by num[]
for (NextCheck::iterator i = file_chfa.next_check.begin(); i != file_chfa.next_check.end(); i++) {
next_check.push_back(*i);
}
// append file perms to policy perms, and rework permsidx if needed
if (accept_idx) {
// policy idx double
// file + doubled offset
// Requires: policy perms table, so we can double and
// update indexes
// * file perm idx to start on even idx
// * policy perms table size to double and entries
// to repeat
assert(accept.size() == old_base_size);
accept.resize(accept.size() + file_chfa.accept.size());
assert(policy_perms.size() < std::numeric_limits<ssize_t>::max());
ssize_t size = (ssize_t) policy_perms.size();
policy_perms.resize(size*2 + file_perms.size());
// shift and double the policy perms
for (ssize_t i = size - 1; i >= 0; i--) {
policy_perms[i*2] = policy_perms[i];
policy_perms[i*2 + 1] = policy_perms[i];
}
// update policy accept idx for the new shifted perms table
for (size_t i = 0; i < old_base_size; i++) {
accept[i] = accept[i]*2;
}
// copy over file perms
for (size_t i = 0; i < file_perms.size(); i++) {
policy_perms[size*2 + i] = file_perms[i];
}
// shift file accept indexs
for (size_t i = 0; i < file_chfa.accept.size(); i++) {
accept[old_base_size + i] = file_chfa.accept[i] + size*2;
}
} else {
// perms are stored in accept just append the perms
size_t size = accept.size();
accept.resize(size + file_chfa.accept.size());
accept2.resize(size + file_chfa.accept.size());
for (size_t i = 0; i < file_chfa.accept.size(); i++) {
accept[size + i] = file_chfa.accept[i];
accept2[size + i] = file_chfa.accept2[i];
}
}
// Rework transition state[start].next[AA_CLASS_FILE]
next_check[default_base[1].second + AA_CLASS_FILE].first = file_chfa.start;
new_start = num[file_chfa.start];
}

View File

@ -39,7 +39,7 @@ class CHFA {
public: public:
CHFA(void); CHFA(void);
CHFA(DFA &dfa, std::map<transchar, transchar> &eq, optflags const &opts, CHFA(DFA &dfa, std::map<transchar, transchar> &eq, optflags const &opts,
bool permindex, bool prompt); bool permindex);
void dump(ostream & os); void dump(ostream & os);
void flex_table(ostream &os, optflags const &opts); void flex_table(ostream &os, optflags const &opts);
void init_free_list(std::vector<std::pair<size_t, size_t> > &free_list, void init_free_list(std::vector<std::pair<size_t, size_t> > &free_list,
@ -48,10 +48,6 @@ class CHFA {
StateTrans &cases); StateTrans &cases);
void insert_state(std::vector<std::pair<size_t, size_t> > &free_list, void insert_state(std::vector<std::pair<size_t, size_t> > &free_list,
State *state, DFA &dfa); State *state, DFA &dfa);
void weld_file_to_policy(CHFA &file_chfa, size_t &new_start,
bool accept_idx, bool prompt,
std::vector <aa_perms> &policy_perms,
std::vector <aa_perms> &file_perms);
// private: // private:
// sigh templates suck, friend declaration does not work so for now // sigh templates suck, friend declaration does not work so for now

View File

@ -1367,13 +1367,12 @@ void DFA::apply_equivalence_classes(map<transchar, transchar> &eq)
} }
void DFA::compute_perms_table_ent(State *state, size_t pos, void DFA::compute_perms_table_ent(State *state, size_t pos,
vector <aa_perms> &perms_table, vector <aa_perms> &perms_table)
bool prompt)
{ {
uint32_t accept1, accept2, accept3; uint32_t accept1, accept2, accept3;
// until front end doesn't map the way it does // until front end doesn't map the way it does
state->map_perms_to_accept(accept1, accept2, accept3, prompt); state->map_perms_to_accept(accept1, accept2, accept3);
if (filedfa) { if (filedfa) {
state->idx = pos * 2; state->idx = pos * 2;
perms_table[pos*2] = compute_fperms_user(accept1, accept2, accept3); perms_table[pos*2] = compute_fperms_user(accept1, accept2, accept3);
@ -1384,7 +1383,7 @@ void DFA::compute_perms_table_ent(State *state, size_t pos,
} }
} }
void DFA::compute_perms_table(vector <aa_perms> &perms_table, bool prompt) void DFA::compute_perms_table(vector <aa_perms> &perms_table)
{ {
size_t mult = filedfa ? 2 : 1; size_t mult = filedfa ? 2 : 1;
size_t pos = 2; size_t pos = 2;
@ -1393,13 +1392,13 @@ void DFA::compute_perms_table(vector <aa_perms> &perms_table, bool prompt)
perms_table.resize(states.size() * mult); perms_table.resize(states.size() * mult);
// nonmatching and start need to be 0 and 1 so handle outside of loop // nonmatching and start need to be 0 and 1 so handle outside of loop
compute_perms_table_ent(nonmatching, 0, perms_table, prompt); compute_perms_table_ent(nonmatching, 0, perms_table);
compute_perms_table_ent(start, 1, perms_table, prompt); compute_perms_table_ent(start, 1, perms_table);
for (Partition::iterator i = states.begin(); i != states.end(); i++) { for (Partition::iterator i = states.begin(); i != states.end(); i++) {
if (*i == nonmatching || *i == start) if (*i == nonmatching || *i == start)
continue; continue;
compute_perms_table_ent(*i, pos, perms_table, prompt); compute_perms_table_ent(*i, pos, perms_table);
pos++; pos++;
} }
} }

View File

@ -289,13 +289,10 @@ public:
int apply_and_clear_deny(void) { return perms.apply_and_clear_deny(); } int apply_and_clear_deny(void) { return perms.apply_and_clear_deny(); }
void map_perms_to_accept(perm32_t &accept1, perm32_t &accept2, void map_perms_to_accept(perm32_t &accept1, perm32_t &accept2,
perm32_t &accept3, bool prompt) perm32_t &accept3)
{ {
accept1 = perms.allow; accept1 = perms.allow;
if (prompt && prompt_compat_mode == PROMPT_COMPAT_DEV) accept2 = PACK_AUDIT_CTL(perms.audit, perms.quiet);
accept2 = PACK_AUDIT_CTL(perms.prompt, perms.quiet);
else
accept2 = PACK_AUDIT_CTL(perms.audit, perms.quiet);
accept3 = perms.prompt; accept3 = perms.prompt;
} }
@ -399,10 +396,8 @@ public:
void apply_equivalence_classes(std::map<transchar, transchar> &eq); void apply_equivalence_classes(std::map<transchar, transchar> &eq);
void compute_perms_table_ent(State *state, size_t pos, void compute_perms_table_ent(State *state, size_t pos,
std::vector <aa_perms> &perms_table, std::vector <aa_perms> &perms_table);
bool prompt); void compute_perms_table(std::vector <aa_perms> &perms_table);
void compute_perms_table(std::vector <aa_perms> &perms_table,
bool prompt);
unsigned int diffcount; unsigned int diffcount;
int oob_range; int oob_range;

View File

@ -133,8 +133,7 @@ struct aa_perms compute_fperms_user(uint32_t accept1, uint32_t accept2,
perms.prompt = map_old_perms(dfa_user_allow(accept3)); perms.prompt = map_old_perms(dfa_user_allow(accept3));
perms.audit = map_old_perms(dfa_user_audit(accept1, accept2)); perms.audit = map_old_perms(dfa_user_audit(accept1, accept2));
perms.quiet = map_old_perms(dfa_user_quiet(accept1, accept2)); perms.quiet = map_old_perms(dfa_user_quiet(accept1, accept2));
if (prompt_compat_mode != PROMPT_COMPAT_PERMSV1) perms.xindex = dfa_user_xindex(accept1);
perms.xindex = dfa_user_xindex(accept1);
compute_fperms_allow(&perms, accept1); compute_fperms_allow(&perms, accept1);
perms.prompt &= ~(perms.allow | perms.deny); perms.prompt &= ~(perms.allow | perms.deny);
@ -150,8 +149,7 @@ struct aa_perms compute_fperms_other(uint32_t accept1, uint32_t accept2,
perms.prompt = map_old_perms(dfa_other_allow(accept3)); perms.prompt = map_old_perms(dfa_other_allow(accept3));
perms.audit = map_old_perms(dfa_other_audit(accept1, accept2)); perms.audit = map_old_perms(dfa_other_audit(accept1, accept2));
perms.quiet = map_old_perms(dfa_other_quiet(accept1, accept2)); perms.quiet = map_old_perms(dfa_other_quiet(accept1, accept2));
if (prompt_compat_mode != PROMPT_COMPAT_PERMSV1) perms.xindex = dfa_other_xindex(accept1);
perms.xindex = dfa_other_xindex(accept1);
compute_fperms_allow(&perms, accept1); compute_fperms_allow(&perms, accept1);
perms.prompt &= ~(perms.allow | perms.deny); perms.prompt &= ~(perms.allow | perms.deny);
@ -165,12 +163,6 @@ static uint32_t map_other(uint32_t x)
((x & 0x60) << 19); /* SETOPT/GETOPT */ ((x & 0x60) << 19); /* SETOPT/GETOPT */
} }
static uint32_t map_xbits(uint32_t x)
{
return ((x & 0x1) << 7) |
((x & 0x7e) << 9);
}
struct aa_perms compute_perms_entry(uint32_t accept1, uint32_t accept2, struct aa_perms compute_perms_entry(uint32_t accept1, uint32_t accept2,
uint32_t accept3) uint32_t accept3)
// don't need to worry about version internally within the parser // don't need to worry about version internally within the parser

View File

@ -185,19 +185,9 @@ bool prompt_compat_mode_supported(int mode)
if (mode == PROMPT_COMPAT_PERMSV2 && if (mode == PROMPT_COMPAT_PERMSV2 &&
(kernel_supports_permstable32 && !kernel_supports_permstable32_v1)) (kernel_supports_permstable32 && !kernel_supports_permstable32_v1))
return true; return true;
/*
else if (mode == PROMPT_COMPAT_DEV &&
kernel_supports_promptdev)
return true;
*/
else if (mode == PROMPT_COMPAT_FLAG && else if (mode == PROMPT_COMPAT_FLAG &&
kernel_supports_permstable32) kernel_supports_permstable32)
return true; return true;
/*
else if (mode == PROMPT_COMPAT_PERMSV1 &&
(kernel_supports_permstable32_v1))
return true;
*/
else if (mode == PROMPT_COMPAT_IGNORE) else if (mode == PROMPT_COMPAT_IGNORE)
return true; return true;
@ -208,12 +198,8 @@ int default_prompt_compat_mode()
{ {
if (prompt_compat_mode_supported(PROMPT_COMPAT_PERMSV2)) if (prompt_compat_mode_supported(PROMPT_COMPAT_PERMSV2))
return PROMPT_COMPAT_PERMSV2; return PROMPT_COMPAT_PERMSV2;
if (prompt_compat_mode_supported(PROMPT_COMPAT_DEV))
return PROMPT_COMPAT_DEV;
if (prompt_compat_mode_supported(PROMPT_COMPAT_FLAG)) if (prompt_compat_mode_supported(PROMPT_COMPAT_FLAG))
return PROMPT_COMPAT_FLAG; return PROMPT_COMPAT_FLAG;
if (prompt_compat_mode_supported(PROMPT_COMPAT_PERMSV1))
return PROMPT_COMPAT_PERMSV1;
if (prompt_compat_mode_supported(PROMPT_COMPAT_IGNORE)) if (prompt_compat_mode_supported(PROMPT_COMPAT_IGNORE))
return PROMPT_COMPAT_IGNORE; return PROMPT_COMPAT_IGNORE;
return PROMPT_COMPAT_IGNORE; return PROMPT_COMPAT_IGNORE;
@ -231,12 +217,6 @@ void print_prompt_compat_mode(FILE *f)
case PROMPT_COMPAT_PERMSV2: case PROMPT_COMPAT_PERMSV2:
fprintf(f, "permsv2"); fprintf(f, "permsv2");
break; break;
case PROMPT_COMPAT_PERMSV1:
fprintf(f, "permsv1");
break;
case PROMPT_COMPAT_DEV:
fprintf(stderr, "dev");
break;
default: default:
fprintf(f, "Unknown prompt compat mode '%d'", prompt_compat_mode); fprintf(f, "Unknown prompt compat mode '%d'", prompt_compat_mode);
} }

View File

@ -384,13 +384,11 @@ void sd_serialize_rlimits(std::ostringstream &buf, struct aa_rlimits *limits)
sd_write_structend(buf); sd_write_structend(buf);
} }
void sd_serialize_xtable(std::ostringstream &buf, char **table, void sd_serialize_xtable(std::ostringstream &buf, char **table)
size_t min_size)
{ {
size_t count; size_t count;
size_t size;
if (!table[4] && min_size == 0) if (!table[4])
return; return;
sd_write_struct(buf, "xtable"); sd_write_struct(buf, "xtable");
count = 0; count = 0;
@ -399,9 +397,7 @@ void sd_serialize_xtable(std::ostringstream &buf, char **table,
count++; count++;
} }
size = max(min_size, count); sd_write_array(buf, NULL, count);
sd_write_array(buf, NULL, size);
for (size_t i = 4; i < count + 4; i++) { for (size_t i = 4; i < count + 4; i++) {
size_t len = strlen(table[i]) + 1; size_t len = strlen(table[i]) + 1;
@ -414,13 +410,6 @@ void sd_serialize_xtable(std::ostringstream &buf, char **table,
} }
sd_write_strn(buf, table[i], len, NULL); sd_write_strn(buf, table[i], len, NULL);
} }
if (min_size > count) {
//fprintf(stderr, "Adding padding to xtable count %lu, min %lu\n", count, min_size);
for (; count < min_size; count++) {
/* fill with null strings */
sd_write_strn(buf, "\000", 1, NULL);
}
}
sd_write_arrayend(buf); sd_write_arrayend(buf);
sd_write_structend(buf); sd_write_structend(buf);
@ -554,38 +543,17 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile,
sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size, sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size,
profile->policy.perms_table); profile->policy.perms_table);
if (kernel_supports_permstable32) { if (kernel_supports_permstable32) {
sd_serialize_xtable(buf, profile->exec_table, sd_serialize_xtable(buf, profile->exec_table);
profile->uses_prompt_rules &&
prompt_compat_mode == PROMPT_COMPAT_PERMSV1 ?
profile->policy.perms_table.size() : 0);
} }
sd_write_structend(buf); sd_write_structend(buf);
} }
/* either have a single dfa or lists of different entry types */ sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size,
if (profile->uses_prompt_rules && prompt_compat_mode == PROMPT_COMPAT_PERMSV1) { profile->dfa.perms_table);
/* special compat mode to work around verification problem */ if (profile->dfa.dfa) {
sd_serialize_dfa(buf, profile->policy.dfa, profile->policy.size, // fprintf(stderr, "profile %s: dfa xtable\n", profile->name);
profile->policy.perms_table); sd_serialize_xtable(buf, profile->exec_table);
sd_write_name(buf, "dfa_start");
sd_write_uint32(buf, profile->policy.file_start);
if (profile->policy.dfa) {
// fprintf(stderr, "profile %s: policy xtable\n", profile->name);
// TODO: this is dummy exec make dependent on V1
sd_serialize_xtable(buf, profile->exec_table,
//permstable32_v1 workaround
profile->policy.perms_table.size());
}
} else {
sd_serialize_dfa(buf, profile->dfa.dfa, profile->dfa.size,
profile->dfa.perms_table);
if (profile->dfa.dfa) {
// fprintf(stderr, "profile %s: dfa xtable\n", profile->name);
sd_serialize_xtable(buf, profile->exec_table,
//??? work around
profile->dfa.perms_table.size());
}
} }
sd_write_structend(buf); sd_write_structend(buf);
} }

View File

@ -797,12 +797,8 @@ static int process_arg(int c, char *optarg)
case ARG_PROMPT_COMPAT: case ARG_PROMPT_COMPAT:
if (strcmp(optarg, "permsv2") == 0) { if (strcmp(optarg, "permsv2") == 0) {
prompt_compat_mode = PROMPT_COMPAT_PERMSV2; prompt_compat_mode = PROMPT_COMPAT_PERMSV2;
} else if (strcmp(optarg, "permsv1") == 0) {
prompt_compat_mode = PROMPT_COMPAT_PERMSV1;
} else if (strcmp(optarg, "default") == 0) { } else if (strcmp(optarg, "default") == 0) {
prompt_compat_mode = default_prompt_compat_mode(); prompt_compat_mode = default_prompt_compat_mode();
} else if (strcmp(optarg, "dev") == 0) {
prompt_compat_mode = PROMPT_COMPAT_DEV;
} else if (strcmp(optarg, "ignore") == 0) { } else if (strcmp(optarg, "ignore") == 0) {
prompt_compat_mode = PROMPT_COMPAT_IGNORE; prompt_compat_mode = PROMPT_COMPAT_IGNORE;
} else if (strcmp(optarg, "flag") == 0) { } else if (strcmp(optarg, "flag") == 0) {

View File

@ -244,10 +244,7 @@ int post_process_profile(Profile *profile, int debug_only)
error = post_process_policy_list(profile->hat_table, debug_only); error = post_process_policy_list(profile->hat_table, debug_only);
if (prompt_compat_mode == PROMPT_COMPAT_DEV && profile->uses_prompt_rules) if (prompt_compat_mode == PROMPT_COMPAT_FLAG && profile->uses_prompt_rules)
profile->flags.flags |= FLAG_PROMPT_COMPAT;
else if (prompt_compat_mode == PROMPT_COMPAT_FLAG && profile->uses_prompt_rules)
profile->flags.mode = MODE_PROMPT; profile->flags.mode = MODE_PROMPT;
return error; return error;

View File

@ -578,7 +578,7 @@ build:
* *
* we don't need to build xmatch for permstable32, so don't * we don't need to build xmatch for permstable32, so don't
*/ */
prof->xmatch = rules->create_dfablob(&prof->xmatch_size, &prof->xmatch_len, prof->xmatch_perms_table, parseopts, false, false, false); prof->xmatch = rules->create_dfablob(&prof->xmatch_size, &prof->xmatch_len, prof->xmatch_perms_table, parseopts, false, false);
delete rules; delete rules;
if (!prof->xmatch) if (!prof->xmatch)
return false; return false;
@ -785,28 +785,17 @@ int process_profile_regex(Profile *prof)
/* under permstable32_v1 we weld file and policydb together, so /* under permstable32_v1 we weld file and policydb together, so
* don't create the file blob here * don't create the file blob here
*/ */
if (prof->dfa.rules->rule_count > 0 && prompt_compat_mode != PROMPT_COMPAT_PERMSV1) { if (prof->dfa.rules->rule_count > 0) {
int xmatch_len = 0; int xmatch_len = 0;
//fprintf(stderr, "Creating file DFA %d\n", kernel_supports_permstable32); //fprintf(stderr, "Creating file DFA %d\n", kernel_supports_permstable32);
prof->dfa.dfa = prof->dfa.rules->create_dfablob(&prof->dfa.size, prof->dfa.dfa = prof->dfa.rules->create_dfablob(&prof->dfa.size,
&xmatch_len, prof->dfa.perms_table, &xmatch_len, prof->dfa.perms_table,
parseopts, true, parseopts, true,
kernel_supports_permstable32, kernel_supports_permstable32);
prof->uses_prompt_rules);
delete prof->dfa.rules; delete prof->dfa.rules;
prof->dfa.rules = NULL; prof->dfa.rules = NULL;
if (!prof->dfa.dfa) if (!prof->dfa.dfa)
goto out; goto out;
/*
if (prof->dfa_size == 0) {
PERROR(_("profile %s: has merged rules (%s) with "
"multiple x modifiers\n"),
prof->name, (char *) prof->dfa);
free(prof->dfa);
prof->dfa = NULL;
goto out;
}
*/
} }
error = 0; error = 0;
@ -1081,7 +1070,6 @@ static const char *mediates_ns = CLASS_STR(AA_CLASS_NS);
static const char *mediates_posix_mqueue = CLASS_STR(AA_CLASS_POSIX_MQUEUE); static const char *mediates_posix_mqueue = CLASS_STR(AA_CLASS_POSIX_MQUEUE);
static const char *mediates_sysv_mqueue = CLASS_STR(AA_CLASS_SYSV_MQUEUE); static const char *mediates_sysv_mqueue = CLASS_STR(AA_CLASS_SYSV_MQUEUE);
static const char *mediates_io_uring = CLASS_STR(AA_CLASS_IO_URING); static const char *mediates_io_uring = CLASS_STR(AA_CLASS_IO_URING);
static const char *deny_file = ".*";
/* Set the mediates priority to the maximum possible. This is to help /* Set the mediates priority to the maximum possible. This is to help
* ensure that the mediates information is not wiped out by a rule * ensure that the mediates information is not wiped out by a rule
@ -1164,44 +1152,13 @@ int process_profile_policydb(Profile *prof)
goto out; goto out;
} }
if (prompt_compat_mode == PROMPT_COMPAT_PERMSV1) { if (prof->policy.rules->rule_count > 0) {
// MUST have file and policy
// This requires file rule processing happen first
if (!prof->dfa.rules->rule_count) {
// add null dfa
if (!prof->dfa.rules->add_rule(deny_file, 0, RULE_DENY, AA_MAY_READ, 0, parseopts))
goto out;
}
if (!prof->policy.rules->rule_count) {
if (!prof->policy.rules->add_rule(mediates_file, 0, RULE_DENY, AA_MAY_READ, 0, parseopts))
goto out;
}
int xmatch_len = 0;
prof->policy.dfa = prof->policy.rules->create_welded_dfablob(
prof->dfa.rules,
&prof->policy.size,
&xmatch_len,
&prof->policy.file_start,
prof->policy.perms_table, parseopts,
kernel_supports_permstable32_v1,
prof->uses_prompt_rules);
delete prof->policy.rules;
delete prof->dfa.rules;
prof->policy.rules = NULL;
prof->dfa.rules = NULL;
if (!prof->policy.dfa)
goto out;
} else if (prof->policy.rules->rule_count > 0 &&
// yes not needed as covered above, just making sure
// this doesn't get messed up in the future
prompt_compat_mode != PROMPT_COMPAT_PERMSV1) {
int xmatch_len = 0; int xmatch_len = 0;
prof->policy.dfa = prof->policy.rules->create_dfablob(&prof->policy.size, prof->policy.dfa = prof->policy.rules->create_dfablob(&prof->policy.size,
&xmatch_len, &xmatch_len,
prof->policy.perms_table, prof->policy.perms_table,
parseopts, false, parseopts, false,
kernel_supports_permstable32, kernel_supports_permstable32);
prof->uses_prompt_rules);
delete prof->policy.rules; delete prof->policy.rules;
prof->policy.rules = NULL; prof->policy.rules = NULL;

View File

@ -28,9 +28,7 @@
#define PROMPT_COMPAT_UNKNOWN 0 #define PROMPT_COMPAT_UNKNOWN 0
#define PROMPT_COMPAT_IGNORE 1 #define PROMPT_COMPAT_IGNORE 1
#define PROMPT_COMPAT_PERMSV2 2 #define PROMPT_COMPAT_PERMSV2 2
#define PROMPT_COMPAT_DEV 3
#define PROMPT_COMPAT_FLAG 4 #define PROMPT_COMPAT_FLAG 4
#define PROMPT_COMPAT_PERMSV1 5
class Profile; class Profile;