parser: consolidate rule class handling into aa_class

Instead of having each rule individually handle the class info
introduce a class_rule_t into the hierarchy and consolidate.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2021-09-10 13:37:54 -07:00
parent 30206fc11e
commit a2d56c3c74
12 changed files with 100 additions and 33 deletions

View file

@ -140,7 +140,7 @@ ostream &af_rule::dump_peer(ostream &os)
ostream &af_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << af_name;
os << af_name();
dump_local(os);
if (has_peer_conds()) {
os << " peer=(";

View file

@ -25,6 +25,8 @@
#include "rule.h"
#define AF_ANY -1
enum cond_side { local_cond, peer_cond, either_cond };
struct supported_cond {
@ -37,7 +39,7 @@ struct supported_cond {
class af_rule: public perms_rule_t {
public:
std::string af_name;
int af;
char *sock_type;
int sock_type_n;
char *proto;
@ -45,10 +47,11 @@ public:
char *label;
char *peer_label;
af_rule(const char *name): af_name(name), sock_type(NULL),
af_rule(int f):
perms_rule_t(AA_CLASS_NET),
af(f), sock_type(NULL),
sock_type_n(-1), proto(NULL), proto_n(0), label(NULL),
peer_label(NULL)
{}
peer_label(NULL) { }
virtual ~af_rule()
{
@ -58,6 +61,11 @@ public:
free(peer_label);
};
const char *af_name(void) {
if (af != AF_ANY)
return net_find_af_name(af);
return "*";
}
bool cond_check(struct supported_cond *cond, struct cond_entry *ent,
bool peer, const char *rname);
int move_base_cond(struct cond_entry *conds, bool peer);

View file

@ -96,7 +96,7 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds)
}
unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode_p):
af_rule("unix"), addr(NULL), peer_addr(NULL)
af_rule(AF_UNIX), addr(NULL), peer_addr(NULL)
{
if (type_p != 0xffffffff) {
sock_type_n = type_p;
@ -111,7 +111,7 @@ unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode
unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds,
struct cond_entry *peer_conds):
af_rule("unix"), addr(NULL), peer_addr(NULL)
af_rule(AF_UNIX), addr(NULL), peer_addr(NULL)
{
move_conditionals(conds);
move_peer_conditionals(peer_conds);

View file

@ -68,7 +68,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds)
dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds,
struct cond_entry *peer_conds):
bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL)
perms_rule_t(AA_CLASS_DBUS), bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL)
{
int name_is_subject_cond = 0, message_rule = 0, service_rule = 0;
@ -121,10 +121,9 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds,
ostream &dbus_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << "dbus ( ";
class_rule_t::dump(os);
os << " ( ";
/* override default perms */
if (perms & AA_DBUS_SEND)
os << "send ";

View file

@ -468,6 +468,7 @@ static void process_one_option(struct cond_entry *&opts, unsigned int &flags,
mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p,
struct cond_entry *dst_conds unused, char *mnt_point_p,
perms_t perms_p):
perms_rule_t(AA_CLASS_MOUNT),
mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL),
flagsv(0), opt_flagsv(0)
{

View file

@ -87,6 +87,9 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds)
}
mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p):
// mqueue uses multiple classes, arbitrary choice to represent group
// withing the AST
perms_rule_t(AA_CLASS_POSIX_MQUEUE),
qtype(mqueue_unspecified), qname(qname_p), label(NULL)
{
move_conditionals(conds);
@ -115,19 +118,17 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_
ostream &mqueue_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << "mqueue ";
class_rule_t::dump(os);
// do we want to always put type out or leave it implied if there
// is a qname
if (qtype == mqueue_posix)
os << "type=posix";
os << " type=posix";
else if (qtype == mqueue_sysv)
os << "type=sysv";
os << " type=sysv";
if (perms != AA_VALID_MQUEUE_PERMS) {
os << "(";
os << " ( ";
if (perms & AA_MQUEUE_WRITE)
os << "write ";

View file

@ -32,13 +32,21 @@
#define AA_CLASS_NS_DOMAIN 8
#define AA_CLASS_PTRACE 9
#define AA_CLASS_SIGNAL 10
#define AA_CLASS_XMATCH 11
#define AA_CLASS_ENV 12
#define AA_CLASS_ARGV 13
#define AA_CLASS_NETV8 14
#define AA_CLASS_LABEL 16
#define AA_CLASS_POSIX_MQUEUE 17
#define AA_CLASS_SYSV_MQUEUE 18
#define AA_CLASS_MODULE 19
#define AA_CLASS_DISPLAY_LSM 20
#define AA_CLASS_NS 21
#define AA_CLASS_IO_URING 22
#define AA_CLASS_X 31
/* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */
#define AA_CLASS_X 33
extern const char *aa_class_table[];
#endif /* __AA_POLICYDB_H */

View file

@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds)
}
ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds):
peer_label(NULL)
perms_rule_t(AA_CLASS_PTRACE), peer_label(NULL)
{
if (perms_p) {
if (perms_p & ~AA_VALID_PTRACE_PERMS)
@ -64,9 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds):
ostream &ptrace_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << "ptrace";
class_rule_t::dump(os);
/* override default perm dump */
if (perms != AA_VALID_PTRACE_PERMS) {

View file

@ -19,6 +19,43 @@
#include "parser.h"
#include <iostream>
const char *aa_class_table[] = {
"nullcond",
"unknown",
"file",
"capability",
"network",
"rlimit",
"domain",
"mount",
"unknown8",
"ptrace",
"signal",
"xmatch",
"env",
"argv",
"network",
"unknown15",
"label",
"mqueue",
"mqueue",
"module",
"display_lsm",
"userns",
"io_uring",
"unknown23",
"unknown24",
"unknown25",
"unknown26",
"unknown27",
"unknown28",
"unknown29",
"unknown30",
"X",
"dbus",
NULL
};
std::ostream &operator<<(std::ostream &os, rule_t &rule)
{
return rule.dump(os);

View file

@ -190,9 +190,27 @@ public:
};
class perms_rule_t: public prefix_rule_t {
class class_rule_t: public prefix_rule_t {
public:
perms_rule_t(): perms(0) { };
int aa_class;
class_rule_t(int c) {
aa_class = c;
}
virtual ostream &dump(ostream &os) {
prefix_rule_t::dump(os);
os << aa_class_table[aa_class];
return os;
}
};
class perms_rule_t: public class_rule_t {
public:
perms_rule_t(int c): class_rule_t(c), perms(0) { };
/* defaut perms, override/mask off if none default used */
virtual ostream &dump(ostream &os) {

View file

@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds)
}
signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds):
signals(), peer_label(NULL)
perms_rule_t(AA_CLASS_SIGNAL), signals(), peer_label(NULL)
{
if (perms_p) {
perms = perms_p;
@ -191,9 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds):
ostream &signal_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << "signal";
class_rule_t::dump(os);
if (perms != AA_VALID_SIGNAL_PERMS) {
os << " (";

View file

@ -40,7 +40,8 @@ void userns_rule::move_conditionals(struct cond_entry *conds)
}
}
userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds)
userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds):
perms_rule_t(AA_CLASS_NS)
{
if (perms_p) {
if (perms_p & ~AA_VALID_USERNS_PERMS)
@ -58,13 +59,11 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds)
ostream &userns_rule::dump(ostream &os)
{
prefix_rule_t::dump(os);
os << "userns ";
class_rule_t::dump(os);
if (perms != AA_VALID_USERNS_PERMS) {
if (perms & AA_USERNS_CREATE)
os << "create ";
os << " create";
}
os << ",\n";