[apparmor] [patch 15/24] Add the ability to mediate signals.
john.johansen at canonical.com
john.johansen at canonical.com
Fri Mar 7 17:31:36 UTC 2014
Add signal rules and make sure the parser encodes support for them
if the supported feature set reports supporting them.
The current format of the signal rule is
[audit] [deny] signal [<signal_perms>] [<signal_set>] <target_profile>,
signal_perm := 'send'|'receive'|'r'|'w'|'rw'
signal_perms := <signal_perm> | '(' <signal_perm> ([,]<signal_perm>)* ')'
signal := ("hup"|"int"|"quit"|"ill"|"trap"|"abrt"|"bus"|"fpe"|"kill"|
"usr1"|"segv"|"usr2"|"pipe"|"alrm"|"term"|"tkflt"|"chld"|
"cont"|"stop"|"stp"|"ttin"|"ttou"|"urg"|"xcpu"|"xfsz"|"vtalrm"|
"prof"|"winch"|"io"|"pwr"|"sys"|"emt"|"exists")
signal_set := set=<signal> | '(' <signal> ([,]<signal>)* ')'
it does not currently follow the peer=() format, and there is some question
as to whether it should or not. Input welcome.
---
parser/Makefile | 8 -
parser/parser.h | 5
parser/parser_common.c | 1
parser/parser_lex.l | 22 ++-
parser/parser_main.c | 2
parser/parser_misc.c | 1
parser/parser_regex.c | 7 -
parser/parser_yacc.y | 68 +++++++++++
parser/policydb.h | 1
parser/signal.c | 301 +++++++++++++++++++++++++++++++++++++++++++++++++
parser/signal.h | 58 +++++++++
11 files changed, 462 insertions(+), 12 deletions(-)
--- 2.9-test.orig/parser/Makefile
+++ 2.9-test/parser/Makefile
@@ -79,8 +79,9 @@
SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \
parser_main.c parser_misc.c parser_merge.c parser_symtab.c \
parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \
- parser_alias.c mount.c dbus.c lib.c profile.cc rule.c
-HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h rule.h
+ parser_alias.c mount.c dbus.c lib.c profile.cc rule.c signal.c
+HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \
+ rule.h signal.h
TOOLS = apparmor_parser
OBJECTS = $(SRCS:.c=.o)
@@ -239,6 +240,9 @@
dbus.o: dbus.c dbus.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H)
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
+signal.o: signal.c signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H)
+ $(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
+
profile.o: profile.cc profile.h parser.h
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
--- 2.9-test.orig/parser/parser.h
+++ 2.9-test/parser/parser.h
@@ -300,6 +300,7 @@
extern int kernel_supports_policydb;
extern int kernel_supports_mount;
extern int kernel_supports_dbus;
+extern int kernel_supports_signal;
extern int conf_verbose;
extern int conf_quiet;
extern int names_only;
@@ -331,7 +332,9 @@
extern const char *basedir;
/* parser_regex.c */
-extern const char *default_match_pattern;
+#define default_match_pattern "[^\\000]*"
+#define anyone_match_pattern "[^\\000]+"
+
extern pattern_t convert_aaregex_to_pcre(const char *aare, int anchor,
std::string& pcre, int *first_re_pos);
extern int build_list_val_expr(std::string& buffer, struct value_list *list);
--- 2.9-test.orig/parser/parser_common.c
+++ 2.9-test/parser/parser_common.c
@@ -70,6 +70,7 @@
int kernel_supports_policydb = 0; /* kernel supports new policydb */
int kernel_supports_mount = 0; /* kernel supports mount rules */
int kernel_supports_dbus = 0; /* kernel supports dbus rules */
+int kernel_supports_signal = 0; /* kernel supports signal rules */
int conf_verbose = 0;
int conf_quiet = 0;
int names_only = 0;
--- 2.9-test.orig/parser/parser_lex.l
+++ 2.9-test/parser/parser_lex.l
@@ -253,6 +253,7 @@
%x RLIMIT_MODE
%x MOUNT_MODE
%x DBUS_MODE
+%x SIGNAL_MODE
%x CHANGE_PROFILE_MODE
%x INCLUDE
@@ -267,7 +268,7 @@
}
%}
-<INITIAL,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE>{
+<INITIAL,INCLUDE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
}
@@ -293,7 +294,7 @@
yyterminate();
}
-<INITIAL,MOUNT_MODE,DBUS_MODE>{
+<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
{VARIABLE_NAME}/{WS}*= {
/* we match to the = in the lexer so that we can switch scanner
* state. By the time the parser see the = it may be too late
@@ -462,12 +463,15 @@
}
<DBUS_MODE>{
+ bind { RETURN_TOKEN(TOK_BIND); }
+ eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); }
+}
+
+<DBUS_MODE,SIGNAL_MODE>{
send { RETURN_TOKEN(TOK_SEND); }
receive { RETURN_TOKEN(TOK_RECEIVE); }
- bind { RETURN_TOKEN(TOK_BIND); }
read { RETURN_TOKEN(TOK_READ); }
write { RETURN_TOKEN(TOK_WRITE); }
- eavesdrop { RETURN_TOKEN(TOK_EAVESDROP); }
{OPEN_PAREN} {
yy_push_state(LIST_VAL_MODE);
RETURN_TOKEN(TOK_OPENPAREN);
@@ -478,7 +482,7 @@
}
}
-<MOUNT_MODE,DBUS_MODE>{
+<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
@@ -567,13 +571,16 @@
case TOK_DBUS:
state = DBUS_MODE;
break;
+ case TOK_SIGNAL:
+ state = SIGNAL_MODE;
+ break;
default: /* nothing */
break;
}
PUSH_AND_RETURN(state, token);
}
-<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE>{
+<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
{END_OF_RULE} {
if (YY_START != INITIAL)
yy_pop_state();
@@ -586,7 +593,7 @@
}
}
-<INITIAL,SUB_ID,SUB_VALUE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,MOUNT_MODE,DBUS_MODE>{
+<INITIAL,SUB_ID,SUB_VALUE,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,ASSIGN_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
[^\n] {
DUMP_PREPROCESS;
/* Something we didn't expect */
@@ -613,6 +620,7 @@
STATE_TABLE_ENT(RLIMIT_MODE),
STATE_TABLE_ENT(MOUNT_MODE),
STATE_TABLE_ENT(DBUS_MODE),
+ STATE_TABLE_ENT(SIGNAL_MODE),
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
STATE_TABLE_ENT(INCLUDE),
};
--- 2.9-test.orig/parser/parser_main.c
+++ 2.9-test/parser/parser_main.c
@@ -847,6 +847,8 @@
kernel_supports_mount = 1;
if (strstr(features_string, "dbus"))
kernel_supports_dbus = 1;
+ if (strstr(features_string, "signal"))
+ kernel_supports_signal = 1;
}
int process_binary(int option, const char *profilename)
--- 2.9-test.orig/parser/parser_misc.c
+++ 2.9-test/parser/parser_misc.c
@@ -142,6 +142,7 @@
{"pivot_root", TOK_PIVOTROOT},
{"in", TOK_IN},
{"dbus", TOK_DBUS},
+ {"signal", TOK_SIGNAL},
{"send", TOK_SEND},
{"receive", TOK_RECEIVE},
{"bind", TOK_BIND},
--- 2.9-test.orig/parser/parser_regex.c
+++ 2.9-test/parser/parser_regex.c
@@ -43,8 +43,6 @@
e_parse_error,
};
-/* match any char except \000 0 or more times */
-const char *default_match_pattern = "[^\\000]*";
/* Filters out multiple slashes (except if the first two are slashes,
* that's a distinct namespace in linux) and trailing slashes.
@@ -675,6 +673,7 @@
static const char *mediates_file = CLASS_STR(AA_CLASS_FILE);
static const char *mediates_mount = CLASS_STR(AA_CLASS_MOUNT);
static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS);
+static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL);
int process_profile_policydb(Profile *prof)
{
@@ -701,6 +700,10 @@
if (kernel_supports_dbus &&
!prof->policy.rules->add_rule(mediates_dbus, 0, AA_MAY_READ, 0, dfaflags))
goto out;
+ if (kernel_supports_signal &&
+ !prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags))
+ goto out;
+
if (prof->policy.rules->rule_count > 0) {
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags);
delete prof->policy.rules;
--- 2.9-test.orig/parser/parser_yacc.y
+++ 2.9-test/parser/parser_yacc.y
@@ -28,6 +28,8 @@
#include <fcntl.h>
#include <libintl.h>
#include <sys/apparmor.h>
+
+#include <iostream>
#define _(s) gettext(s)
/* #define DEBUG */
@@ -128,6 +130,7 @@
%token TOK_PIVOTROOT
%token TOK_IN
%token TOK_DBUS
+%token TOK_SIGNAL
%token TOK_SEND
%token TOK_RECEIVE
%token TOK_BIND
@@ -166,6 +169,7 @@
#include "profile.h"
#include "mount.h"
#include "dbus.h"
+ #include "signal.h"
}
%union {
@@ -179,6 +183,7 @@
mnt_rule *mnt_entry;
dbus_rule *dbus_entry;
+ signal_rule *signal_entry;
flagvals flags;
int fmode;
@@ -241,6 +246,10 @@
%type <fmode> dbus_perms
%type <fmode> opt_dbus_perm
%type <dbus_entry> dbus_rule
+%type <fmode> signal_perm
+%type <fmode> signal_perms
+%type <fmode> opt_signal_perm
+%type <signal_entry> signal_rule
%type <transition> opt_named_transition
%type <boolean> opt_unsafe
%type <boolean> opt_file
@@ -698,6 +707,22 @@
$$ = $1;
}
+rules: rules opt_prefix signal_rule
+ {
+ if ($2.owner)
+ yyerror(_("owner prefix not allowed on signal rules"));
+ if ($2.deny && $2.audit) {
+ $3->deny = 1;
+ } else if ($2.deny) {
+ $3->deny = 1;
+ $3->audit = $3->mode;
+ } else if ($2.audit) {
+ $3->audit = $3->mode;
+ }
+ $1->rule_ents.push_back($3);
+ $$ = $1;
+ }
+
rules: rules change_profile
{
PDEBUG("matched: rules change_profile\n");
@@ -1214,6 +1239,49 @@
$$ = ent;
}
+signal_perm: TOK_VALUE
+ {
+ if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0)
+ $$ = AA_MAY_SEND;
+ else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
+ $$ = AA_MAY_RECEIVE;
+ else if ($1) {
+ parse_signal_mode($1, &$$, 1);
+ } else
+ $$ = 0;
+
+ if ($1)
+ free($1);
+ }
+ | TOK_SEND { $$ = AA_MAY_SEND; }
+ | TOK_RECEIVE { $$ = AA_MAY_RECEIVE; }
+ | TOK_READ { $$ = AA_MAY_RECEIVE; }
+ | TOK_WRITE { $$ = AA_MAY_SEND; }
+ | TOK_MODE
+ {
+ parse_signal_mode($1, &$$, 1);
+ free($1);
+ }
+
+signal_perms: { /* nothing */ $$ = 0; }
+ | signal_perms signal_perm { $$ = $1 | $2; }
+ | signal_perms TOK_COMMA signal_perm { $$ = $1 | $3; }
+
+opt_signal_perm: { /* nothing */ $$ = 0; }
+ | signal_perm { $$ = $1; }
+ | TOK_OPENPAREN signal_perms TOK_CLOSEPAREN { $$ = $2; }
+
+signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE
+ {
+ signal_rule *ent = new signal_rule($2, $3, NULL);
+ $$ = ent;
+ }
+ | TOK_SIGNAL opt_signal_perm opt_conds TOK_ID TOK_END_OF_RULE
+ {
+ signal_rule *ent = new signal_rule($2, $3, $4);
+ $$ = ent;
+ }
+
hat_start: TOK_CARET {}
| TOK_HAT {}
--- 2.9-test.orig/parser/policydb.h
+++ 2.9-test/parser/policydb.h
@@ -31,6 +31,7 @@
#define AA_CLASS_MOUNT 7
#define AA_CLASS_NS_DOMAIN 8
#define AA_CLASS_PTRACE 9
+#define AA_CLASS_SIGNAL 10
#define AA_CLASS_LABEL 16
--- /dev/null
+++ 2.9-test/parser/signal.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2014
+ * Canonical, Ltd. (All rights reserved)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Novell, Inc. or Canonical
+ * Ltd.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/apparmor.h>
+
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <map>
+
+#include "parser.h"
+#include "profile.h"
+#include "parser_yacc.h"
+#include "signal.h"
+
+#define MAXMAPPED_SIG 35
+#define MINRT_SIG 128 /* base of RT sigs */
+#define MAXRT_SIG 32 /* Max RT above MINRT_SIG */
+
+/* Signal names mapped to and internal ordering */
+static struct signal_map { const char *name; int num; } signal_map[] = {
+ {"hup", 1},
+ {"int", 2},
+ {"quit", 3},
+ {"ill", 4},
+ {"trap", 5},
+ {"abrt", 6},
+ {"bus", 7},
+ {"fpe", 8},
+ {"kill", 9},
+ {"usr1", 10},
+ {"segv", 11},
+ {"usr2", 12},
+ {"pipe", 13},
+ {"alrm", 14},
+ {"term", 15},
+ {"tkflt", 16},
+ {"chld", 17},
+ {"cont", 18},
+ {"stop", 19},
+ {"stp", 20},
+ {"ttin", 21},
+ {"ttou", 22},
+ {"urg", 23},
+ {"xcpu", 24},
+ {"xfsz", 25},
+ {"vtalrm", 26},
+ {"prof", 27},
+ {"winch", 28},
+ {"io", 29},
+ {"pwr", 30},
+ {"sys", 31},
+ {"emt", 32},
+ {"exists", 35},
+
+ /* terminate */
+ {NULL, 0}
+};
+
+/* this table is ordered post sig_map[sig] mapping */
+static const char *const sig_names[MAXMAPPED_SIG + 1] = {
+ "unknown",
+ "hup",
+ "int",
+ "quit",
+ "ill",
+ "trap",
+ "abrt",
+ "bus",
+ "fpe",
+ "kill",
+ "usr1",
+ "segv",
+ "usr2",
+ "pipe",
+ "alrm",
+ "term",
+ "tkflt",
+ "chld",
+ "cont",
+ "stop",
+ "stp",
+ "ttin",
+ "ttou",
+ "urg",
+ "xcpu",
+ "xfsz",
+ "vtalrm",
+ "prof",
+ "winch",
+ "io",
+ "pwr",
+ "sys",
+ "emt",
+ "lost",
+ "unused",
+
+ "exists", /* always last existance test mapped to MAXMAPPED_SIG */
+};
+
+
+int parse_signal_mode(const char *str_mode, int *mode, int fail)
+{
+ return parse_X_mode("signal", AA_VALID_SIGNAL_PERMS, str_mode, mode, fail);
+}
+
+static int find_signal_mapping(const char *sig)
+{
+ if (strncmp("rtmin+", sig, 6) == 0) {
+ char *end;
+ unsigned long n = strtoul(sig + 6, &end, 10);
+ if (end == sig || n > MAXRT_SIG)
+ return -1;
+ return MINRT_SIG + n;
+ } else {
+ for (int i = 0; signal_map[i].name; i++) {
+ if (strcmp(sig, signal_map[i].name) == 0)
+ return signal_map[i].num;
+ }
+ }
+ return -1;
+}
+
+void signal_rule::extract_sigs(struct value_list **list)
+{
+ struct value_list *entry, *tmp, *prev = NULL;
+ list_for_each_safe(*list, entry, tmp) {
+ int i = find_signal_mapping(entry->value);
+ if (i != -1) {
+ signals.insert(i);
+ list_remove_at(*list, prev, entry);
+ free_value_list(entry);
+ } else {
+ yyerror("unknown signal \"%s\"\n", entry->value);
+ prev = entry;
+ }
+ }
+}
+
+void signal_rule::move_conditionals(struct cond_entry *conds)
+{
+ struct cond_entry *cond_ent;
+
+ list_for_each(conds, cond_ent) {
+ /* for now disallow keyword 'in' (list) */
+ if (!cond_ent->eq)
+ yyerror("keyword \"in\" is not allowed in signal rules\n");
+ /* use alternation instead????
+ * set=(kill,usr1) vs. set={kill,usr1}
+ */
+ if (strcmp(cond_ent->name, "set") == 0) {
+ extract_sigs(&cond_ent->vals);
+ } else {
+ yyerror("invalid signal rule conditional \"%s\"\n",
+ cond_ent->name);
+ }
+ }
+}
+
+signal_rule::signal_rule(int mode_p, struct cond_entry *conds,
+ char *peer):
+ signals(), peer_label(peer), audit(0), deny(0)
+{
+ if (mode_p) {
+ mode = mode_p;
+ if (mode & ~AA_VALID_SIGNAL_PERMS)
+ yyerror("mode contains invalid permission for signals\n");
+ } else {
+ mode = AA_VALID_SIGNAL_PERMS;
+ }
+
+ move_conditionals(conds);
+
+ free_cond_list(conds);
+}
+
+ostream &signal_rule::dump(ostream &os)
+{
+ if (audit)
+ os << "audit ";
+ if (deny)
+ os << "deny ";
+
+ os << "signal";
+
+ if (mode != AA_VALID_SIGNAL_PERMS) {
+ os << " (";
+
+ if (mode & AA_MAY_SEND)
+ os << "send ";
+ if (mode & AA_MAY_RECEIVE)
+ os << "receive ";
+ os << ")";
+ }
+
+ if (!signals.empty()) {
+ os << " set=(";
+ for (Signals::iterator i = signals.begin(); i != signals.end();
+ i++) {
+ if (i != signals.begin())
+ os << ", ";
+ if (*i < MINRT_SIG)
+ os << sig_names[*i];
+ else
+ os << "rtmin+" << (*i - MINRT_SIG);
+ }
+ os << ")";
+ }
+
+ if (peer_label)
+ os << " " << peer_label;
+
+ os << ",\n";
+
+ return os;
+}
+
+int signal_rule::expand_variables(void)
+{
+ return expand_entry_variables(&peer_label);
+}
+
+int signal_rule::gen_policy_re(Profile &prof)
+{
+ std::ostringstream buffer;
+ std::string buf;
+
+ pattern_t ptype;
+ int pos;
+
+ /* Currently do not generate the rules if the kernel doesn't support
+ * it. We may want to switch this so that a compile could be
+ * used for full support on kernels that don't support the feature
+ */
+ if (!kernel_supports_signal) {
+ pwarn("profile %s signal rules not enforced\n", prof.name);
+ return RULE_NOT_SUPPORTED;
+ }
+
+ if (signals.size() == 0) {
+ /* not conditional on signal set, so will generate a label
+ * rule as well
+ */
+ buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "\\x" << AA_CLASS_SIGNAL << "|";
+ }
+
+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_SIGNAL;
+
+ if (signals.size()) {
+ buffer << "[";
+ for (Signals::iterator i = signals.begin(); i != signals.end(); i++) {
+ buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << *i;
+ }
+ buffer << "]";
+ } else {
+ /* match any char */
+ buffer << ".";
+ }
+
+ if (signals.size() == 0) {
+ /* close alternation */
+ buffer << ")";
+ }
+ if (peer_label) {
+ ptype = convert_aaregex_to_pcre(peer_label, 0, buf, &pos);
+ if (ptype == ePatternInvalid)
+ goto fail;
+ buffer << buf;
+ } else {
+ buffer << anyone_match_pattern;
+ }
+
+ buf = buffer.str();
+ if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) {
+ if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
+ dfaflags))
+ goto fail;
+ }
+
+ return RULE_OK;
+
+fail:
+ return RULE_ERROR;
+}
--- /dev/null
+++ 2.9-test/parser/signal.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014
+ * Canonical, Ltd. (All rights reserved)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Novell, Inc. or Canonical
+ * Ltd.
+ */
+
+#ifndef __AA_SIGNAL_H
+#define __AA_SIGNAL_H
+
+#include "parser.h"
+#include "rule.h"
+#include "profile.h"
+
+
+#define AA_MAY_SEND (1 << 1)
+#define AA_MAY_RECEIVE (1 << 2)
+#define AA_VALID_SIGNAL_PERMS (AA_MAY_SEND | AA_MAY_RECEIVE)
+
+
+typedef set<int> Signals;
+
+int parse_signal_mode(const char *str_mode, int *mode, int fail);
+
+class signal_rule: public rule_t {
+ void extract_sigs(struct value_list **list);
+ void move_conditionals(struct cond_entry *conds);
+public:
+ Signals signals;
+ char *peer_label;
+ int mode;
+ int audit;
+ int deny;
+
+ signal_rule(int mode, struct cond_entry *conds, char *peer);
+ virtual ~signal_rule() {
+ signals.clear();
+ free(peer_label);
+ };
+
+ virtual ostream &dump(ostream &os);
+ virtual int expand_variables(void);
+ virtual int gen_policy_re(Profile &prof);
+ virtual void post_process(Profile &prof __unused) { };
+};
+
+#endif /* __AA_SIGNAL_H */
More information about the AppArmor
mailing list