mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 01:57:43 +00:00
parser: add support for a generic all rule type
Extend the policy syntax to have a rule that allows specifying all permissions for all rule types. allow all, This is useful for making blacklist based policy, but can also be useful when combined with other rule prefixes, eg. to add audit to all rules. audit access all, Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
a9c5388f69
commit
197d00d21a
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,6 +29,7 @@ parser/parser_yacc.h
|
|||||||
parser/pod2htm*.tmp
|
parser/pod2htm*.tmp
|
||||||
parser/af_rule.o
|
parser/af_rule.o
|
||||||
parser/af_unix.o
|
parser/af_unix.o
|
||||||
|
parser/all_rule.o
|
||||||
parser/common_optarg.o
|
parser/common_optarg.o
|
||||||
parser/dbus.o
|
parser/dbus.o
|
||||||
parser/default_features.o
|
parser/default_features.o
|
||||||
|
@ -102,12 +102,12 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \
|
|||||||
parser_alias.c common_optarg.c lib.c network.cc \
|
parser_alias.c common_optarg.c lib.c network.cc \
|
||||||
mount.cc dbus.cc profile.cc rule.cc signal.cc ptrace.cc \
|
mount.cc dbus.cc profile.cc rule.cc signal.cc ptrace.cc \
|
||||||
af_rule.cc af_unix.cc policy_cache.c default_features.c userns.cc \
|
af_rule.cc af_unix.cc policy_cache.c default_features.c userns.cc \
|
||||||
mqueue.cc io_uring.cc
|
mqueue.cc io_uring.cc all_rule.cc
|
||||||
STATIC_HDRS = af_rule.h af_unix.h capability.h common_optarg.h dbus.h \
|
STATIC_HDRS = af_rule.h af_unix.h capability.h common_optarg.h dbus.h \
|
||||||
file_cache.h immunix.h lib.h mount.h network.h parser.h \
|
file_cache.h immunix.h lib.h mount.h network.h parser.h \
|
||||||
parser_include.h parser_version.h policy_cache.h policydb.h \
|
parser_include.h parser_version.h policy_cache.h policydb.h \
|
||||||
profile.h ptrace.h rule.h signal.h userns.h mqueue.h io_uring.h \
|
profile.h ptrace.h rule.h signal.h userns.h mqueue.h io_uring.h \
|
||||||
common_flags.h bignum.h
|
common_flags.h bignum.h all_rule.h
|
||||||
|
|
||||||
SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h
|
SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h
|
||||||
GENERATED_HDRS = af_names.h generated_af_names.h \
|
GENERATED_HDRS = af_names.h generated_af_names.h \
|
||||||
@ -322,6 +322,9 @@ mqueue.o: mqueue.cc $(HDRS)
|
|||||||
io_uring.o: io_uring.cc $(HDRS)
|
io_uring.o: io_uring.cc $(HDRS)
|
||||||
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
all_rule.o: all_rule.cc $(HDRS)
|
||||||
|
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
parser_version.h: Makefile
|
parser_version.h: Makefile
|
||||||
@echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
|
@echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
|
||||||
@mv -f .ver $@
|
@mv -f .ver $@
|
||||||
|
130
parser/all_rule.cc
Normal file
130
parser/all_rule.cc
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023
|
||||||
|
* 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 Canonical Ltd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "profile.h"
|
||||||
|
#include "all_rule.h"
|
||||||
|
#include "af_unix.h"
|
||||||
|
#include "dbus.h"
|
||||||
|
#include "io_uring.h"
|
||||||
|
#include "mqueue.h"
|
||||||
|
#include "ptrace.h"
|
||||||
|
#include "signal.h"
|
||||||
|
#include "userns.h"
|
||||||
|
#include "mount.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void all_rule::add_implied_rules(Profile &prof)
|
||||||
|
{
|
||||||
|
prefix_rule_t *rule;
|
||||||
|
const prefixes *prefix = this;
|
||||||
|
|
||||||
|
rule = new unix_rule(0, audit, rule_mode);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new dbus_rule(0, NULL, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new io_uring_rule(0, NULL, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new mqueue_rule(0, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new ptrace_rule(0, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new signal_rule(0, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new userns_rule(0, NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new mnt_rule(NULL, NULL, NULL, NULL, 0);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new mnt_rule(NULL, NULL, NULL, NULL, AA_DUMMY_REMOUNT);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new mnt_rule(NULL, NULL, NULL, NULL, AA_MAY_UMOUNT);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new mnt_rule(NULL, NULL, NULL, NULL, AA_MAY_PIVOTROOT);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
rule = new network_rule(NULL);
|
||||||
|
(void) rule->add_prefix(*prefix);
|
||||||
|
prof.rule_ents.push_back(rule);
|
||||||
|
|
||||||
|
/* rules that have not been converted to use rule.h */
|
||||||
|
|
||||||
|
//file
|
||||||
|
{
|
||||||
|
const char *error;
|
||||||
|
struct cod_entry *entry;
|
||||||
|
char *path = strdup("/{**,}");
|
||||||
|
int perms = ((AA_BASE_PERMS & ~AA_EXEC_TYPE) |
|
||||||
|
(AA_MAY_EXEC));
|
||||||
|
if (rule_mode != RULE_DENY)
|
||||||
|
perms |= AA_EXEC_INHERIT;
|
||||||
|
/* duplicate to other permission set */
|
||||||
|
perms |= perms << AA_OTHER_SHIFT;
|
||||||
|
if (!path)
|
||||||
|
yyerror(_("Memory allocation error."));
|
||||||
|
entry = new_entry(path, perms, NULL);
|
||||||
|
if (!entry_add_prefix(entry, *prefix, error)) {
|
||||||
|
yyerror(_("%s"), error);
|
||||||
|
}
|
||||||
|
add_entry_to_policy(&prof, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// caps
|
||||||
|
{
|
||||||
|
if (prefix->owner)
|
||||||
|
yyerror(_("owner prefix not allowed on capability rules"));
|
||||||
|
|
||||||
|
if (rule_mode == RULE_DENY && audit == AUDIT_FORCE) {
|
||||||
|
prof.caps.deny |= 0xffffffffffffffff;
|
||||||
|
} else if (rule_mode == RULE_DENY) {
|
||||||
|
prof.caps.deny |= 0xffffffffffffffff;
|
||||||
|
prof.caps.quiet |= 0xffffffffffffffff;
|
||||||
|
} else {
|
||||||
|
prof.caps.allow |= 0xffffffffffffffff;
|
||||||
|
if (audit != AUDIT_UNSPECIFIED)
|
||||||
|
prof.caps.audit |= 0xffffffffffffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: rlimit
|
||||||
|
}
|
70
parser/all_rule.h
Normal file
70
parser/all_rule.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023
|
||||||
|
* 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 Canonical Ltd.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __AA_ALL_H
|
||||||
|
#define __AA_ALL_H
|
||||||
|
|
||||||
|
#include "rule.h"
|
||||||
|
|
||||||
|
#define AA_IO_URING_OVERRIDE_CREDS AA_MAY_APPEND
|
||||||
|
#define AA_IO_URING_SQPOLL AA_MAY_CREATE
|
||||||
|
|
||||||
|
#define AA_VALID_IO_URING_PERMS (AA_IO_URING_OVERRIDE_CREDS | \
|
||||||
|
AA_IO_URING_SQPOLL)
|
||||||
|
|
||||||
|
class all_rule: public prefix_rule_t {
|
||||||
|
void move_conditionals(struct cond_entry *conds);
|
||||||
|
public:
|
||||||
|
char *label;
|
||||||
|
|
||||||
|
all_rule(void): prefix_rule_t(RULE_TYPE_ALL) { }
|
||||||
|
|
||||||
|
virtual bool valid_prefix(const prefixes &p, const char *&error) {
|
||||||
|
if (p.owner) {
|
||||||
|
error = _("owner prefix not allowed on all rules");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
int expand_variables(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual ostream &dump(ostream &os) {
|
||||||
|
prefix_rule_t::dump(os);
|
||||||
|
|
||||||
|
os << "all";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
virtual bool is_mergeable(void) { return true; }
|
||||||
|
virtual int cmp(rule_t const &rhs) const
|
||||||
|
{
|
||||||
|
return prefix_rule_t::cmp(rhs);
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void add_implied_rules(Profile &prof);
|
||||||
|
|
||||||
|
virtual int gen_policy_re(Profile &prof unused) { return RULE_OK; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void warn_once(const char *name unused, const char *msg unused) { };
|
||||||
|
virtual void warn_once(const char *name unused) { };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __AA_ALL_H */
|
@ -125,7 +125,7 @@ B<RULES> = [ ( I<LINE RULES> | I<COMMA RULES> ',' | I<BLOCK RULES> )
|
|||||||
|
|
||||||
B<LINE RULES> = ( I<COMMENT> | I<INCLUDE> ) [ '\r' ] '\n'
|
B<LINE RULES> = ( I<COMMENT> | I<INCLUDE> ) [ '\r' ] '\n'
|
||||||
|
|
||||||
B<COMMA RULES> = ( I<CAPABILITY RULE> | I<NETWORK RULE> | I<MOUNT RULE> | I<PIVOT ROOT RULE> | I<UNIX RULE> | I<FILE RULE> | I<LINK RULE> | I<CHANGE_PROFILE RULE> | I<RLIMIT RULE> | I<DBUS RULE> | I<MQUEUE RULE> | I<IO_URING RULE> | I<USERNS RULE>)
|
B<COMMA RULES> = ( I<CAPABILITY RULE> | I<NETWORK RULE> | I<MOUNT RULE> | I<PIVOT ROOT RULE> | I<UNIX RULE> | I<FILE RULE> | I<LINK RULE> | I<CHANGE_PROFILE RULE> | I<RLIMIT RULE> | I<DBUS RULE> | I<MQUEUE RULE> | I<IO_URING RULE> | I<USERNS RULE> | I<ALL RULE>)
|
||||||
|
|
||||||
B<BLOCK RULES> = ( I<SUBPROFILE> | I<HAT> | I<QUALIFIER BLOCK> )
|
B<BLOCK RULES> = ( I<SUBPROFILE> | I<HAT> | I<QUALIFIER BLOCK> )
|
||||||
|
|
||||||
@ -346,6 +346,8 @@ B<EXEC_MODE> = ( 'safe' | 'unsafe' )
|
|||||||
|
|
||||||
B<EXEC COND> = I<FILEGLOB>
|
B<EXEC COND> = I<FILEGLOB>
|
||||||
|
|
||||||
|
B<ALL RULE> = 'all'
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
All resources and programs need a full path. There may be any number of
|
All resources and programs need a full path. There may be any number of
|
||||||
@ -1604,6 +1606,26 @@ Not all kernels support B<safe> mode and the parser will downgrade rules to
|
|||||||
B<unsafe> mode in that situation. If no exec mode is specified, the default is
|
B<unsafe> mode in that situation. If no exec mode is specified, the default is
|
||||||
B<safe> mode in kernels that support it.
|
B<safe> mode in kernels that support it.
|
||||||
|
|
||||||
|
=head2 all rule
|
||||||
|
|
||||||
|
The all rule is used to add a generic rule for all supported rule types.
|
||||||
|
This is useful when policy wants to define a black list instead of
|
||||||
|
white list, but can also be useful to add an access qualifier to all
|
||||||
|
rules.
|
||||||
|
|
||||||
|
Eg. Black list
|
||||||
|
|
||||||
|
allow all,
|
||||||
|
# begin blacklist
|
||||||
|
deny file,
|
||||||
|
deny unix,
|
||||||
|
|
||||||
|
|
||||||
|
Eg. Adding audit qualifier
|
||||||
|
|
||||||
|
audit access all,
|
||||||
|
|
||||||
|
|
||||||
=head2 rlimit rules
|
=head2 rlimit rules
|
||||||
|
|
||||||
AppArmor can set and control the resource limits associated with a
|
AppArmor can set and control the resource limits associated with a
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, contact or Canonical Ltd.
|
* along with this program; if not, contact Canonical Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common_optarg.h"
|
#include "common_optarg.h"
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, contact or Canonical Ltd.
|
* along with this program; if not, contact Canonical Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __AA_IO_URING_H
|
#ifndef __AA_IO_URING_H
|
||||||
|
@ -461,6 +461,9 @@ extern bool strcomp (const char *lhs, const char *rhs);
|
|||||||
extern struct cod_entry *copy_cod_entry(struct cod_entry *cod);
|
extern struct cod_entry *copy_cod_entry(struct cod_entry *cod);
|
||||||
extern void free_cod_entries(struct cod_entry *list);
|
extern void free_cod_entries(struct cod_entry *list);
|
||||||
void debug_cod_entries(struct cod_entry *list);
|
void debug_cod_entries(struct cod_entry *list);
|
||||||
|
bool check_x_qualifier(struct cod_entry *entry, const char *&error);
|
||||||
|
bool entry_add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error);
|
||||||
|
|
||||||
|
|
||||||
#define SECONDS_P_MS (1000LL * 1000LL)
|
#define SECONDS_P_MS (1000LL * 1000LL)
|
||||||
long long convert_time_units(long long value, long long base, const char *units);
|
long long convert_time_units(long long value, long long base, const char *units);
|
||||||
|
@ -658,6 +658,10 @@ include/{WS} {
|
|||||||
yy_push_state(INCLUDE);
|
yy_push_state(INCLUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all/({WS}|[^[:alnum:]_]) {
|
||||||
|
RETURN_TOKEN(TOK_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
#.*\r?\n { /* normal comment */
|
#.*\r?\n { /* normal comment */
|
||||||
DUMP_AND_DEBUG("comment(%d): %s\n", current_lineno, yytext);
|
DUMP_AND_DEBUG("comment(%d): %s\n", current_lineno, yytext);
|
||||||
current_lineno++;
|
current_lineno++;
|
||||||
|
@ -129,6 +129,7 @@ static struct keyword_table keyword_table[] = {
|
|||||||
{"io_uring", TOK_IO_URING},
|
{"io_uring", TOK_IO_URING},
|
||||||
{"override_creds", TOK_OVERRIDE_CREDS},
|
{"override_creds", TOK_OVERRIDE_CREDS},
|
||||||
{"sqpoll", TOK_SQPOLL},
|
{"sqpoll", TOK_SQPOLL},
|
||||||
|
{"all", TOK_ALL},
|
||||||
|
|
||||||
/* terminate */
|
/* terminate */
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
@ -1086,6 +1087,47 @@ void debug_cod_entries(struct cod_entry *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_x_qualifier(struct cod_entry *entry, const char *&error)
|
||||||
|
{
|
||||||
|
if (entry->perms & AA_EXEC_BITS) {
|
||||||
|
if ((entry->rule_mode == RULE_DENY) &&
|
||||||
|
(entry->perms & ALL_AA_EXEC_TYPE)) {
|
||||||
|
error = _("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'");
|
||||||
|
return false;
|
||||||
|
} else if ((entry->rule_mode != RULE_DENY) &&
|
||||||
|
!(entry->perms & ALL_AA_EXEC_TYPE)) {
|
||||||
|
error = _("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cod_entry version of ->add_prefix here just as file rules aren't converted yet
|
||||||
|
bool entry_add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error)
|
||||||
|
{
|
||||||
|
/* modifiers aren't correctly stored for cod_entries yet so
|
||||||
|
* we can't conflict on them easily. Leave that until conversion
|
||||||
|
* to rule_t
|
||||||
|
*/
|
||||||
|
/* apply rule mode */
|
||||||
|
entry->rule_mode = p.rule_mode;
|
||||||
|
|
||||||
|
/* apply owner/other */
|
||||||
|
if (p.owner == 1)
|
||||||
|
entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS);
|
||||||
|
else if (p.owner == 2)
|
||||||
|
entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
|
||||||
|
|
||||||
|
/* implied audit modifier */
|
||||||
|
if (p.audit == AUDIT_FORCE && (entry->rule_mode != RULE_DENY))
|
||||||
|
entry->audit = AUDIT_FORCE;
|
||||||
|
else if (p.audit != AUDIT_FORCE && (entry->rule_mode == RULE_DENY))
|
||||||
|
entry->audit = AUDIT_FORCE;
|
||||||
|
|
||||||
|
return check_x_qualifier(entry, error);
|
||||||
|
}
|
||||||
|
|
||||||
// these need to move to stl
|
// these need to move to stl
|
||||||
int ordered_cmp_value_list(value_list *lhs, value_list *rhs)
|
int ordered_cmp_value_list(value_list *lhs, value_list *rhs)
|
||||||
{
|
{
|
||||||
|
@ -70,8 +70,6 @@ mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src,
|
|||||||
mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
|
mnt_rule *do_pivot_rule(struct cond_entry *old, char *root,
|
||||||
char *transition);
|
char *transition);
|
||||||
static void abi_features(char *filename, bool search);
|
static void abi_features(char *filename, bool search);
|
||||||
bool add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error);
|
|
||||||
bool check_x_qualifier(struct cod_entry *entry, const char *&errror);
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -149,6 +147,7 @@ bool check_x_qualifier(struct cod_entry *entry, const char *&errror);
|
|||||||
%token TOK_IO_URING
|
%token TOK_IO_URING
|
||||||
%token TOK_OVERRIDE_CREDS
|
%token TOK_OVERRIDE_CREDS
|
||||||
%token TOK_SQPOLL
|
%token TOK_SQPOLL
|
||||||
|
%token TOK_ALL
|
||||||
|
|
||||||
/* rlimits */
|
/* rlimits */
|
||||||
%token TOK_RLIMIT
|
%token TOK_RLIMIT
|
||||||
@ -188,6 +187,7 @@ bool check_x_qualifier(struct cod_entry *entry, const char *&errror);
|
|||||||
#include "mqueue.h"
|
#include "mqueue.h"
|
||||||
#include "io_uring.h"
|
#include "io_uring.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "all_rule.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
@ -207,6 +207,7 @@ bool check_x_qualifier(struct cod_entry *entry, const char *&errror);
|
|||||||
userns_rule *userns_entry;
|
userns_rule *userns_entry;
|
||||||
mqueue_rule *mqueue_entry;
|
mqueue_rule *mqueue_entry;
|
||||||
io_uring_rule *io_uring_entry;
|
io_uring_rule *io_uring_entry;
|
||||||
|
all_rule *all_entry;
|
||||||
prefix_rule_t *prefix_entry;
|
prefix_rule_t *prefix_entry;
|
||||||
|
|
||||||
flagvals flags;
|
flagvals flags;
|
||||||
@ -303,6 +304,7 @@ bool check_x_qualifier(struct cod_entry *entry, const char *&errror);
|
|||||||
%type <fperms> io_uring_perms
|
%type <fperms> io_uring_perms
|
||||||
%type <fperms> opt_io_uring_perm
|
%type <fperms> opt_io_uring_perm
|
||||||
%type <io_uring_entry> io_uring_rule
|
%type <io_uring_entry> io_uring_rule
|
||||||
|
%type <all_entry> all_rule
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
||||||
@ -656,7 +658,7 @@ rules: rules opt_prefix rule
|
|||||||
PDEBUG("rules rule: (%s)\n", $3->name);
|
PDEBUG("rules rule: (%s)\n", $3->name);
|
||||||
if (!$3)
|
if (!$3)
|
||||||
yyerror(_("Assert: `rule' returned NULL."));
|
yyerror(_("Assert: `rule' returned NULL."));
|
||||||
if (!add_prefix($3, $2, error)) {
|
if (!entry_add_prefix($3, $2, error)) {
|
||||||
yyerror(_("%s"), error);
|
yyerror(_("%s"), error);
|
||||||
}
|
}
|
||||||
add_entry_to_policy($1, $3);
|
add_entry_to_policy($1, $3);
|
||||||
@ -677,7 +679,7 @@ rules: rules opt_prefix block
|
|||||||
list_for_each_safe($3->entries, entry, tmp) {
|
list_for_each_safe($3->entries, entry, tmp) {
|
||||||
const char *error;
|
const char *error;
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
if (!add_prefix(entry, $2, error)) {
|
if (!entry_add_prefix(entry, $2, error)) {
|
||||||
yyerror(_("%s"), error);
|
yyerror(_("%s"), error);
|
||||||
}
|
}
|
||||||
/* transfer rule for now, TODO keep block and just
|
/* transfer rule for now, TODO keep block and just
|
||||||
@ -722,6 +724,7 @@ prefix_rule : mnt_rule { $$ = $1; }
|
|||||||
| userns_rule { $$ = $1; }
|
| userns_rule { $$ = $1; }
|
||||||
| mqueue_rule { $$ = $1; }
|
| mqueue_rule { $$ = $1; }
|
||||||
| io_uring_rule { $$ = $1; }
|
| io_uring_rule { $$ = $1; }
|
||||||
|
| all_rule { $$ = $1; }
|
||||||
|
|
||||||
rules: rules opt_prefix prefix_rule
|
rules: rules opt_prefix prefix_rule
|
||||||
{
|
{
|
||||||
@ -1511,6 +1514,14 @@ io_uring_rule: TOK_IO_URING opt_io_uring_perm opt_conds opt_cond_list TOK_END_OF
|
|||||||
$$ = ent;
|
$$ = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all_rule: TOK_ALL TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
all_rule *ent = new all_rule();
|
||||||
|
if (!ent)
|
||||||
|
yyerror(_("Memory allocation error."));
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
|
||||||
hat_start: TOK_CARET {}
|
hat_start: TOK_CARET {}
|
||||||
| TOK_HAT {}
|
| TOK_HAT {}
|
||||||
|
|
||||||
@ -1773,43 +1784,3 @@ static void abi_features(char *filename, bool search)
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool check_x_qualifier(struct cod_entry *entry, const char *&error)
|
|
||||||
{
|
|
||||||
if (entry->perms & AA_EXEC_BITS) {
|
|
||||||
if ((entry->rule_mode == RULE_DENY) &&
|
|
||||||
(entry->perms & ALL_AA_EXEC_TYPE)) {
|
|
||||||
error = _("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'");
|
|
||||||
return false;
|
|
||||||
} else if ((entry->rule_mode != RULE_DENY) &&
|
|
||||||
!(entry->perms & ALL_AA_EXEC_TYPE)) {
|
|
||||||
error = _("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cod_entry version of ->add_prefix here just as file rules aren't converted yet
|
|
||||||
bool add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error)
|
|
||||||
{
|
|
||||||
/* modifiers aren't correctly stored for cod_entries yet so
|
|
||||||
* we can't conflict on them easily. Leave that until conversion
|
|
||||||
* to rule_t
|
|
||||||
*/
|
|
||||||
/* apply rule mode */
|
|
||||||
entry->rule_mode = p.rule_mode;
|
|
||||||
|
|
||||||
/* apply owner/other */
|
|
||||||
if (p.owner == 1)
|
|
||||||
entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS);
|
|
||||||
else if (p.owner == 2)
|
|
||||||
entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
|
|
||||||
|
|
||||||
/* implied audit modifier */
|
|
||||||
if (p.audit == AUDIT_FORCE && (entry->rule_mode != RULE_DENY))
|
|
||||||
entry->audit = AUDIT_FORCE;
|
|
||||||
else if (p.audit != AUDIT_FORCE && (entry->rule_mode == RULE_DENY))
|
|
||||||
entry->audit = AUDIT_FORCE;
|
|
||||||
|
|
||||||
return check_x_qualifier(entry, error);
|
|
||||||
}
|
|
||||||
|
@ -347,6 +347,12 @@ void Profile::add_implied_rules(void)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); i++) {
|
||||||
|
if ((*i)->skip())
|
||||||
|
continue;
|
||||||
|
(*i)->add_implied_rules(*this);
|
||||||
|
}
|
||||||
|
|
||||||
error = profile_add_hat_rules(this);
|
error = profile_add_hat_rules(this);
|
||||||
if (error) {
|
if (error) {
|
||||||
PERROR(_("ERROR adding hat access rule for profile %s\n"),
|
PERROR(_("ERROR adding hat access rule for profile %s\n"),
|
||||||
|
@ -35,8 +35,9 @@ class Profile;
|
|||||||
#define RULE_TYPE_RULE 0
|
#define RULE_TYPE_RULE 0
|
||||||
#define RULE_TYPE_PREFIX 1
|
#define RULE_TYPE_PREFIX 1
|
||||||
#define RULE_TYPE_PERMS 2
|
#define RULE_TYPE_PERMS 2
|
||||||
|
#define RULE_TYPE_ALL 3
|
||||||
// RULE_TYPE_CLASS needs to be last because various class follow it
|
// RULE_TYPE_CLASS needs to be last because various class follow it
|
||||||
#define RULE_TYPE_CLASS 3
|
#define RULE_TYPE_CLASS 4
|
||||||
|
|
||||||
// rule_cast should only be used after a comparison of rule_type to ensure
|
// rule_cast should only be used after a comparison of rule_type to ensure
|
||||||
// that it is valid. Change to dynamic_cast for debugging
|
// that it is valid. Change to dynamic_cast for debugging
|
||||||
@ -289,6 +290,10 @@ public:
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
virtual bool add_prefix(const prefixes &p) {
|
||||||
|
const char *err;
|
||||||
|
return add_prefix(p, err);
|
||||||
|
}
|
||||||
|
|
||||||
int cmp(prefixes const &rhs) const {
|
int cmp(prefixes const &rhs) const {
|
||||||
return prefixes::cmp(rhs);
|
return prefixes::cmp(rhs);
|
||||||
|
8
parser/tst/simple_tests/all/bad_01.sd
Normal file
8
parser/tst/simple_tests/all/bad_01.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic ptrace all rule
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
all read readby trace tracedby ,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/bad_02.sd
Normal file
8
parser/tst/simple_tests/all/bad_02.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic ptrace all rule
|
||||||
|
#=EXRESULT FAIL
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
owner all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_01.sd
Normal file
8
parser/tst/simple_tests/all/ok_01.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_02.sd
Normal file
8
parser/tst/simple_tests/all/ok_02.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
audit all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_03.sd
Normal file
8
parser/tst/simple_tests/all/ok_03.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
allow all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_04.sd
Normal file
8
parser/tst/simple_tests/all/ok_04.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
deny all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_05.sd
Normal file
8
parser/tst/simple_tests/all/ok_05.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
audit deny all,
|
||||||
|
|
||||||
|
}
|
8
parser/tst/simple_tests/all/ok_06.sd
Normal file
8
parser/tst/simple_tests/all/ok_06.sd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#
|
||||||
|
#=Description basic all rule
|
||||||
|
#=EXRESULT PASS
|
||||||
|
#
|
||||||
|
/usr/bin/foo {
|
||||||
|
audit allow all,
|
||||||
|
|
||||||
|
}
|
@ -263,6 +263,14 @@ unknown_line = (
|
|||||||
'file/ok_other_2.sd',
|
'file/ok_other_2.sd',
|
||||||
'file/ok_other_3.sd',
|
'file/ok_other_3.sd',
|
||||||
|
|
||||||
|
# 'all' keyword
|
||||||
|
'all/ok_01.sd',
|
||||||
|
'all/ok_02.sd',
|
||||||
|
'all/ok_03.sd',
|
||||||
|
'all/ok_04.sd',
|
||||||
|
'all/ok_05.sd',
|
||||||
|
'all/ok_06.sd',
|
||||||
|
|
||||||
# 'unsafe' keyword
|
# 'unsafe' keyword
|
||||||
'file/file/front_perms_ok_1.sd',
|
'file/file/front_perms_ok_1.sd',
|
||||||
'file/front_perms_ok_1.sd',
|
'file/front_perms_ok_1.sd',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user