mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 18:17:09 +00:00
parser: add parser support for message queue mediation
Message queue rules take the following format: mqueue [<access_mode>] [<type>] [<label>] [<mqueue name>], access_mode := 'r'|'w'|'rw'|'read'|'write'| 'create'|'open'|'delete'| 'getattr'|'setattr' type := 'type' '=' ('posix'|'sysv') label := 'label' '=' <target label> Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
f03a3198a8
commit
d98c5c4cf9
1
.gitignore
vendored
1
.gitignore
vendored
@ -39,6 +39,7 @@ parser/libapparmor_re/hfa.o
|
|||||||
parser/libapparmor_re/libapparmor_re.a
|
parser/libapparmor_re/libapparmor_re.a
|
||||||
parser/libapparmor_re/parse.o
|
parser/libapparmor_re/parse.o
|
||||||
parser/mount.o
|
parser/mount.o
|
||||||
|
parser/mqueue.o
|
||||||
parser/network.o
|
parser/network.o
|
||||||
parser/parser_alias.o
|
parser/parser_alias.o
|
||||||
parser/parser_common.o
|
parser/parser_common.o
|
||||||
|
@ -101,10 +101,11 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.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 common_optarg.c lib.c network.c \
|
parser_alias.c common_optarg.c lib.c network.c \
|
||||||
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
|
||||||
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 ptrace.h network.h af_rule.h af_unix.h \
|
rule.h common_optarg.h signal.h ptrace.h network.h af_rule.h af_unix.h \
|
||||||
policy_cache.h file_cache.h userns.h
|
policy_cache.h file_cache.h userns.h mqueue.h
|
||||||
TOOLS = apparmor_parser
|
TOOLS = apparmor_parser
|
||||||
|
|
||||||
OBJECTS = $(patsubst %.cc, %.o, $(SRCS:.c=.o))
|
OBJECTS = $(patsubst %.cc, %.o, $(SRCS:.c=.o))
|
||||||
@ -304,6 +305,9 @@ rule.o: rule.cc rule.h policydb.h
|
|||||||
userns.o: userns.cc userns.h parser.h parser_yacc.h rule.h $(APPARMOR_H)
|
userns.o: userns.cc userns.h parser.h parser_yacc.h rule.h $(APPARMOR_H)
|
||||||
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
$(CXX) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
mqueue.o: mqueue.cc mqueue.h parser.h immunix.h profile.h parser_yacc.h rule.h $(APPARMOR_H)
|
||||||
|
$(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 $@
|
||||||
|
@ -123,7 +123,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> )
|
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> )
|
||||||
|
|
||||||
B<BLOCK RULES> = ( I<SUBPROFILE> | I<HAT> | I<QUALIFIER BLOCK> )
|
B<BLOCK RULES> = ( I<SUBPROFILE> | I<HAT> | I<QUALIFIER BLOCK> )
|
||||||
|
|
||||||
@ -176,6 +176,20 @@ B<MOUNT FLAGS> = ( 'ro' | 'rw' | 'nosuid' | 'suid' | 'nodev' | 'dev' | 'noexec'
|
|||||||
|
|
||||||
B<MOUNT EXPRESSION> = ( I<ALPHANUMERIC> | I<AARE> ) ...
|
B<MOUNT EXPRESSION> = ( I<ALPHANUMERIC> | I<AARE> ) ...
|
||||||
|
|
||||||
|
B<MQUEUE_RULE> = [ I<QUALIFIERS> ] 'mqueue' [ I<MQUEUE ACCESS PERMISSIONS> ] [ I<MQUEUE TYPE> ] [ I<MQUEUE LABEL> ] [ I<MQUEUE NAME> ]
|
||||||
|
|
||||||
|
B<MQUEUE ACCESS PERMISSIONS> = I<MQUEUE ACCESS> | I<MQUEUE ACCESS LIST>
|
||||||
|
|
||||||
|
B<MQUEUE ACCESS LIST> = '(' Comma or space separated list of I<MQUEUE ACCESS> ')'
|
||||||
|
|
||||||
|
B<MQUEUE ACCESS> = ( 'r' | 'w' | 'rw' | 'read' | 'write' | 'create' | 'open' | 'delete' | 'getattr' | 'setattr' )
|
||||||
|
|
||||||
|
B<MQUEUE TYPE> = 'type' '=' ( 'posix' | 'sysv' )
|
||||||
|
|
||||||
|
B<MQUEUE LABEL> = 'label' '=' '(' '"' I<AARE> '"' | I<AARE> ')'
|
||||||
|
|
||||||
|
B<MQUEUE NAME> = I<AARE>
|
||||||
|
|
||||||
B<PIVOT ROOT RULE> = [ I<QUALIFIERS> ] pivot_root [ oldroot=I<OLD PUT FILEGLOB> ] [ I<NEW ROOT FILEGLOB> ] [ '-E<gt>' I<PROFILE NAME> ]
|
B<PIVOT ROOT RULE> = [ I<QUALIFIERS> ] pivot_root [ oldroot=I<OLD PUT FILEGLOB> ] [ I<NEW ROOT FILEGLOB> ] [ '-E<gt>' I<PROFILE NAME> ]
|
||||||
|
|
||||||
B<SOURCE FILEGLOB> = I<FILEGLOB>
|
B<SOURCE FILEGLOB> = I<FILEGLOB>
|
||||||
@ -1057,6 +1071,51 @@ Matches only:
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
=head2 Message Queue rules
|
||||||
|
|
||||||
|
AppArmor supports mediation of POSIX and SYSV message queues.
|
||||||
|
|
||||||
|
AppArmor Message Queue permissions are implied when a rule does not explicitly
|
||||||
|
state an access list. By default, all Message Queue permissions are implied.
|
||||||
|
|
||||||
|
AppArmor Message Queue permissions become more restricted as further information
|
||||||
|
is specified. Policy can be specified by determining its access mode, type,
|
||||||
|
label, and message queue name.
|
||||||
|
|
||||||
|
Regarding access modes, 'r' and 'read' are used to read messages from the queue.
|
||||||
|
'w' and 'write' are used to write to the message queue. 'create' is used to create
|
||||||
|
the message queue, and 'open' is used to get the message queue identifier when the
|
||||||
|
queue is already created. 'delete' is used to remove the message queue. The access
|
||||||
|
modes to get and set attributes of the message queue are 'setattr' and 'getattr'.
|
||||||
|
|
||||||
|
The type of the policy can be either 'posix' or 'sysv'. This information is
|
||||||
|
relevant when the message queue name is not specified, and when specified can be
|
||||||
|
inferred by the queue name, since message queues' name for posix must start with '/',
|
||||||
|
and message queues' key for SYSV must be a positive integer.
|
||||||
|
|
||||||
|
The policy label is the label assigned to the message queue when it is created.
|
||||||
|
|
||||||
|
The message queue name can be either a string starting with '/' if the type
|
||||||
|
is POSIX, or a positive integer if the type is SYSV. If the type is not
|
||||||
|
specified, then it will be inferred by the queue name.
|
||||||
|
|
||||||
|
Example AppArmor Message Queue rules:
|
||||||
|
|
||||||
|
# Allow all Message Queue access
|
||||||
|
mqueue,
|
||||||
|
|
||||||
|
# Explicitly allow all Message Queue access,
|
||||||
|
mqueue (create, open, delete, read, write, getattr, setattr),
|
||||||
|
|
||||||
|
# Explicitly deny use of Message Queue
|
||||||
|
deny mqueue,
|
||||||
|
|
||||||
|
# Allow all access for POSIX queue of name /bar
|
||||||
|
mqueue type=posix /bar,
|
||||||
|
|
||||||
|
# Allow create permission for a SYSV queue of label foo
|
||||||
|
mqueue create label=foo 123,
|
||||||
|
|
||||||
=head2 Pivot Root Rules
|
=head2 Pivot Root Rules
|
||||||
|
|
||||||
AppArmor mediates changing of the root filesystem through the pivot_root(2)
|
AppArmor mediates changing of the root filesystem through the pivot_root(2)
|
||||||
|
272
parser/mqueue.cc
Normal file
272
parser/mqueue.cc
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022
|
||||||
|
* 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 "mqueue.h"
|
||||||
|
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
int parse_mqueue_mode(const char *str_mode, int *mode, int fail)
|
||||||
|
{
|
||||||
|
return parse_X_mode("mqueue", AA_VALID_MQUEUE_PERMS, str_mode, mode, fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_all_digits(char *str)
|
||||||
|
{
|
||||||
|
const char *s = str;
|
||||||
|
while (*str && isdigit(*str))
|
||||||
|
str++;
|
||||||
|
return str != s && *str == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqueue_rule::validate_qname(void)
|
||||||
|
{
|
||||||
|
if (qname[0] == '/') {
|
||||||
|
// TODO full syntax check of name
|
||||||
|
if (qtype == mqueue_sysv)
|
||||||
|
yyerror("mqueue type=sysv invalid name '%s', sysv "
|
||||||
|
"message queues must be identified by a "
|
||||||
|
"positive integer.\n", qname);
|
||||||
|
qtype = mqueue_posix; // implied by name
|
||||||
|
} else if (is_all_digits(qname)) {
|
||||||
|
if (qtype == mqueue_posix)
|
||||||
|
yyerror("mqueue type=posix invalid name '%s', posix "
|
||||||
|
"message queues names must begin with a /\n",
|
||||||
|
qname);
|
||||||
|
qtype = mqueue_sysv; // implied
|
||||||
|
} else {
|
||||||
|
yyerror("mqueue invalid name '%s', message queue names must begin with a / or be a positive integer.\n", qname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqueue_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 mqueue rules\n");
|
||||||
|
|
||||||
|
if (strcmp(cond_ent->name, "label") == 0) {
|
||||||
|
move_conditional_value("mqueue", &label, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "type") == 0) {
|
||||||
|
char *tmp = NULL;
|
||||||
|
move_conditional_value("mqueue", &tmp, cond_ent);
|
||||||
|
if (strcmp(tmp, "posix") == 0)
|
||||||
|
qtype = mqueue_posix;
|
||||||
|
else if (strcmp(tmp, "sysv") == 0)
|
||||||
|
qtype = mqueue_sysv;
|
||||||
|
else
|
||||||
|
yyerror("mqueue invalid type='%s'\n", tmp);
|
||||||
|
free(tmp);
|
||||||
|
} else {
|
||||||
|
yyerror("invalid mqueue rule conditional \"%s\"\n",
|
||||||
|
cond_ent->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p):
|
||||||
|
qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(0), deny(0)
|
||||||
|
{
|
||||||
|
move_conditionals(conds);
|
||||||
|
free_cond_list(conds);
|
||||||
|
|
||||||
|
if (qname)
|
||||||
|
validate_qname();
|
||||||
|
if (mode_p) {
|
||||||
|
// do we want to allow perms to imply type like we do for
|
||||||
|
// qname?
|
||||||
|
if (qtype == mqueue_posix && (mode_p & ~AA_VALID_POSIX_MQ_PERMS)) {
|
||||||
|
yyerror("mode contains invalid permissions for mqueue type=posix\n");
|
||||||
|
} else if (qtype == mqueue_sysv && (mode_p & ~AA_VALID_SYSV_MQ_PERMS)) {
|
||||||
|
yyerror("mode contains invalid permissions for mqueue type=sysv\n");
|
||||||
|
} else if (mode_p & ~AA_VALID_MQUEUE_PERMS) {
|
||||||
|
yyerror("mode contains invalid permissions for mqueue\n");
|
||||||
|
}
|
||||||
|
mode = mode_p;
|
||||||
|
} else {
|
||||||
|
// default to all perms
|
||||||
|
mode = AA_VALID_MQUEUE_PERMS;
|
||||||
|
}
|
||||||
|
qname = qname_p;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ostream &mqueue_rule::dump(ostream &os)
|
||||||
|
{
|
||||||
|
if (audit)
|
||||||
|
os << "audit ";
|
||||||
|
if (deny)
|
||||||
|
os << "deny ";
|
||||||
|
|
||||||
|
os << "mqueue ";
|
||||||
|
|
||||||
|
// do we want to always put type out or leave it implied if there
|
||||||
|
// is a qname
|
||||||
|
if (qtype == mqueue_posix)
|
||||||
|
os << "type=posix";
|
||||||
|
else if (qtype == mqueue_sysv)
|
||||||
|
os << "type=sysv";
|
||||||
|
|
||||||
|
if (mode != AA_VALID_MQUEUE_PERMS) {
|
||||||
|
os << "(";
|
||||||
|
|
||||||
|
if (mode & AA_MQUEUE_WRITE)
|
||||||
|
os << "write ";
|
||||||
|
if (mode & AA_MQUEUE_READ)
|
||||||
|
os << "read ";
|
||||||
|
if (mode & AA_MQUEUE_OPEN)
|
||||||
|
os << "open ";
|
||||||
|
if (mode & AA_MQUEUE_CREATE)
|
||||||
|
os << "create ";
|
||||||
|
if (mode & AA_MQUEUE_DELETE)
|
||||||
|
os << "delete ";
|
||||||
|
if (mode & AA_MQUEUE_SETATTR)
|
||||||
|
os << "setattr ";
|
||||||
|
if (mode & AA_MQUEUE_GETATTR)
|
||||||
|
os << "getattr ";
|
||||||
|
|
||||||
|
os << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qname)
|
||||||
|
os << " " << qname;
|
||||||
|
|
||||||
|
os << ",\n";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mqueue_rule::expand_variables(void)
|
||||||
|
{
|
||||||
|
int error = expand_entry_variables(&qname);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
error = expand_entry_variables(&label);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: this is not right, need separate warning for each type */
|
||||||
|
void mqueue_rule::warn_once(const char *name)
|
||||||
|
{
|
||||||
|
if (qtype == mqueue_unspecified)
|
||||||
|
rule_t::warn_once(name, "mqueue rules not enforced");
|
||||||
|
else if (qtype == mqueue_posix)
|
||||||
|
rule_t::warn_once(name, "mqueue type=posix rules not enforced");
|
||||||
|
else if (qtype == mqueue_sysv)
|
||||||
|
rule_t::warn_once(name, "mqueue type=sysv rules not enforced");
|
||||||
|
}
|
||||||
|
|
||||||
|
int mqueue_rule::gen_policy_re(Profile &prof)
|
||||||
|
{
|
||||||
|
std::string labelbuf;
|
||||||
|
std::string buf;
|
||||||
|
const int size = 2;
|
||||||
|
const char *vec[size];
|
||||||
|
|
||||||
|
|
||||||
|
if (qtype == mqueue_posix && !features_supports_posix_mqueue) {
|
||||||
|
warn_once(prof.name);
|
||||||
|
// return RULE_NOT_SUPPORTED;
|
||||||
|
} else if (qtype == mqueue_sysv && !features_supports_sysv_mqueue) {
|
||||||
|
warn_once(prof.name);
|
||||||
|
// return RULE_NOT_SUPPORTED;
|
||||||
|
} else if (qtype == mqueue_unspecified &&
|
||||||
|
!(features_supports_posix_mqueue ||
|
||||||
|
features_supports_sysv_mqueue)) {
|
||||||
|
warn_once(prof.name);
|
||||||
|
// should split into warning where posix and sysv can
|
||||||
|
// be separated from nothing being enforced
|
||||||
|
// return RULE_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* always generate a label and mqueue entry */
|
||||||
|
|
||||||
|
//buffer << "(" << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_LABEL << "|)"; //is this required?
|
||||||
|
|
||||||
|
// posix and generic
|
||||||
|
if (qtype != mqueue_sysv) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_POSIX_MQUEUE;
|
||||||
|
buf.assign(buffer.str());
|
||||||
|
if (qname) {
|
||||||
|
if (!convert_entry(buf, qname))
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
buf += default_match_pattern;
|
||||||
|
}
|
||||||
|
vec[0] = buf.c_str();
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
if (!convert_entry(labelbuf, label))
|
||||||
|
goto fail;
|
||||||
|
vec[1] = labelbuf.c_str();
|
||||||
|
} else {
|
||||||
|
vec[1] = anyone_match_pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & AA_VALID_POSIX_MQ_PERMS) {
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec,
|
||||||
|
dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// sysv and generic
|
||||||
|
if (qtype != mqueue_posix) {
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_SYSV_MQUEUE;
|
||||||
|
buf.assign(buffer.str());
|
||||||
|
if (qname) {
|
||||||
|
if (!convert_entry(buf, qname))
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
buf += default_match_pattern;
|
||||||
|
}
|
||||||
|
vec[0] = buf.c_str();
|
||||||
|
|
||||||
|
if (label) {
|
||||||
|
if (!convert_entry(labelbuf, label))
|
||||||
|
goto fail;
|
||||||
|
vec[1] = labelbuf.c_str();
|
||||||
|
} else {
|
||||||
|
vec[1] = anyone_match_pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode & AA_VALID_SYSV_MQ_PERMS) {
|
||||||
|
if (!label && !prof.policy.rules->add_rule_vec(deny, mode, audit, 1, vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
/* also provide label match with perm */
|
||||||
|
if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec, dfaflags, false))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RULE_OK;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return RULE_ERROR;
|
||||||
|
}
|
111
parser/mqueue.h
Normal file
111
parser/mqueue.h
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* sysv and posix mqueue mediation. */
|
||||||
|
|
||||||
|
#ifndef __AA_MQUEUE_H
|
||||||
|
#define __AA_MQUEUE_H
|
||||||
|
|
||||||
|
#include "immunix.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#define AA_MQUEUE_WRITE AA_MAY_WRITE
|
||||||
|
#define AA_MQUEUE_READ AA_MAY_READ
|
||||||
|
|
||||||
|
#define AA_MQUEUE_CREATE 0x0010 /* create */
|
||||||
|
#define AA_MQUEUE_DELETE 0x0020 /* destroy, unlink */
|
||||||
|
#define AA_MQUEUE_OPEN 0x0040 /* associate */
|
||||||
|
#define AA_MQUEUE_RENAME 0x0080 /* ?? pair */
|
||||||
|
|
||||||
|
#define AA_MQUEUE_SETATTR 0x0100 /* setattr */
|
||||||
|
#define AA_MQUEUE_GETATTR 0x0200 /* getattr */
|
||||||
|
|
||||||
|
#define AA_MQUEUE_CHMOD 0x1000 /* pair */
|
||||||
|
#define AA_MQUEUE_CHOWN 0x2000 /* pair */
|
||||||
|
#define AA_MQUEUE_CHGRP 0x4000 /* pair */
|
||||||
|
#define AA_MQUEUE_LOCK 0x8000 /* LINK_SUBSET overlaid */
|
||||||
|
|
||||||
|
/* sysv and posix mqueues use different terminology, allow mapping
|
||||||
|
* between. To be as common as possible.
|
||||||
|
*
|
||||||
|
* sysv and posix mqueues have different levels of mediation possible
|
||||||
|
* in the kernel. Only the most basic mqueue rules can be shared
|
||||||
|
* eg.
|
||||||
|
* mqueue rw,
|
||||||
|
* mqueue rw label=foo,
|
||||||
|
*
|
||||||
|
* kernel doesn't allow for us to control
|
||||||
|
* - posix
|
||||||
|
* - notify
|
||||||
|
* - getattr/setattr
|
||||||
|
* - labels at anything other than mqueue label, via mqueue inode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define AA_VALID_POSIX_MQ_PERMS (AA_MQUEUE_WRITE | AA_MQUEUE_READ | \
|
||||||
|
AA_MQUEUE_CREATE | AA_MQUEUE_DELETE | \
|
||||||
|
AA_MQUEUE_OPEN)
|
||||||
|
|
||||||
|
/* TBD - for now make it wider than posix */
|
||||||
|
#define AA_VALID_SYSV_MQ_PERMS (AA_MQUEUE_WRITE | AA_MQUEUE_READ | \
|
||||||
|
AA_MQUEUE_CREATE | AA_MQUEUE_DELETE | \
|
||||||
|
AA_MQUEUE_OPEN | \
|
||||||
|
AA_MQUEUE_SETATTR | AA_MQUEUE_GETATTR)
|
||||||
|
|
||||||
|
#define AA_VALID_MQUEUE_PERMS (AA_VALID_POSIX_MQ_PERMS | \
|
||||||
|
AA_VALID_SYSV_MQ_PERMS)
|
||||||
|
|
||||||
|
// warning getting into overlap area
|
||||||
|
|
||||||
|
/* Type of mqueue - can be explicit or implied by rule id/path */
|
||||||
|
typedef enum mqueue_type {
|
||||||
|
mqueue_unspecified,
|
||||||
|
mqueue_posix,
|
||||||
|
mqueue_sysv
|
||||||
|
} mqueue_type;
|
||||||
|
|
||||||
|
|
||||||
|
int parse_mqueue_mode(const char *str_mode, int *mode, int fail);
|
||||||
|
|
||||||
|
class mqueue_rule: public rule_t {
|
||||||
|
void move_conditionals(struct cond_entry *conds);
|
||||||
|
public:
|
||||||
|
mqueue_type qtype;
|
||||||
|
char *qname;
|
||||||
|
char *label;
|
||||||
|
int mode;
|
||||||
|
int audit;
|
||||||
|
int deny;
|
||||||
|
|
||||||
|
mqueue_rule(int mode, struct cond_entry *conds, char *qname = NULL);
|
||||||
|
virtual ~mqueue_rule()
|
||||||
|
{
|
||||||
|
free(qname);
|
||||||
|
free(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) { };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void warn_once(const char *name) override;
|
||||||
|
void validate_qname(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __AA_MQUEUE_H */
|
@ -345,6 +345,8 @@ extern int features_supports_unix;
|
|||||||
extern int features_supports_stacking;
|
extern int features_supports_stacking;
|
||||||
extern int features_supports_domain_xattr;
|
extern int features_supports_domain_xattr;
|
||||||
extern int features_supports_userns;
|
extern int features_supports_userns;
|
||||||
|
extern int features_supports_posix_mqueue;
|
||||||
|
extern int features_supports_sysv_mqueue;
|
||||||
extern int kernel_supports_oob;
|
extern int kernel_supports_oob;
|
||||||
extern int conf_verbose;
|
extern int conf_verbose;
|
||||||
extern int conf_quiet;
|
extern int conf_quiet;
|
||||||
|
@ -79,6 +79,8 @@ int features_supports_ptrace = 0; /* kernel supports ptrace rules */
|
|||||||
int features_supports_stacking = 0; /* kernel supports stacking */
|
int features_supports_stacking = 0; /* kernel supports stacking */
|
||||||
int features_supports_domain_xattr = 0; /* x attachment cond */
|
int features_supports_domain_xattr = 0; /* x attachment cond */
|
||||||
int features_supports_userns = 0; /* kernel supports user namespace */
|
int features_supports_userns = 0; /* kernel supports user namespace */
|
||||||
|
int features_supports_posix_mqueue = 0; /* kernel supports mqueue rules */
|
||||||
|
int features_supports_sysv_mqueue = 0; /* kernel supports mqueue rules */
|
||||||
int kernel_supports_oob = 0; /* out of band transitions */
|
int kernel_supports_oob = 0; /* out of band transitions */
|
||||||
int conf_verbose = 0;
|
int conf_verbose = 0;
|
||||||
int conf_quiet = 0;
|
int conf_quiet = 0;
|
||||||
|
@ -328,6 +328,7 @@ GT >
|
|||||||
%x INCLUDE_EXISTS
|
%x INCLUDE_EXISTS
|
||||||
%x ABI_MODE
|
%x ABI_MODE
|
||||||
%x USERNS_MODE
|
%x USERNS_MODE
|
||||||
|
%x MQUEUE_MODE
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
@ -340,7 +341,7 @@ GT >
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,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,UNIX_MODE,ABI_MODE,USERNS_MODE>{
|
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,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,UNIX_MODE,ABI_MODE,USERNS_MODE,MQUEUE_MODE>{
|
||||||
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +377,7 @@ GT >
|
|||||||
yyterminate();
|
yyterminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE>{
|
||||||
(peer|xattrs)/{WS}*={WS}*\( {
|
(peer|xattrs)/{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
|
||||||
@ -560,17 +561,25 @@ GT >
|
|||||||
listen { RETURN_TOKEN(TOK_LISTEN); }
|
listen { RETURN_TOKEN(TOK_LISTEN); }
|
||||||
accept { RETURN_TOKEN(TOK_ACCEPT); }
|
accept { RETURN_TOKEN(TOK_ACCEPT); }
|
||||||
connect { RETURN_TOKEN(TOK_CONNECT); }
|
connect { RETURN_TOKEN(TOK_CONNECT); }
|
||||||
getattr { RETURN_TOKEN(TOK_GETATTR); }
|
|
||||||
setattr { RETURN_TOKEN(TOK_SETATTR); }
|
|
||||||
getopt { RETURN_TOKEN(TOK_GETOPT); }
|
getopt { RETURN_TOKEN(TOK_GETOPT); }
|
||||||
setopt { RETURN_TOKEN(TOK_SETOPT); }
|
setopt { RETURN_TOKEN(TOK_SETOPT); }
|
||||||
shutdown { RETURN_TOKEN(TOK_SHUTDOWN); }
|
shutdown { RETURN_TOKEN(TOK_SHUTDOWN); }
|
||||||
}
|
}
|
||||||
|
|
||||||
<UNIX_MODE,USERNS_MODE>{
|
<UNIX_MODE,USERNS_MODE,MQUEUE_MODE>{
|
||||||
create { RETURN_TOKEN(TOK_CREATE); }
|
create { RETURN_TOKEN(TOK_CREATE); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<MQUEUE_MODE>{
|
||||||
|
open { RETURN_TOKEN(TOK_OPEN); }
|
||||||
|
delete { RETURN_TOKEN(TOK_DELETE); }
|
||||||
|
}
|
||||||
|
|
||||||
|
<UNIX_MODE,MQUEUE_MODE>{
|
||||||
|
getattr { RETURN_TOKEN(TOK_GETATTR); }
|
||||||
|
setattr { RETURN_TOKEN(TOK_SETATTR); }
|
||||||
|
}
|
||||||
|
|
||||||
<DBUS_MODE,UNIX_MODE>{
|
<DBUS_MODE,UNIX_MODE>{
|
||||||
bind { RETURN_TOKEN(TOK_BIND); }
|
bind { RETURN_TOKEN(TOK_BIND); }
|
||||||
}
|
}
|
||||||
@ -590,7 +599,7 @@ GT >
|
|||||||
tracedby { RETURN_TOKEN(TOK_TRACEDBY); }
|
tracedby { RETURN_TOKEN(TOK_TRACEDBY); }
|
||||||
}
|
}
|
||||||
|
|
||||||
<DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
<DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_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} {
|
||||||
@ -606,7 +615,7 @@ GT >
|
|||||||
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
|
{ARROW} { RETURN_TOKEN(TOK_ARROW); }
|
||||||
}
|
}
|
||||||
|
|
||||||
<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE>{
|
<MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,MQUEUE_MODE>{
|
||||||
({IDS_NOEQ}|{LABEL}|{QUOTED_ID}) {
|
({IDS_NOEQ}|{LABEL}|{QUOTED_ID}) {
|
||||||
yylval.id = processid(yytext, yyleng);
|
yylval.id = processid(yytext, yyleng);
|
||||||
RETURN_TOKEN(TOK_ID);
|
RETURN_TOKEN(TOK_ID);
|
||||||
@ -731,13 +740,16 @@ include/{WS} {
|
|||||||
case TOK_USERNS:
|
case TOK_USERNS:
|
||||||
state = USERNS_MODE;
|
state = USERNS_MODE;
|
||||||
break;
|
break;
|
||||||
|
case TOK_MQUEUE:
|
||||||
|
state = MQUEUE_MODE;
|
||||||
|
break;
|
||||||
default: /* nothing */
|
default: /* nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PUSH_AND_RETURN(state, token);
|
PUSH_AND_RETURN(state, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,NETWORK_MODE,RLIMIT_MODE,CHANGE_PROFILE_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,ABI_MODE,USERNS_MODE>{
|
<INITIAL,NETWORK_MODE,RLIMIT_MODE,CHANGE_PROFILE_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,ABI_MODE,USERNS_MODE,MQUEUE_MODE>{
|
||||||
{END_OF_RULE} {
|
{END_OF_RULE} {
|
||||||
if (YY_START != INITIAL)
|
if (YY_START != INITIAL)
|
||||||
POP_NODUMP();
|
POP_NODUMP();
|
||||||
@ -745,14 +757,14 @@ include/{WS} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,ABI_MODE,USERNS_MODE>{
|
<INITIAL,SUB_ID_WS,INCLUDE,INCLUDE_EXISTS,LIST_VAL_MODE,EXTCOND_MODE,LIST_COND_VAL,LIST_COND_PAREN_VAL,LIST_COND_MODE,EXTCONDLIST_MODE,NETWORK_MODE,CHANGE_PROFILE_MODE,RLIMIT_MODE,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE,PTRACE_MODE,UNIX_MODE,ABI_MODE,USERNS_MODE,MQUEUE_MODE>{
|
||||||
\r?\n {
|
\r?\n {
|
||||||
DUMP_PREPROCESS;
|
DUMP_PREPROCESS;
|
||||||
current_lineno++;
|
current_lineno++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,SUB_ID,SUB_ID_WS,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,UNIX_MODE,RLIMIT_MODE,INCLUDE,INCLUDE_EXISTS,ABI_MODE,USERNS_MODE>{
|
<INITIAL,SUB_ID,SUB_ID_WS,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,UNIX_MODE,RLIMIT_MODE,INCLUDE,INCLUDE_EXISTS,ABI_MODE,USERNS_MODE,MQUEUE_MODE>{
|
||||||
(.|\n) {
|
(.|\n) {
|
||||||
DUMP_PREPROCESS;
|
DUMP_PREPROCESS;
|
||||||
/* Something we didn't expect */
|
/* Something we didn't expect */
|
||||||
@ -788,4 +800,5 @@ unordered_map<int, string> state_names = {
|
|||||||
STATE_TABLE_ENT(INCLUDE_EXISTS),
|
STATE_TABLE_ENT(INCLUDE_EXISTS),
|
||||||
STATE_TABLE_ENT(ABI_MODE),
|
STATE_TABLE_ENT(ABI_MODE),
|
||||||
STATE_TABLE_ENT(USERNS_MODE),
|
STATE_TABLE_ENT(USERNS_MODE),
|
||||||
|
STATE_TABLE_ENT(MQUEUE_MODE),
|
||||||
};
|
};
|
||||||
|
@ -944,6 +944,12 @@ void set_supported_features()
|
|||||||
features_supports_userns = features_intersect(kernel_features,
|
features_supports_userns = features_intersect(kernel_features,
|
||||||
policy_features,
|
policy_features,
|
||||||
"namespaces/mask/userns_create");
|
"namespaces/mask/userns_create");
|
||||||
|
features_supports_posix_mqueue = features_intersect(kernel_features,
|
||||||
|
policy_features,
|
||||||
|
"ipc/posix_mqueue");
|
||||||
|
features_supports_sysv_mqueue = features_intersect(kernel_features,
|
||||||
|
policy_features,
|
||||||
|
"ipc/sysv_mqueue");
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
|
static bool do_print_cache_dir(aa_features *features, int dirfd, const char *path)
|
||||||
|
@ -121,6 +121,9 @@ static struct keyword_table keyword_table[] = {
|
|||||||
{"readby", TOK_READBY},
|
{"readby", TOK_READBY},
|
||||||
{"abi", TOK_ABI},
|
{"abi", TOK_ABI},
|
||||||
{"userns", TOK_USERNS},
|
{"userns", TOK_USERNS},
|
||||||
|
{"mqueue", TOK_MQUEUE},
|
||||||
|
{"delete", TOK_DELETE},
|
||||||
|
{"open", TOK_OPEN},
|
||||||
|
|
||||||
/* terminate */
|
/* terminate */
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
|
@ -936,6 +936,8 @@ static const char *mediates_extended_net = CLASS_STR(AA_CLASS_NET);
|
|||||||
static const char *mediates_netv8 = CLASS_STR(AA_CLASS_NETV8);
|
static const char *mediates_netv8 = CLASS_STR(AA_CLASS_NETV8);
|
||||||
static const char *mediates_net_unix = CLASS_SUB_STR(AA_CLASS_NET, AF_UNIX);
|
static const char *mediates_net_unix = CLASS_SUB_STR(AA_CLASS_NET, AF_UNIX);
|
||||||
static const char *mediates_ns = CLASS_STR(AA_CLASS_NS);
|
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_sysv_mqueue = CLASS_STR(AA_CLASS_SYSV_MQUEUE);
|
||||||
|
|
||||||
int process_profile_policydb(Profile *prof)
|
int process_profile_policydb(Profile *prof)
|
||||||
{
|
{
|
||||||
@ -981,6 +983,12 @@ int process_profile_policydb(Profile *prof)
|
|||||||
if (features_supports_userns &&
|
if (features_supports_userns &&
|
||||||
!prof->policy.rules->add_rule(mediates_ns, 0, AA_MAY_READ, 0, dfaflags))
|
!prof->policy.rules->add_rule(mediates_ns, 0, AA_MAY_READ, 0, dfaflags))
|
||||||
goto out;
|
goto out;
|
||||||
|
if (features_supports_posix_mqueue &&
|
||||||
|
!prof->policy.rules->add_rule(mediates_posix_mqueue, 0, AA_MAY_READ, 0, dfaflags))
|
||||||
|
goto out;
|
||||||
|
if (features_supports_sysv_mqueue &&
|
||||||
|
!prof->policy.rules->add_rule(mediates_sysv_mqueue, 0, AA_MAY_READ, 0, dfaflags))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (prof->policy.rules->rule_count > 0) {
|
if (prof->policy.rules->rule_count > 0) {
|
||||||
int xmatch_len = 0;
|
int xmatch_len = 0;
|
||||||
|
@ -143,6 +143,8 @@ void add_local_entry(Profile *prof);
|
|||||||
%token TOK_READBY
|
%token TOK_READBY
|
||||||
%token TOK_ABI
|
%token TOK_ABI
|
||||||
%token TOK_USERNS
|
%token TOK_USERNS
|
||||||
|
%token TOK_MQUEUE
|
||||||
|
%token TOK_DELETE
|
||||||
|
|
||||||
/* rlimits */
|
/* rlimits */
|
||||||
%token TOK_RLIMIT
|
%token TOK_RLIMIT
|
||||||
@ -179,6 +181,7 @@ void add_local_entry(Profile *prof);
|
|||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
#include "af_unix.h"
|
#include "af_unix.h"
|
||||||
#include "userns.h"
|
#include "userns.h"
|
||||||
|
#include "mqueue.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
@ -196,6 +199,7 @@ void add_local_entry(Profile *prof);
|
|||||||
ptrace_rule *ptrace_entry;
|
ptrace_rule *ptrace_entry;
|
||||||
unix_rule *unix_entry;
|
unix_rule *unix_entry;
|
||||||
userns_rule *userns_entry;
|
userns_rule *userns_entry;
|
||||||
|
mqueue_rule *mqueue_entry;
|
||||||
|
|
||||||
flagvals flags;
|
flagvals flags;
|
||||||
int fmode;
|
int fmode;
|
||||||
@ -279,6 +283,10 @@ void add_local_entry(Profile *prof);
|
|||||||
%type <fmode> userns_perms
|
%type <fmode> userns_perms
|
||||||
%type <fmode> opt_userns_perm
|
%type <fmode> opt_userns_perm
|
||||||
%type <userns_entry> userns_rule
|
%type <userns_entry> userns_rule
|
||||||
|
%type <fmode> mqueue_perm
|
||||||
|
%type <fmode> mqueue_perms
|
||||||
|
%type <fmode> opt_mqueue_perm
|
||||||
|
%type <mqueue_entry> mqueue_rule
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
||||||
@ -920,6 +928,22 @@ rules: rules opt_prefix capability
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rules: rules opt_prefix mqueue_rule
|
||||||
|
{
|
||||||
|
if ($2.owner)
|
||||||
|
yyerror(_("owner prefix not allowed on mqueue rules")); //is this true?
|
||||||
|
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 hat
|
rules: rules hat
|
||||||
{
|
{
|
||||||
PDEBUG("Matched: hat rule\n");
|
PDEBUG("Matched: hat rule\n");
|
||||||
@ -1591,6 +1615,62 @@ userns_rule: TOK_USERNS opt_userns_perm opt_conds TOK_END_OF_RULE
|
|||||||
$$ = ent;
|
$$ = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mqueue_perm: TOK_VALUE
|
||||||
|
{
|
||||||
|
if (strcmp($1, "create") == 0)
|
||||||
|
$$ = AA_MQUEUE_CREATE;
|
||||||
|
else if (strcmp($1, "open") == 0)
|
||||||
|
$$ = AA_MQUEUE_OPEN;
|
||||||
|
else if (strcmp($1, "delete") == 0)
|
||||||
|
$$ = AA_MQUEUE_DELETE;
|
||||||
|
else if (strcmp($1, "getattr") == 0)
|
||||||
|
$$ = AA_MQUEUE_GETATTR;
|
||||||
|
else if (strcmp($1, "setattr") == 0)
|
||||||
|
$$ = AA_MQUEUE_SETATTR;
|
||||||
|
else if (strcmp($1, "write") == 0)
|
||||||
|
$$ = AA_MQUEUE_WRITE;
|
||||||
|
else if (strcmp($1, "read") == 0)
|
||||||
|
$$ = AA_MQUEUE_READ;
|
||||||
|
else if ($1) {
|
||||||
|
parse_mqueue_mode($1, &$$, 1);
|
||||||
|
} else
|
||||||
|
$$ = 0;
|
||||||
|
|
||||||
|
if ($1)
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
|
| TOK_CREATE { $$ = AA_MQUEUE_CREATE; }
|
||||||
|
| TOK_OPEN { $$ = AA_MQUEUE_OPEN; }
|
||||||
|
| TOK_DELETE { $$ = AA_MQUEUE_DELETE; }
|
||||||
|
| TOK_GETATTR { $$ = AA_MQUEUE_GETATTR; }
|
||||||
|
| TOK_SETATTR { $$ = AA_MQUEUE_SETATTR; }
|
||||||
|
| TOK_WRITE { $$ = AA_MQUEUE_WRITE; }
|
||||||
|
| TOK_READ { $$ = AA_MQUEUE_READ; }
|
||||||
|
| TOK_MODE
|
||||||
|
{
|
||||||
|
parse_mqueue_mode($1, &$$, 1);
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mqueue_perms: { /* nothing */ $$ = 0; }
|
||||||
|
| mqueue_perms mqueue_perm { $$ = $1 | $2; }
|
||||||
|
| mqueue_perms TOK_COMMA mqueue_perm { $$ = $1 | $3; }
|
||||||
|
|
||||||
|
opt_mqueue_perm: { /* nothing */ $$ = 0; }
|
||||||
|
| mqueue_perm { $$ = $1; }
|
||||||
|
| TOK_OPENPAREN mqueue_perms TOK_CLOSEPAREN { $$ = $2; }
|
||||||
|
|
||||||
|
mqueue_rule: TOK_MQUEUE opt_mqueue_perm opt_conds TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
mqueue_rule *ent = new mqueue_rule($2, $3);
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
| TOK_MQUEUE opt_mqueue_perm opt_conds TOK_ID TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
mqueue_rule *ent = new mqueue_rule($2, $3, $4);
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
|
||||||
hat_start: TOK_CARET {}
|
hat_start: TOK_CARET {}
|
||||||
| TOK_HAT {}
|
| TOK_HAT {}
|
||||||
|
|
||||||
|
@ -34,6 +34,8 @@
|
|||||||
#define AA_CLASS_SIGNAL 10
|
#define AA_CLASS_SIGNAL 10
|
||||||
#define AA_CLASS_NETV8 14
|
#define AA_CLASS_NETV8 14
|
||||||
#define AA_CLASS_LABEL 16
|
#define AA_CLASS_LABEL 16
|
||||||
|
#define AA_CLASS_POSIX_MQUEUE 17
|
||||||
|
#define AA_CLASS_SYSV_MQUEUE 18
|
||||||
#define AA_CLASS_NS 21
|
#define AA_CLASS_NS 21
|
||||||
|
|
||||||
/* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */
|
/* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user