mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-28 21:07:56 +00:00
Add the ability to specify ptrace rules
ptrace rules currently take the form of ptrace [<ptrace_perms>] [<peer_profile_name>], ptrace_perm := read|trace|readby|tracedby ptrace_perms := ptrace_perm | '(' ptrace_perm+ ')' After having used the cross check (permission needed in both profiles) I am not sure it is correct for ptrace. Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
parent
559f0a72fa
commit
a1a7c78755
@ -80,9 +80,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_main.c parser_misc.c parser_merge.c parser_symtab.c \
|
||||||
parser_yacc.c parser_regex.c parser_variable.c parser_policy.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 common_optarg.c \
|
parser_alias.c mount.c dbus.c lib.c profile.cc rule.c common_optarg.c \
|
||||||
signal.c
|
signal.c ptrace.c
|
||||||
HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \
|
HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \
|
||||||
rule.h common_optarg.h signal.h
|
rule.h common_optarg.h signal.h ptrace.h
|
||||||
TOOLS = apparmor_parser
|
TOOLS = apparmor_parser
|
||||||
|
|
||||||
OBJECTS = $(SRCS:.c=.o)
|
OBJECTS = $(SRCS:.c=.o)
|
||||||
@ -248,6 +248,9 @@ dbus.o: dbus.c dbus.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H)
|
|||||||
signal.o: signal.c signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H)
|
signal.o: signal.c signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H)
|
||||||
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
ptrace.o: ptrace.c ptrace.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
|
profile.o: profile.cc profile.h parser.h
|
||||||
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
@ -305,6 +305,7 @@ extern int kernel_supports_diff_encode;
|
|||||||
extern int kernel_supports_mount;
|
extern int kernel_supports_mount;
|
||||||
extern int kernel_supports_dbus;
|
extern int kernel_supports_dbus;
|
||||||
extern int kernel_supports_signal;
|
extern int kernel_supports_signal;
|
||||||
|
extern int kernel_supports_ptrace;
|
||||||
extern int conf_verbose;
|
extern int conf_verbose;
|
||||||
extern int conf_quiet;
|
extern int conf_quiet;
|
||||||
extern int names_only;
|
extern int names_only;
|
||||||
|
@ -72,6 +72,7 @@ int kernel_supports_mount = 0; /* kernel supports mount rules */
|
|||||||
int kernel_supports_dbus = 0; /* kernel supports dbus rules */
|
int kernel_supports_dbus = 0; /* kernel supports dbus rules */
|
||||||
int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */
|
int kernel_supports_diff_encode = 0; /* kernel supports diff_encode */
|
||||||
int kernel_supports_signal = 0; /* kernel supports signal rules */
|
int kernel_supports_signal = 0; /* kernel supports signal rules */
|
||||||
|
int kernel_supports_ptrace = 0; /* kernel supports ptrace rules */
|
||||||
int conf_verbose = 0;
|
int conf_verbose = 0;
|
||||||
int conf_quiet = 0;
|
int conf_quiet = 0;
|
||||||
int names_only = 0;
|
int names_only = 0;
|
||||||
|
@ -260,6 +260,7 @@ LT_EQUAL <=
|
|||||||
%x MOUNT_MODE
|
%x MOUNT_MODE
|
||||||
%x DBUS_MODE
|
%x DBUS_MODE
|
||||||
%x SIGNAL_MODE
|
%x SIGNAL_MODE
|
||||||
|
%x PTRACE_MODE
|
||||||
%x CHANGE_PROFILE_MODE
|
%x CHANGE_PROFILE_MODE
|
||||||
%x INCLUDE
|
%x INCLUDE
|
||||||
|
|
||||||
@ -274,7 +275,7 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
<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>{
|
<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,PTRACE_MODE>{
|
||||||
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +301,7 @@ LT_EQUAL <=
|
|||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
|
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE>{
|
||||||
peer/{WS}*={WS}*\( {
|
peer/{WS}*={WS}*\( {
|
||||||
/* we match to the = in the lexer so that we can switch scanner
|
/* 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
|
* state. By the time the parser see the = it may be too late
|
||||||
@ -478,6 +479,15 @@ LT_EQUAL <=
|
|||||||
<DBUS_MODE,SIGNAL_MODE>{
|
<DBUS_MODE,SIGNAL_MODE>{
|
||||||
send { RETURN_TOKEN(TOK_SEND); }
|
send { RETURN_TOKEN(TOK_SEND); }
|
||||||
receive { RETURN_TOKEN(TOK_RECEIVE); }
|
receive { RETURN_TOKEN(TOK_RECEIVE); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<PTRACE_MODE>{
|
||||||
|
trace { RETURN_TOKEN(TOK_TRACE); }
|
||||||
|
readby { RETURN_TOKEN(TOK_READBY); }
|
||||||
|
tracedby { RETURN_TOKEN(TOK_TRACEDBY); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<DBUS_MODE,SIGNAL_MODE,PTRACE_MODE>{
|
||||||
read { RETURN_TOKEN(TOK_READ); }
|
read { RETURN_TOKEN(TOK_READ); }
|
||||||
write { RETURN_TOKEN(TOK_WRITE); }
|
write { RETURN_TOKEN(TOK_WRITE); }
|
||||||
{OPEN_PAREN} {
|
{OPEN_PAREN} {
|
||||||
@ -489,9 +499,11 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
|
<MOUNT_MODE>{
|
||||||
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
|
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE>{
|
||||||
({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
|
({IDS_NOEQ}|{PATHNAME}|{QUOTED_ID}) {
|
||||||
yylval.id = processid(yytext, yyleng);
|
yylval.id = processid(yytext, yyleng);
|
||||||
RETURN_TOKEN(TOK_ID);
|
RETURN_TOKEN(TOK_ID);
|
||||||
@ -581,13 +593,15 @@ LT_EQUAL <=
|
|||||||
case TOK_SIGNAL:
|
case TOK_SIGNAL:
|
||||||
state = SIGNAL_MODE;
|
state = SIGNAL_MODE;
|
||||||
break;
|
break;
|
||||||
|
case TOK_PTRACE:
|
||||||
|
state = PTRACE_MODE;
|
||||||
default: /* nothing */
|
default: /* nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PUSH_AND_RETURN(state, token);
|
PUSH_AND_RETURN(state, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
|
<INITIAL,NETWORK_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE>{
|
||||||
{END_OF_RULE} {
|
{END_OF_RULE} {
|
||||||
if (YY_START != INITIAL)
|
if (YY_START != INITIAL)
|
||||||
POP_NODUMP();
|
POP_NODUMP();
|
||||||
@ -600,7 +614,7 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<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>{
|
<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,PTRACE_MODE>{
|
||||||
[^\n] {
|
[^\n] {
|
||||||
DUMP_PREPROCESS;
|
DUMP_PREPROCESS;
|
||||||
/* Something we didn't expect */
|
/* Something we didn't expect */
|
||||||
@ -628,6 +642,7 @@ unordered_map<int, string> state_names = {
|
|||||||
STATE_TABLE_ENT(MOUNT_MODE),
|
STATE_TABLE_ENT(MOUNT_MODE),
|
||||||
STATE_TABLE_ENT(DBUS_MODE),
|
STATE_TABLE_ENT(DBUS_MODE),
|
||||||
STATE_TABLE_ENT(SIGNAL_MODE),
|
STATE_TABLE_ENT(SIGNAL_MODE),
|
||||||
|
STATE_TABLE_ENT(PTRACE_MODE),
|
||||||
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
|
STATE_TABLE_ENT(CHANGE_PROFILE_MODE),
|
||||||
STATE_TABLE_ENT(INCLUDE),
|
STATE_TABLE_ENT(INCLUDE),
|
||||||
};
|
};
|
||||||
|
@ -697,6 +697,8 @@ static void set_supported_features(void) {
|
|||||||
kernel_supports_dbus = 1;
|
kernel_supports_dbus = 1;
|
||||||
if (strstr(features_string, "signal"))
|
if (strstr(features_string, "signal"))
|
||||||
kernel_supports_signal = 1;
|
kernel_supports_signal = 1;
|
||||||
|
if (strstr(features_string, "ptrace {"))
|
||||||
|
kernel_supports_ptrace = 1;
|
||||||
if (strstr(features_string, "diff_encode"))
|
if (strstr(features_string, "diff_encode"))
|
||||||
kernel_supports_diff_encode = 1;
|
kernel_supports_diff_encode = 1;
|
||||||
else if (dfaflags & DFA_CONTROL_DIFF_ENCODE)
|
else if (dfaflags & DFA_CONTROL_DIFF_ENCODE)
|
||||||
|
@ -151,6 +151,9 @@ static struct keyword_table keyword_table[] = {
|
|||||||
{"write", TOK_WRITE},
|
{"write", TOK_WRITE},
|
||||||
{"eavesdrop", TOK_EAVESDROP},
|
{"eavesdrop", TOK_EAVESDROP},
|
||||||
{"peer", TOK_PEER},
|
{"peer", TOK_PEER},
|
||||||
|
{"trace", TOK_TRACE},
|
||||||
|
{"tracedby", TOK_TRACEDBY},
|
||||||
|
{"readby", TOK_READBY},
|
||||||
|
|
||||||
/* terminate */
|
/* terminate */
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
|
@ -674,6 +674,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_mount = CLASS_STR(AA_CLASS_MOUNT);
|
||||||
static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS);
|
static const char *mediates_dbus = CLASS_STR(AA_CLASS_DBUS);
|
||||||
static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL);
|
static const char *mediates_signal = CLASS_STR(AA_CLASS_SIGNAL);
|
||||||
|
static const char *mediates_ptrace = CLASS_STR(AA_CLASS_PTRACE);
|
||||||
|
|
||||||
int process_profile_policydb(Profile *prof)
|
int process_profile_policydb(Profile *prof)
|
||||||
{
|
{
|
||||||
@ -703,6 +704,9 @@ int process_profile_policydb(Profile *prof)
|
|||||||
if (kernel_supports_signal &&
|
if (kernel_supports_signal &&
|
||||||
!prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags))
|
!prof->policy.rules->add_rule(mediates_signal, 0, AA_MAY_READ, 0, dfaflags))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (kernel_supports_ptrace &&
|
||||||
|
!prof->policy.rules->add_rule(mediates_ptrace, 0, AA_MAY_READ, 0, dfaflags))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (prof->policy.rules->rule_count > 0) {
|
if (prof->policy.rules->rule_count > 0) {
|
||||||
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags);
|
prof->policy.dfa = prof->policy.rules->create_dfa(&prof->policy.size, dfaflags);
|
||||||
|
@ -138,6 +138,9 @@ void add_local_entry(Profile *prof);
|
|||||||
%token TOK_WRITE
|
%token TOK_WRITE
|
||||||
%token TOK_EAVESDROP
|
%token TOK_EAVESDROP
|
||||||
%token TOK_PEER
|
%token TOK_PEER
|
||||||
|
%token TOK_TRACE
|
||||||
|
%token TOK_TRACEDBY
|
||||||
|
%token TOK_READBY
|
||||||
|
|
||||||
/* rlimits */
|
/* rlimits */
|
||||||
%token TOK_RLIMIT
|
%token TOK_RLIMIT
|
||||||
@ -171,6 +174,7 @@ void add_local_entry(Profile *prof);
|
|||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "signal.h"
|
#include "signal.h"
|
||||||
|
#include "ptrace.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
@ -185,6 +189,7 @@ void add_local_entry(Profile *prof);
|
|||||||
mnt_rule *mnt_entry;
|
mnt_rule *mnt_entry;
|
||||||
dbus_rule *dbus_entry;
|
dbus_rule *dbus_entry;
|
||||||
signal_rule *signal_entry;
|
signal_rule *signal_entry;
|
||||||
|
ptrace_rule *ptrace_entry;
|
||||||
|
|
||||||
flagvals flags;
|
flagvals flags;
|
||||||
int fmode;
|
int fmode;
|
||||||
@ -252,6 +257,10 @@ void add_local_entry(Profile *prof);
|
|||||||
%type <fmode> signal_perms
|
%type <fmode> signal_perms
|
||||||
%type <fmode> opt_signal_perm
|
%type <fmode> opt_signal_perm
|
||||||
%type <signal_entry> signal_rule
|
%type <signal_entry> signal_rule
|
||||||
|
%type <fmode> ptrace_perm
|
||||||
|
%type <fmode> ptrace_perms
|
||||||
|
%type <fmode> opt_ptrace_perm
|
||||||
|
%type <ptrace_entry> ptrace_rule
|
||||||
%type <transition> opt_named_transition
|
%type <transition> opt_named_transition
|
||||||
%type <boolean> opt_unsafe
|
%type <boolean> opt_unsafe
|
||||||
%type <boolean> opt_file
|
%type <boolean> opt_file
|
||||||
@ -725,6 +734,22 @@ rules: rules opt_prefix signal_rule
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rules: rules opt_prefix ptrace_rule
|
||||||
|
{
|
||||||
|
if ($2.owner)
|
||||||
|
yyerror(_("owner prefix not allowed on ptrace 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
|
rules: rules change_profile
|
||||||
{
|
{
|
||||||
PDEBUG("matched: rules change_profile\n");
|
PDEBUG("matched: rules change_profile\n");
|
||||||
@ -1285,6 +1310,54 @@ signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE
|
|||||||
$$ = ent;
|
$$ = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ptrace_perm: TOK_VALUE
|
||||||
|
{
|
||||||
|
if (strcmp($1, "trace") == 0 || strcmp($1, "write") == 0)
|
||||||
|
$$ = AA_MAY_TRACE;
|
||||||
|
else if (strcmp($1, "read") == 0)
|
||||||
|
$$ = AA_MAY_READ;
|
||||||
|
else if (strcmp($1, "tracedby") == 0)
|
||||||
|
$$ = AA_MAY_TRACEDBY;
|
||||||
|
else if (strcmp($1, "readby") == 0)
|
||||||
|
$$ = AA_MAY_READBY;
|
||||||
|
else if ($1)
|
||||||
|
parse_ptrace_mode($1, &$$, 1);
|
||||||
|
else
|
||||||
|
$$ = 0;
|
||||||
|
|
||||||
|
if ($1)
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
|
| TOK_TRACE { $$ = AA_MAY_TRACE; }
|
||||||
|
| TOK_TRACEDBY { $$ = AA_MAY_TRACEDBY; }
|
||||||
|
| TOK_READ { $$ = AA_MAY_READ; }
|
||||||
|
| TOK_WRITE { $$ = AA_MAY_TRACE; }
|
||||||
|
| TOK_READBY { $$ = AA_MAY_READBY; }
|
||||||
|
| TOK_MODE
|
||||||
|
{
|
||||||
|
parse_ptrace_mode($1, &$$, 1);
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrace_perms: { /* nothing */ $$ = 0; }
|
||||||
|
| ptrace_perms ptrace_perm { $$ = $1 | $2; }
|
||||||
|
| ptrace_perms TOK_COMMA ptrace_perm { $$ = $1 | $3; }
|
||||||
|
|
||||||
|
opt_ptrace_perm: { /* nothing */ $$ = 0; }
|
||||||
|
| ptrace_perm { $$ = $1; }
|
||||||
|
| TOK_OPENPAREN ptrace_perms TOK_CLOSEPAREN { $$ = $2; }
|
||||||
|
|
||||||
|
ptrace_rule: TOK_PTRACE opt_ptrace_perm opt_conds TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
ptrace_rule *ent = new ptrace_rule($2, $3, NULL);
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
| TOK_PTRACE opt_ptrace_perm opt_conds TOK_ID TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
ptrace_rule *ent = new ptrace_rule($2, $3, $4);
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
|
||||||
hat_start: TOK_CARET {}
|
hat_start: TOK_CARET {}
|
||||||
| TOK_HAT {}
|
| TOK_HAT {}
|
||||||
|
|
||||||
|
159
parser/ptrace.c
Normal file
159
parser/ptrace.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* 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 "parser.h"
|
||||||
|
#include "profile.h"
|
||||||
|
#include "ptrace.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
int parse_ptrace_mode(const char *str_mode, int *mode, int fail)
|
||||||
|
{
|
||||||
|
return parse_X_mode("ptrace", AA_VALID_PTRACE_PERMS, str_mode, mode, fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ptrace_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 ptrace rules\n");
|
||||||
|
|
||||||
|
/* no valid conditionals atm */
|
||||||
|
yyerror("invalid ptrace rule conditional \"%s\"\n",
|
||||||
|
cond_ent->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds, char *peer):
|
||||||
|
peer_label(peer), audit(0), deny(0)
|
||||||
|
{
|
||||||
|
if (mode_p) {
|
||||||
|
if (mode_p & ~AA_VALID_PTRACE_PERMS)
|
||||||
|
yyerror("mode contains invalid permissions for ptrace\n");
|
||||||
|
mode = mode_p;
|
||||||
|
} else {
|
||||||
|
mode = AA_VALID_PTRACE_PERMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
move_conditionals(conds);
|
||||||
|
free_cond_list(conds);
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream &ptrace_rule::dump(ostream &os)
|
||||||
|
{
|
||||||
|
if (audit)
|
||||||
|
os << "audit ";
|
||||||
|
if (deny)
|
||||||
|
os << "deny ";
|
||||||
|
|
||||||
|
os << "ptrace";
|
||||||
|
|
||||||
|
if (mode != AA_VALID_PTRACE_PERMS) {
|
||||||
|
os << " (";
|
||||||
|
|
||||||
|
if (mode & AA_MAY_READ)
|
||||||
|
os << "read ";
|
||||||
|
if (mode & AA_MAY_READBY)
|
||||||
|
os << "readby ";
|
||||||
|
if (mode & AA_MAY_TRACE)
|
||||||
|
os << "trace ";
|
||||||
|
if (mode & AA_MAY_TRACEDBY)
|
||||||
|
os << "tracedby ";
|
||||||
|
os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer_label)
|
||||||
|
os << " " << peer_label;
|
||||||
|
|
||||||
|
os << ",\n";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ptrace_rule::expand_variables(void)
|
||||||
|
{
|
||||||
|
return expand_entry_variables(&peer_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do we want to warn once/profile or just once per compile?? */
|
||||||
|
static void warn_once(const char *name)
|
||||||
|
{
|
||||||
|
static const char *warned_name = NULL;
|
||||||
|
|
||||||
|
if (warned_name != name) {
|
||||||
|
cerr << "Warning from profile " << name << " (";
|
||||||
|
if (current_filename)
|
||||||
|
cerr << current_filename;
|
||||||
|
else
|
||||||
|
cerr << "stdin";
|
||||||
|
cerr << ") ptrace rules not enforced\n";
|
||||||
|
warned_name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ptrace_rule::gen_policy_re(Profile &prof)
|
||||||
|
{
|
||||||
|
std::ostringstream buffer;
|
||||||
|
std::string buf;
|
||||||
|
|
||||||
|
pattern_t ptype;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
/* ?? do we want to generate the rules in the policy so that it
|
||||||
|
* the compile could be used on another kernel unchanged??
|
||||||
|
* Current caching doesn't support this but in the future maybe
|
||||||
|
*/
|
||||||
|
if (!kernel_supports_ptrace) {
|
||||||
|
warn_once(prof.name);
|
||||||
|
return RULE_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* always generate a label and ptrace entry */
|
||||||
|
buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "|)";
|
||||||
|
|
||||||
|
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_PTRACE;
|
||||||
|
|
||||||
|
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_VALID_PTRACE_PERMS) {
|
||||||
|
if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit,
|
||||||
|
dfaflags))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
||||||
|
|
52
parser/ptrace.h
Normal file
52
parser/ptrace.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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_PTRACE_H
|
||||||
|
#define __AA_PTRACE_H
|
||||||
|
|
||||||
|
#include "immunix.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#define AA_MAY_TRACE AA_MAY_WRITE
|
||||||
|
#define AA_MAY_READBY 0x10 /* MAY_CREATE in new encoding */
|
||||||
|
#define AA_MAY_TRACEDBY AA_MAY_APPEND
|
||||||
|
#define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \
|
||||||
|
AA_MAY_TRACEDBY)
|
||||||
|
|
||||||
|
int parse_ptrace_mode(const char *str_mode, int *mode, int fail);
|
||||||
|
|
||||||
|
class ptrace_rule: public rule_t {
|
||||||
|
void move_conditionals(struct cond_entry *conds);
|
||||||
|
public:
|
||||||
|
char *peer_label;
|
||||||
|
int mode;
|
||||||
|
int audit;
|
||||||
|
int deny;
|
||||||
|
|
||||||
|
ptrace_rule(int mode, struct cond_entry *conds, char *peer);
|
||||||
|
virtual ~ptrace_rule()
|
||||||
|
{
|
||||||
|
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_PTRACE_H */
|
Loading…
x
Reference in New Issue
Block a user