mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 10:07:12 +00:00
parser: Add support for DBus rules
This patch implements the parsing of DBus rules. It attempts to catch all corner cases, such as specifying a bind permission with an interface conditional or specifying a subject name conditional and a peer name conditional in the same rule. It introduces the concept of conditional lists to the lexer and parser in order to handle 'peer=(label=/usr/bin/foo name=com.foo.bar)', since the existing list support in the lexer only supports a list of values. The DBus rules are encoded as follows: bus,name<bind_perm>,peer_label,path,interface,member<rw_perms> Bind rules stop matching at name<bind_perm>. Note that name is used for the subject name in bind rules and the peer name in rw rules. The function new_dbus_entry() is what does the proper sanitization to make sure that if a name conditional is specified, that it is the subject name in the case of a bind rule or that it is the peer name in the case of a rw rule. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: Seth Arnold <seth.arnold@canonical.com>
This commit is contained in:
parent
1aba3394a3
commit
ab84444d3a
@ -76,8 +76,8 @@ EXTRA_CFLAGS+=-DSUBDOMAIN_CONFDIR=\"${CONFDIR}\"
|
|||||||
SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \
|
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 lib.c
|
parser_alias.c mount.c dbus.c lib.c
|
||||||
HDRS = parser.h parser_include.h immunix.h mount.h lib.h
|
HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h
|
||||||
TOOLS = apparmor_parser
|
TOOLS = apparmor_parser
|
||||||
|
|
||||||
OBJECTS = $(SRCS:.c=.o)
|
OBJECTS = $(SRCS:.c=.o)
|
||||||
@ -207,6 +207,9 @@ mount.o: mount.c mount.h parser.h immunix.h
|
|||||||
lib.o: lib.c lib.h parser.h
|
lib.o: lib.c lib.h parser.h
|
||||||
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
|
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
dbus.o: dbus.c dbus.h parser.h immunix.h
|
||||||
|
$(CC) $(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 $@
|
||||||
|
183
parser/dbus.c
Normal file
183
parser/dbus.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013
|
||||||
|
* 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 "parser.h"
|
||||||
|
#include "parser_yacc.h"
|
||||||
|
#include "dbus.h"
|
||||||
|
|
||||||
|
void free_dbus_entry(struct dbus_entry *ent)
|
||||||
|
{
|
||||||
|
if (!ent)
|
||||||
|
return;
|
||||||
|
free(ent->bus);
|
||||||
|
free(ent->name);
|
||||||
|
free(ent->peer_label);
|
||||||
|
free(ent->path);
|
||||||
|
free(ent->interface);
|
||||||
|
free(ent->member);
|
||||||
|
|
||||||
|
free(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int list_len(struct value_list *v)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
struct value_list *tmp;
|
||||||
|
|
||||||
|
list_for_each(v, tmp)
|
||||||
|
len++;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent)
|
||||||
|
{
|
||||||
|
if (*dst_ptr)
|
||||||
|
yyerror("dbus conditional \"%s\" can only be specified once\n",
|
||||||
|
cond_ent->name);
|
||||||
|
|
||||||
|
*dst_ptr = cond_ent->vals->value;
|
||||||
|
cond_ent->vals->value = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void move_conditionals(struct dbus_entry *ent, 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 dbus rules\n");
|
||||||
|
if (list_len(cond_ent->vals) > 1)
|
||||||
|
yyerror("dbus conditional \"%s\" only supports a single value\n",
|
||||||
|
cond_ent->name);
|
||||||
|
|
||||||
|
if (strcmp(cond_ent->name, "bus") == 0) {
|
||||||
|
move_conditional_value(&ent->bus, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "name") == 0) {
|
||||||
|
move_conditional_value(&ent->name, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "label") == 0) {
|
||||||
|
move_conditional_value(&ent->peer_label, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "path") == 0) {
|
||||||
|
move_conditional_value(&ent->path, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "interface") == 0) {
|
||||||
|
move_conditional_value(&ent->interface, cond_ent);
|
||||||
|
} else if (strcmp(cond_ent->name, "member") == 0) {
|
||||||
|
move_conditional_value(&ent->member, cond_ent);
|
||||||
|
} else {
|
||||||
|
yyerror("invalid dbus conditional \"%s\"\n",
|
||||||
|
cond_ent->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds,
|
||||||
|
struct cond_entry *peer_conds)
|
||||||
|
{
|
||||||
|
struct dbus_entry *ent;
|
||||||
|
int name_is_subject_cond = 0, message_rule = 0, service_rule = 0;
|
||||||
|
|
||||||
|
ent = (struct dbus_entry*) calloc(1, sizeof(struct dbus_entry));
|
||||||
|
if (!ent)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Move the global/subject conditionals over & check the results */
|
||||||
|
move_conditionals(ent, conds);
|
||||||
|
if (ent->name)
|
||||||
|
name_is_subject_cond = 1;
|
||||||
|
if (ent->peer_label)
|
||||||
|
yyerror("dbus \"label\" conditional can only be used inside of the \"peer=()\" grouping\n");
|
||||||
|
|
||||||
|
/* Move the peer conditionals */
|
||||||
|
move_conditionals(ent, peer_conds);
|
||||||
|
|
||||||
|
if (ent->path || ent->interface || ent->member || ent->peer_label ||
|
||||||
|
(ent->name && !name_is_subject_cond))
|
||||||
|
message_rule = 1;
|
||||||
|
|
||||||
|
if (ent->name && name_is_subject_cond)
|
||||||
|
service_rule = 1;
|
||||||
|
|
||||||
|
if (message_rule && service_rule)
|
||||||
|
yyerror("dbus rule contains message conditionals and service conditionals\n");
|
||||||
|
|
||||||
|
/* Copy mode. If no mode was specified, assign an implied mode. */
|
||||||
|
if (mode) {
|
||||||
|
ent->mode = mode;
|
||||||
|
if (ent->mode & ~AA_VALID_DBUS_PERMS)
|
||||||
|
yyerror("mode contains unknown dbus accesss\n");
|
||||||
|
else if (message_rule && (ent->mode & AA_DBUS_BIND))
|
||||||
|
yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n");
|
||||||
|
else if (service_rule && (ent->mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)))
|
||||||
|
yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n");
|
||||||
|
} else {
|
||||||
|
ent->mode = AA_VALID_DBUS_PERMS;
|
||||||
|
if (message_rule)
|
||||||
|
ent->mode &= ~AA_DBUS_BIND;
|
||||||
|
else if (service_rule)
|
||||||
|
ent->mode &= ~(AA_DBUS_SEND | AA_DBUS_RECEIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free_cond_list(conds);
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void print_dbus_entry(struct dbus_entry *ent)
|
||||||
|
{
|
||||||
|
if (ent->audit)
|
||||||
|
fprintf(stderr, "audit ");
|
||||||
|
if (ent->deny)
|
||||||
|
fprintf(stderr, "deny ");
|
||||||
|
|
||||||
|
fprintf(stderr, "dbus ( ");
|
||||||
|
|
||||||
|
if (ent->mode & AA_DBUS_SEND)
|
||||||
|
fprintf(stderr, "send ");
|
||||||
|
if (ent->mode & AA_DBUS_RECEIVE)
|
||||||
|
fprintf(stderr, "receive ");
|
||||||
|
if (ent->mode & AA_DBUS_BIND)
|
||||||
|
fprintf(stderr, "bind ");
|
||||||
|
fprintf(stderr, ")");
|
||||||
|
|
||||||
|
if (ent->bus)
|
||||||
|
fprintf(stderr, " bus=\"%s\"", ent->bus);
|
||||||
|
if ((ent->mode & AA_DBUS_BIND) && ent->name)
|
||||||
|
fprintf(stderr, " name=\"%s\"", ent->name);
|
||||||
|
if (ent->path)
|
||||||
|
fprintf(stderr, " path=\"%s\"", ent->path);
|
||||||
|
if (ent->interface)
|
||||||
|
fprintf(stderr, " interface=\"%s\"", ent->interface);
|
||||||
|
if (ent->member)
|
||||||
|
fprintf(stderr, " member=\"%s\"", ent->member);
|
||||||
|
|
||||||
|
if (!(ent->mode & AA_DBUS_BIND) && (ent->peer_label || ent->name)) {
|
||||||
|
fprintf(stderr, " peer=( ");
|
||||||
|
if (ent->peer_label)
|
||||||
|
fprintf(stderr, "label=\"%s\" ", ent->peer_label);
|
||||||
|
if (ent->name)
|
||||||
|
fprintf(stderr, "name=\"%s\" ", ent->name);
|
||||||
|
fprintf(stderr, ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, ",\n");
|
||||||
|
}
|
48
parser/dbus.h
Normal file
48
parser/dbus.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013
|
||||||
|
* 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_DBUS_H
|
||||||
|
#define __AA_DBUS_H
|
||||||
|
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
struct dbus_entry {
|
||||||
|
char *bus;
|
||||||
|
/**
|
||||||
|
* Be careful! ->name can be the subject or the peer name, depending on
|
||||||
|
* whether the rule is a bind rule or a send/receive rule. See the
|
||||||
|
* comments in new_dbus_entry() for details.
|
||||||
|
*/
|
||||||
|
char *name;
|
||||||
|
char *peer_label;
|
||||||
|
char *path;
|
||||||
|
char *interface;
|
||||||
|
char *member;
|
||||||
|
int mode;
|
||||||
|
int audit;
|
||||||
|
int deny;
|
||||||
|
|
||||||
|
struct dbus_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
void free_dbus_entry(struct dbus_entry *ent);
|
||||||
|
struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds,
|
||||||
|
struct cond_entry *peer_conds);
|
||||||
|
void print_dbus_entry(struct dbus_entry *ent);
|
||||||
|
|
||||||
|
#endif /* __AA_DBUS_H */
|
@ -40,6 +40,13 @@
|
|||||||
#define AA_EXEC_MOD_2 (1 << 12)
|
#define AA_EXEC_MOD_2 (1 << 12)
|
||||||
#define AA_EXEC_MOD_3 (1 << 13)
|
#define AA_EXEC_MOD_3 (1 << 13)
|
||||||
|
|
||||||
|
#define AA_DBUS_SEND AA_MAY_WRITE
|
||||||
|
#define AA_DBUS_RECEIVE AA_MAY_READ
|
||||||
|
#define AA_DBUS_BIND (1 << 6)
|
||||||
|
|
||||||
|
#define AA_VALID_DBUS_PERMS (AA_DBUS_SEND | AA_DBUS_RECEIVE | \
|
||||||
|
AA_DBUS_BIND)
|
||||||
|
|
||||||
#define AA_BASE_PERMS (AA_MAY_EXEC | AA_MAY_WRITE | \
|
#define AA_BASE_PERMS (AA_MAY_EXEC | AA_MAY_WRITE | \
|
||||||
AA_MAY_READ | AA_MAY_APPEND | \
|
AA_MAY_READ | AA_MAY_APPEND | \
|
||||||
AA_MAY_LINK | AA_MAY_LOCK | \
|
AA_MAY_LINK | AA_MAY_LOCK | \
|
||||||
|
@ -142,6 +142,7 @@ struct codomain {
|
|||||||
|
|
||||||
char *exec_table[AA_EXEC_COUNT];
|
char *exec_table[AA_EXEC_COUNT];
|
||||||
struct cod_entry *entries;
|
struct cod_entry *entries;
|
||||||
|
struct dbus_entry *dbus_ents;
|
||||||
struct mnt_entry *mnt_ents;
|
struct mnt_entry *mnt_ents;
|
||||||
|
|
||||||
void *hat_table;
|
void *hat_table;
|
||||||
@ -301,6 +302,8 @@ extern char *basedir;
|
|||||||
/* parser_regex.c */
|
/* parser_regex.c */
|
||||||
extern int process_regex(struct codomain *cod);
|
extern int process_regex(struct codomain *cod);
|
||||||
extern int post_process_entry(struct cod_entry *entry);
|
extern int post_process_entry(struct cod_entry *entry);
|
||||||
|
extern int process_dbus(struct codomain *cod);
|
||||||
|
|
||||||
extern void reset_regex(void);
|
extern void reset_regex(void);
|
||||||
|
|
||||||
extern int process_policydb(struct codomain *cod);
|
extern int process_policydb(struct codomain *cod);
|
||||||
@ -319,6 +322,7 @@ extern void free_value_list(struct value_list *list);
|
|||||||
extern void print_value_list(struct value_list *list);
|
extern void print_value_list(struct value_list *list);
|
||||||
extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list);
|
extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list);
|
||||||
extern void free_cond_entry(struct cond_entry *ent);
|
extern void free_cond_entry(struct cond_entry *ent);
|
||||||
|
extern void free_cond_list(struct cond_entry *ents);
|
||||||
extern void print_cond_entry(struct cond_entry *ent);
|
extern void print_cond_entry(struct cond_entry *ent);
|
||||||
extern char *processid(char *string, int len);
|
extern char *processid(char *string, int len);
|
||||||
extern char *processquoted(char *string, int len);
|
extern char *processquoted(char *string, int len);
|
||||||
@ -328,6 +332,7 @@ extern int name_to_capability(const char *keyword);
|
|||||||
extern int get_rlimit(const char *name);
|
extern int get_rlimit(const char *name);
|
||||||
extern char *process_var(const char *var);
|
extern char *process_var(const char *var);
|
||||||
extern int parse_mode(const char *mode);
|
extern int parse_mode(const char *mode);
|
||||||
|
extern int parse_dbus_mode(const char *str_mode, int *mode, int fail);
|
||||||
extern struct cod_entry *new_entry(char *namespace, char *id, int mode,
|
extern struct cod_entry *new_entry(char *namespace, char *id, int mode,
|
||||||
char *link_id);
|
char *link_id);
|
||||||
extern struct aa_network_entry *new_network_ent(unsigned int family,
|
extern struct aa_network_entry *new_network_ent(unsigned int family,
|
||||||
@ -344,6 +349,7 @@ extern int str_to_boolean(const char* str);
|
|||||||
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);
|
||||||
extern void free_mnt_entries(struct mnt_entry *list);
|
extern void free_mnt_entries(struct mnt_entry *list);
|
||||||
|
extern void free_dbus_entries(struct dbus_entry *list);
|
||||||
|
|
||||||
/* parser_symtab.c */
|
/* parser_symtab.c */
|
||||||
struct set_value {;
|
struct set_value {;
|
||||||
@ -385,6 +391,7 @@ extern void post_process_file_entries(struct codomain *cod);
|
|||||||
extern void post_process_mnt_entries(struct codomain *cod);
|
extern void post_process_mnt_entries(struct codomain *cod);
|
||||||
extern int post_process_policy(int debug_only);
|
extern int post_process_policy(int debug_only);
|
||||||
extern int process_hat_regex(struct codomain *cod);
|
extern int process_hat_regex(struct codomain *cod);
|
||||||
|
extern int process_hat_dbus(struct codomain *cod);
|
||||||
extern int process_hat_variables(struct codomain *cod);
|
extern int process_hat_variables(struct codomain *cod);
|
||||||
extern int process_hat_policydb(struct codomain *cod);
|
extern int process_hat_policydb(struct codomain *cod);
|
||||||
extern int post_merge_rules(void);
|
extern int post_merge_rules(void);
|
||||||
|
@ -53,6 +53,12 @@
|
|||||||
#define NPDEBUG(fmt, args...) /* Do nothing */
|
#define NPDEBUG(fmt, args...) /* Do nothing */
|
||||||
|
|
||||||
#define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
|
#define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
|
||||||
|
#define RETURN_TOKEN(X) \
|
||||||
|
do { \
|
||||||
|
DUMP_PREPROCESS; \
|
||||||
|
PDEBUG("Matched: %s\n", yytext); \
|
||||||
|
return (X); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define YY_NO_INPUT
|
#define YY_NO_INPUT
|
||||||
|
|
||||||
@ -198,9 +204,11 @@ POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
|
|||||||
POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS})
|
POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS})
|
||||||
LIST_VALUE_ID_CHARS [^ \t\n"!,]{-}[()]
|
LIST_VALUE_ID_CHARS [^ \t\n"!,]{-}[()]
|
||||||
LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+
|
LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+
|
||||||
|
QUOTED_LIST_VALUE_ID {LIST_VALUE_ID}|\"{LIST_VALUE_ID}\"
|
||||||
ID_CHARS_NOEQ [^ \t\n"!,]{-}[=]
|
ID_CHARS_NOEQ [^ \t\n"!,]{-}[=]
|
||||||
|
LEADING_ID_CHARS_NOEQ [^ \t\n"!,]{-}[=()]
|
||||||
ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ})
|
ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ})
|
||||||
IDS_NOEQ {ID_NOEQ}+
|
IDS_NOEQ {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}*
|
||||||
ALLOWED_QUOTED_ID [^\0"]|\\\"
|
ALLOWED_QUOTED_ID [^\0"]|\\\"
|
||||||
QUOTED_ID \"{ALLOWED_QUOTED_ID}*\"
|
QUOTED_ID \"{ALLOWED_QUOTED_ID}*\"
|
||||||
|
|
||||||
@ -228,11 +236,16 @@ LT_EQUAL <=
|
|||||||
%x SUB_ID
|
%x SUB_ID
|
||||||
%x SUB_VALUE
|
%x SUB_VALUE
|
||||||
%x EXTCOND_MODE
|
%x EXTCOND_MODE
|
||||||
|
%x EXTCONDLIST_MODE
|
||||||
%x NETWORK_MODE
|
%x NETWORK_MODE
|
||||||
%x LIST_VAL_MODE
|
%x LIST_VAL_MODE
|
||||||
|
%x LIST_COND_MODE
|
||||||
|
%x LIST_COND_VAL
|
||||||
|
%x LIST_COND_PAREN_VAL
|
||||||
%x ASSIGN_MODE
|
%x ASSIGN_MODE
|
||||||
%x RLIMIT_MODE
|
%x RLIMIT_MODE
|
||||||
%x MOUNT_MODE
|
%x MOUNT_MODE
|
||||||
|
%x DBUS_MODE
|
||||||
%x CHANGE_PROFILE_MODE
|
%x CHANGE_PROFILE_MODE
|
||||||
%x INCLUDE
|
%x INCLUDE
|
||||||
|
|
||||||
@ -278,7 +291,7 @@ LT_EQUAL <=
|
|||||||
if ( !YY_CURRENT_BUFFER ) yyterminate();
|
if ( !YY_CURRENT_BUFFER ) yyterminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,MOUNT_MODE>{
|
<INITIAL,MOUNT_MODE,DBUS_MODE>{
|
||||||
{VARIABLE_NAME}/{WS}*= {
|
{VARIABLE_NAME}/{WS}*= {
|
||||||
/* we match to the = in the lexer so that
|
/* we match to the = in the lexer so that
|
||||||
* can switch scanner state. By the time
|
* can switch scanner state. By the time
|
||||||
@ -286,11 +299,19 @@ LT_EQUAL <=
|
|||||||
* as bison may have requested the next
|
* as bison may have requested the next
|
||||||
* token from the scanner
|
* token from the scanner
|
||||||
*/
|
*/
|
||||||
|
int token = get_keyword_token(yytext);
|
||||||
|
|
||||||
DUMP_PREPROCESS;
|
DUMP_PREPROCESS;
|
||||||
PDEBUG("conditional %s=\n", yytext);
|
if (token == TOK_PEER) {
|
||||||
yylval.id = processid(yytext, yyleng);
|
PDEBUG("conditional list %s=\n", yytext);
|
||||||
yy_push_state(EXTCOND_MODE);
|
yy_push_state(EXTCONDLIST_MODE);
|
||||||
return TOK_CONDID;
|
return TOK_CONDLISTID;
|
||||||
|
} else {
|
||||||
|
PDEBUG("conditional %s=\n", yytext);
|
||||||
|
yylval.id = processid(yytext, yyleng);
|
||||||
|
yy_push_state(EXTCOND_MODE);
|
||||||
|
return TOK_CONDID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{VARIABLE_NAME}/{WS}+in{WS}*\( {
|
{VARIABLE_NAME}/{WS}+in{WS}*\( {
|
||||||
/* we match to 'in' in the lexer so that
|
/* we match to 'in' in the lexer so that
|
||||||
@ -422,6 +443,116 @@ LT_EQUAL <=
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<LIST_COND_VAL>{
|
||||||
|
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
||||||
|
|
||||||
|
({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
yylval.id = processid(yytext, yyleng);
|
||||||
|
PDEBUG("listcond value: \"%s\"\n", yylval.id);
|
||||||
|
yy_pop_state();
|
||||||
|
return TOK_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[^\n] {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
/* Something we didn't expect */
|
||||||
|
yyerror(_("Found unexpected character: '%s'"), yytext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<LIST_COND_PAREN_VAL>{
|
||||||
|
{CLOSE_PAREN} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
yy_pop_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
||||||
|
|
||||||
|
({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
yylval.id = processid(yytext, yyleng);
|
||||||
|
PDEBUG("listcond paren value: \"%s\"\n", yylval.id);
|
||||||
|
return TOK_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[^\n] {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
/* Something we didn't expect */
|
||||||
|
yyerror(_("Found unexpected character: '%s'"), yytext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<LIST_COND_MODE>{
|
||||||
|
{CLOSE_PAREN} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
PDEBUG("listcond: )\n");
|
||||||
|
yy_pop_state();
|
||||||
|
return TOK_CLOSEPAREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
||||||
|
|
||||||
|
{COMMA} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
PDEBUG("listcond: , \n");
|
||||||
|
/* Eat comma, its an optional separator */
|
||||||
|
}
|
||||||
|
|
||||||
|
{ID_CHARS_NOEQ}+ {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
PDEBUG("listcond conditional %s=\n", yytext);
|
||||||
|
yylval.id = processid(yytext, yyleng);
|
||||||
|
return TOK_CONDID;
|
||||||
|
}
|
||||||
|
|
||||||
|
{EQUALS}{WS}*{OPEN_PAREN} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
yy_push_state(LIST_COND_PAREN_VAL);
|
||||||
|
return TOK_EQUALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
{EQUALS} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
yy_push_state(LIST_COND_VAL);
|
||||||
|
return TOK_EQUALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
[^\n] {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
/* Something we didn't expect */
|
||||||
|
yyerror(_("Found unexpected character: '%s'"), yytext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<EXTCONDLIST_MODE>{
|
||||||
|
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
||||||
|
|
||||||
|
{EQUALS} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
return TOK_EQUALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
{OPEN_PAREN} {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
PDEBUG("extcondlist (\n");
|
||||||
|
/* Don't push state here as this is a transition
|
||||||
|
* start condition and we want to return to the start
|
||||||
|
* condition that invoked <EXTCONDLIST_MODE> when
|
||||||
|
* LIST_VAL_ID is done
|
||||||
|
*/
|
||||||
|
BEGIN(LIST_COND_MODE);
|
||||||
|
return TOK_OPENPAREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
[^\n] {
|
||||||
|
DUMP_PREPROCESS;
|
||||||
|
/* Something we didn't expect */
|
||||||
|
yyerror(_("Found unexpected character: '%s' %d"), yytext, *yytext);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
<ASSIGN_MODE>{
|
<ASSIGN_MODE>{
|
||||||
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
|
||||||
|
|
||||||
@ -547,7 +678,23 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<MOUNT_MODE>{
|
<DBUS_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); }
|
||||||
|
{OPEN_PAREN} {
|
||||||
|
yy_push_state(LIST_VAL_MODE);
|
||||||
|
RETURN_TOKEN(TOK_OPENPAREN);
|
||||||
|
}
|
||||||
|
(r|w|rw|wr)/([[:space:],]) {
|
||||||
|
yylval.mode = strdup(yytext);
|
||||||
|
RETURN_TOKEN(TOK_MODE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<MOUNT_MODE,DBUS_MODE>{
|
||||||
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
|
||||||
|
|
||||||
{ARROW} {
|
{ARROW} {
|
||||||
@ -709,6 +856,10 @@ LT_EQUAL <=
|
|||||||
PDEBUG("Entering mount\n");
|
PDEBUG("Entering mount\n");
|
||||||
yy_push_state(MOUNT_MODE);
|
yy_push_state(MOUNT_MODE);
|
||||||
break;
|
break;
|
||||||
|
case TOK_DBUS:
|
||||||
|
PDEBUG("Entering dbus\n");
|
||||||
|
yy_push_state(DBUS_MODE);
|
||||||
|
break;
|
||||||
default: /* nothing */
|
default: /* nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "parser_yacc.h"
|
#include "parser_yacc.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
#include "dbus.h"
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -85,6 +86,14 @@ static struct keyword_table keyword_table[] = {
|
|||||||
{"unmount", TOK_UMOUNT},
|
{"unmount", TOK_UMOUNT},
|
||||||
{"pivot_root", TOK_PIVOTROOT},
|
{"pivot_root", TOK_PIVOTROOT},
|
||||||
{"in", TOK_IN},
|
{"in", TOK_IN},
|
||||||
|
{"dbus", TOK_DBUS},
|
||||||
|
{"send", TOK_SEND},
|
||||||
|
{"receive", TOK_RECEIVE},
|
||||||
|
{"bind", TOK_BIND},
|
||||||
|
{"read", TOK_READ},
|
||||||
|
{"write", TOK_WRITE},
|
||||||
|
{"peer", TOK_PEER},
|
||||||
|
|
||||||
/* terminate */
|
/* terminate */
|
||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
@ -724,6 +733,81 @@ int parse_mode(const char *str_mode)
|
|||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused)
|
||||||
|
{
|
||||||
|
int mode = 0;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
PDEBUG("Parsing DBus mode: %s\n", str_mode);
|
||||||
|
|
||||||
|
if (!str_mode)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p = str_mode;
|
||||||
|
while (*p) {
|
||||||
|
char this = *p;
|
||||||
|
char lower;
|
||||||
|
|
||||||
|
reeval:
|
||||||
|
switch (this) {
|
||||||
|
case COD_READ_CHAR:
|
||||||
|
PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc);
|
||||||
|
mode |= AA_DBUS_RECEIVE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COD_WRITE_CHAR:
|
||||||
|
PDEBUG("Parsing DBus mode: found %s WRITE\n",
|
||||||
|
mode_desc);
|
||||||
|
mode |= AA_DBUS_SEND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* error cases */
|
||||||
|
|
||||||
|
default:
|
||||||
|
lower = tolower(this);
|
||||||
|
switch (lower) {
|
||||||
|
case COD_READ_CHAR:
|
||||||
|
case COD_WRITE_CHAR:
|
||||||
|
PDEBUG("Parsing DBus mode: found invalid upper case char %c\n",
|
||||||
|
this);
|
||||||
|
warn_uppercase();
|
||||||
|
this = lower;
|
||||||
|
goto reeval;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (fail)
|
||||||
|
yyerror(_("Internal: unexpected DBus mode character '%c' in input"),
|
||||||
|
this);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode);
|
||||||
|
|
||||||
|
*result = mode;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_dbus_mode(const char *str_mode, int *mode, int fail)
|
||||||
|
{
|
||||||
|
*mode = 0;
|
||||||
|
if (!parse_dbus_sub_mode(str_mode, mode, fail, ""))
|
||||||
|
return 0;
|
||||||
|
if (*mode & ~AA_VALID_DBUS_PERMS) {
|
||||||
|
if (fail)
|
||||||
|
yyerror(_("Internal error generated invalid DBus perm 0x%x\n"),
|
||||||
|
mode);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct cod_entry *new_entry(char *namespace, char *id, int mode, char *link_id)
|
struct cod_entry *new_entry(char *namespace, char *id, int mode, char *link_id)
|
||||||
{
|
{
|
||||||
struct cod_entry *entry = NULL;
|
struct cod_entry *entry = NULL;
|
||||||
@ -803,6 +887,16 @@ void free_mnt_entries(struct mnt_entry *list)
|
|||||||
free(list);
|
free(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_dbus_entries(struct dbus_entry *list)
|
||||||
|
{
|
||||||
|
if (!list)
|
||||||
|
return;
|
||||||
|
if (list->next)
|
||||||
|
free_dbus_entries(list->next);
|
||||||
|
|
||||||
|
free_dbus_entry(list);
|
||||||
|
}
|
||||||
|
|
||||||
static void debug_base_perm_mask(int mask)
|
static void debug_base_perm_mask(int mask)
|
||||||
{
|
{
|
||||||
if (HAS_MAY_READ(mask))
|
if (HAS_MAY_READ(mask))
|
||||||
@ -1148,6 +1242,15 @@ void free_cond_entry(struct cond_entry *ent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_cond_list(struct cond_entry *ents)
|
||||||
|
{
|
||||||
|
struct cond_entry *entry, *tmp;
|
||||||
|
|
||||||
|
list_for_each_safe(ents, entry, tmp) {
|
||||||
|
free_cond_entry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print_cond_entry(struct cond_entry *ent)
|
void print_cond_entry(struct cond_entry *ent)
|
||||||
{
|
{
|
||||||
if (ent) {
|
if (ent) {
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
#include "dbus.h"
|
||||||
#include "parser_yacc.h"
|
#include "parser_yacc.h"
|
||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
@ -818,6 +819,7 @@ void free_policy(struct codomain *cod)
|
|||||||
free_hat_table(cod->hat_table);
|
free_hat_table(cod->hat_table);
|
||||||
free_cod_entries(cod->entries);
|
free_cod_entries(cod->entries);
|
||||||
free_mnt_entries(cod->mnt_ents);
|
free_mnt_entries(cod->mnt_ents);
|
||||||
|
free_dbus_entries(cod->dbus_ents);
|
||||||
if (cod->dfarules)
|
if (cod->dfarules)
|
||||||
aare_delete_ruleset(cod->dfarules);
|
aare_delete_ruleset(cod->dfarules);
|
||||||
if (cod->dfa)
|
if (cod->dfa)
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "libapparmor_re/apparmor_re.h"
|
#include "libapparmor_re/apparmor_re.h"
|
||||||
#include "libapparmor_re/aare_rules.h"
|
#include "libapparmor_re/aare_rules.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
#include "dbus.h"
|
||||||
#include "policydb.h"
|
#include "policydb.h"
|
||||||
|
|
||||||
enum error_type {
|
enum error_type {
|
||||||
@ -1041,7 +1042,107 @@ fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int post_process_policydb_ents(struct codomain *cod)
|
static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry)
|
||||||
|
{
|
||||||
|
char busbuf[PATH_MAX + 3];
|
||||||
|
char namebuf[PATH_MAX + 3];
|
||||||
|
char peer_labelbuf[PATH_MAX + 3];
|
||||||
|
char pathbuf[PATH_MAX + 3];
|
||||||
|
char ifacebuf[PATH_MAX + 3];
|
||||||
|
char memberbuf[PATH_MAX + 3];
|
||||||
|
char *p, *vec[6];
|
||||||
|
|
||||||
|
pattern_t ptype;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (!entry) /* shouldn't happen */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
p = busbuf;
|
||||||
|
p += sprintf(p, "\\x%02x", AA_CLASS_DBUS);
|
||||||
|
|
||||||
|
if (entry->bus) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->bus, 0, p,
|
||||||
|
PATH_MAX+3 - (p - busbuf), &pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
strcpy(p, "[^\\000]*");
|
||||||
|
}
|
||||||
|
vec[0] = busbuf;
|
||||||
|
|
||||||
|
if (entry->name) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf,
|
||||||
|
PATH_MAX+3, &pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
vec[1] = namebuf;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
vec[1] = "[^\\000]*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->peer_label) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->peer_label, 0,
|
||||||
|
peer_labelbuf, PATH_MAX+3,
|
||||||
|
&pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
vec[2] = peer_labelbuf;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
vec[2] = "[^\\000]*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->path) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf,
|
||||||
|
PATH_MAX+3, &pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
vec[3] = pathbuf;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
vec[3] = "[^\\000]*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->interface) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf,
|
||||||
|
PATH_MAX+3, &pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
vec[4] = ifacebuf;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
vec[4] = "[^\\000]*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->member) {
|
||||||
|
ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf,
|
||||||
|
PATH_MAX+3, &pos);
|
||||||
|
if (ptype == ePatternInvalid)
|
||||||
|
goto fail;
|
||||||
|
vec[5] = memberbuf;
|
||||||
|
} else {
|
||||||
|
/* match any char except \000 0 or more times */
|
||||||
|
vec[5] = "[^\\000]*";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->mode & AA_DBUS_BIND) {
|
||||||
|
if (!aare_add_rule_vec(dfarules, entry->deny, entry->mode & AA_DBUS_BIND, entry->audit & AA_DBUS_BIND, 2, vec, dfaflags))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (entry->mode & ~AA_DBUS_BIND) {
|
||||||
|
if (!aare_add_rule_vec(dfarules, entry->deny, entry->mode, entry->audit, 6, vec, dfaflags))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int post_process_mnt_ents(struct codomain *cod)
|
||||||
{
|
{
|
||||||
int ret = TRUE;
|
int ret = TRUE;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -1058,10 +1159,37 @@ int post_process_policydb_ents(struct codomain *cod)
|
|||||||
} else if (cod->mnt_ents && !kernel_supports_mount)
|
} else if (cod->mnt_ents && !kernel_supports_mount)
|
||||||
pwarn("profile %s mount rules not enforced\n", cod->name);
|
pwarn("profile %s mount rules not enforced\n", cod->name);
|
||||||
|
|
||||||
cod->policy_rule_count = count;
|
cod->policy_rule_count += count;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int post_process_dbus_ents(struct codomain *cod)
|
||||||
|
{
|
||||||
|
int ret = TRUE;
|
||||||
|
struct dbus_entry *entry;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
list_for_each(cod->dbus_ents, entry) {
|
||||||
|
if (regex_type == AARE_DFA &&
|
||||||
|
!process_dbus_entry(cod->policy_rules, entry))
|
||||||
|
ret = FALSE;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
cod->policy_rule_count += count;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int post_process_policydb_ents(struct codomain *cod)
|
||||||
|
{
|
||||||
|
if (!post_process_mnt_ents(cod))
|
||||||
|
return FALSE;
|
||||||
|
if (!post_process_dbus_ents(cod))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int process_policydb(struct codomain *cod)
|
int process_policydb(struct codomain *cod)
|
||||||
{
|
{
|
||||||
int error = -1;
|
int error = -1;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
#include "dbus.h"
|
||||||
#include "parser_include.h"
|
#include "parser_include.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -81,6 +82,7 @@ void add_local_entry(struct codomain *cod);
|
|||||||
|
|
||||||
%token TOK_ID
|
%token TOK_ID
|
||||||
%token TOK_CONDID
|
%token TOK_CONDID
|
||||||
|
%token TOK_CONDLISTID
|
||||||
%token TOK_CARET
|
%token TOK_CARET
|
||||||
%token TOK_OPEN
|
%token TOK_OPEN
|
||||||
%token TOK_CLOSE
|
%token TOK_CLOSE
|
||||||
@ -122,6 +124,13 @@ void add_local_entry(struct codomain *cod);
|
|||||||
%token TOK_UMOUNT
|
%token TOK_UMOUNT
|
||||||
%token TOK_PIVOTROOT
|
%token TOK_PIVOTROOT
|
||||||
%token TOK_IN
|
%token TOK_IN
|
||||||
|
%token TOK_DBUS
|
||||||
|
%token TOK_SEND
|
||||||
|
%token TOK_RECEIVE
|
||||||
|
%token TOK_BIND
|
||||||
|
%token TOK_READ
|
||||||
|
%token TOK_WRITE
|
||||||
|
%token TOK_PEER
|
||||||
|
|
||||||
/* rlimits */
|
/* rlimits */
|
||||||
%token TOK_RLIMIT
|
%token TOK_RLIMIT
|
||||||
@ -158,6 +167,7 @@ void add_local_entry(struct codomain *cod);
|
|||||||
struct cod_net_entry *net_entry;
|
struct cod_net_entry *net_entry;
|
||||||
struct cod_entry *user_entry;
|
struct cod_entry *user_entry;
|
||||||
struct mnt_entry *mnt_entry;
|
struct mnt_entry *mnt_entry;
|
||||||
|
struct dbus_entry *dbus_entry;
|
||||||
|
|
||||||
struct flagval flags;
|
struct flagval flags;
|
||||||
int fmode;
|
int fmode;
|
||||||
@ -174,6 +184,7 @@ void add_local_entry(struct codomain *cod);
|
|||||||
|
|
||||||
%type <id> TOK_ID
|
%type <id> TOK_ID
|
||||||
%type <id> TOK_CONDID
|
%type <id> TOK_CONDID
|
||||||
|
%type <id> TOK_CONDLISTID
|
||||||
%type <mode> TOK_MODE
|
%type <mode> TOK_MODE
|
||||||
%type <fmode> file_mode
|
%type <fmode> file_mode
|
||||||
%type <cod> profile_base
|
%type <cod> profile_base
|
||||||
@ -192,6 +203,8 @@ void add_local_entry(struct codomain *cod);
|
|||||||
%type <mnt_entry> mnt_rule
|
%type <mnt_entry> mnt_rule
|
||||||
%type <cond_entry> opt_conds
|
%type <cond_entry> opt_conds
|
||||||
%type <cond_entry> cond
|
%type <cond_entry> cond
|
||||||
|
%type <cond_entry> cond_list
|
||||||
|
%type <cond_entry> opt_cond_list
|
||||||
%type <flags> flags
|
%type <flags> flags
|
||||||
%type <flags> flagvals
|
%type <flags> flagvals
|
||||||
%type <flags> flagval
|
%type <flags> flagval
|
||||||
@ -211,6 +224,10 @@ void add_local_entry(struct codomain *cod);
|
|||||||
%type <boolean> opt_flags
|
%type <boolean> opt_flags
|
||||||
%type <id> opt_namespace
|
%type <id> opt_namespace
|
||||||
%type <id> opt_id
|
%type <id> opt_id
|
||||||
|
%type <fmode> dbus_perm
|
||||||
|
%type <fmode> dbus_perms
|
||||||
|
%type <fmode> opt_dbus_perm
|
||||||
|
%type <dbus_entry> dbus_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
|
||||||
@ -680,6 +697,25 @@ rules: rules opt_audit_flag mnt_rule
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rules: rules opt_audit_flag TOK_DENY dbus_rule
|
||||||
|
{
|
||||||
|
$4->deny = $4->mode;
|
||||||
|
if ($2)
|
||||||
|
$4->audit = $4->mode;
|
||||||
|
$4->next = $1->dbus_ents;
|
||||||
|
$1->dbus_ents = $4;
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rules: rules opt_audit_flag dbus_rule
|
||||||
|
{
|
||||||
|
if ($2)
|
||||||
|
$3->audit = $3->mode;
|
||||||
|
$3->next = $1->dbus_ents;
|
||||||
|
$1->dbus_ents = $3;
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
|
||||||
rules: rules change_profile
|
rules: rules change_profile
|
||||||
{
|
{
|
||||||
PDEBUG("matched: rules change_profile\n");
|
PDEBUG("matched: rules change_profile\n");
|
||||||
@ -1103,6 +1139,14 @@ opt_conds: { /* nothing */ $$ = NULL; }
|
|||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN
|
||||||
|
{
|
||||||
|
$$ = $4;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_cond_list: { /* nothing */ $$ = NULL; }
|
||||||
|
| cond_list { $$ = $1; }
|
||||||
|
|
||||||
mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
|
mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
|
||||||
{
|
{
|
||||||
$$ = do_mnt_rule($2, $3, NULL, NULL, AA_MAY_MOUNT);
|
$$ = do_mnt_rule($2, $3, NULL, NULL, AA_MAY_MOUNT);
|
||||||
@ -1142,6 +1186,51 @@ mnt_rule: TOK_PIVOTROOT opt_conds opt_id opt_named_transition TOK_END_OF_RULE
|
|||||||
$$ = do_pivot_rule($2, $3, name);
|
$$ = do_pivot_rule($2, $3, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbus_perm: TOK_VALUE
|
||||||
|
{
|
||||||
|
if (strcmp($1, "bind") == 0)
|
||||||
|
$$ = AA_DBUS_BIND;
|
||||||
|
else if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0)
|
||||||
|
$$ = AA_DBUS_SEND;
|
||||||
|
else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
|
||||||
|
$$ = AA_DBUS_RECEIVE;
|
||||||
|
else if ($1) {
|
||||||
|
parse_dbus_mode($1, &$$, 1);
|
||||||
|
} else
|
||||||
|
$$ = 0;
|
||||||
|
|
||||||
|
if ($1)
|
||||||
|
free($1);
|
||||||
|
}
|
||||||
|
| TOK_BIND { $$ = AA_DBUS_BIND; }
|
||||||
|
| TOK_SEND { $$ = AA_DBUS_SEND; }
|
||||||
|
| TOK_RECEIVE { $$ = AA_DBUS_RECEIVE; }
|
||||||
|
| TOK_READ { $$ = AA_DBUS_RECEIVE; }
|
||||||
|
| TOK_WRITE { $$ = AA_DBUS_SEND; }
|
||||||
|
| TOK_MODE
|
||||||
|
{
|
||||||
|
parse_dbus_mode($1, &$$, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_perms: { /* nothing */ $$ = 0; }
|
||||||
|
| dbus_perms dbus_perm { $$ = $1 | $2; }
|
||||||
|
| dbus_perms TOK_COMMA dbus_perm { $$ = $1 | $3; }
|
||||||
|
|
||||||
|
opt_dbus_perm: { /* nothing */ $$ = 0; }
|
||||||
|
| dbus_perm { $$ = $1; }
|
||||||
|
| TOK_OPENPAREN dbus_perms TOK_CLOSEPAREN { $$ = $2; }
|
||||||
|
|
||||||
|
dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE
|
||||||
|
{
|
||||||
|
struct dbus_entry *ent;
|
||||||
|
|
||||||
|
ent = new_dbus_entry($2, $3, $4);
|
||||||
|
if (!ent) {
|
||||||
|
yyerror(_("Memory allocation error."));
|
||||||
|
}
|
||||||
|
$$ = ent;
|
||||||
|
}
|
||||||
|
|
||||||
hat_start: TOK_CARET {}
|
hat_start: TOK_CARET {}
|
||||||
| TOK_HAT {}
|
| TOK_HAT {}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user