1
Description: parser: Add support for DBus rules
3
This patch implements the parsing of DBus rules.
5
It attempts to catch all corner cases, such as specifying a bind
6
permission with an interface conditional or specifying a subject name
7
conditional and a peer name conditional in the same rule.
9
It introduces the concept of conditional lists to the lexer and parser
10
in order to handle 'peer=(label=/usr/bin/foo name=com.foo.bar)', since
11
the existing list support in the lexer only supports a list of values.
13
The DBus rules are encoded as follows:
15
bus,name<bind_perm>,peer_label,path,interface,member<rw_perms>
17
Bind rules stop matching at name<bind_perm>. Note that name is used for
18
the subject name in bind rules and the peer name in rw rules. The
19
function new_dbus_entry() is what does the proper sanitization to make
20
sure that if a name conditional is specified, that it is the subject
21
name in the case of a bind rule or that it is the peer name in the case
24
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
25
Acked-by: Seth Arnold <seth.arnold@canonical.com>
26
Origin: backport, revision id: tyhicks@canonical.com-20130731160551-hbro3c6848v64z6g
27
Author: Tyler Hicks <tyhicks@canonical.com>
28
Last-Update: 2013-07-31
29
X-Bzr-Revision-Id: tyhicks@canonical.com-20130731160551-hbro3c6848v64z6g
31
Index: apparmor-2.8.0/parser/Makefile
32
===================================================================
33
--- apparmor-2.8.0.orig/parser/Makefile 2013-07-30 12:28:41.166534988 -0700
34
+++ apparmor-2.8.0/parser/Makefile 2013-07-30 12:28:41.146534989 -0700
35
@@ -76,8 +76,8 @@ EXTRA_CFLAGS+=-DSUBDOMAIN_CONFDIR=\"${CO
36
SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \
37
parser_main.c parser_misc.c parser_merge.c parser_symtab.c \
38
parser_yacc.c parser_regex.c parser_variable.c parser_policy.c \
39
- parser_alias.c mount.c
40
-HDRS = parser.h parser_include.h immunix.h mount.h
41
+ parser_alias.c mount.c dbus.c
42
+HDRS = parser.h parser_include.h immunix.h mount.h dbus.h
43
TOOLS = apparmor_parser
45
OBJECTS = $(SRCS:.c=.o)
46
@@ -204,6 +204,9 @@ parser_common.o: parser_common.c parser.
47
mount.o: mount.c mount.h parser.h immunix.h
48
$(CC) $(EXTRA_CFLAGS) -c -o $@ $<
50
+dbus.o: dbus.c dbus.h parser.h immunix.h
51
+ $(CC) $(EXTRA_CFLAGS) -c -o $@ $<
53
parser_version.h: Makefile
54
@echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
56
Index: apparmor-2.8.0/parser/dbus.c
57
===================================================================
58
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
59
+++ apparmor-2.8.0/parser/dbus.c 2013-07-30 12:28:41.146534989 -0700
62
+ * Copyright (c) 2013
63
+ * Canonical, Ltd. (All rights reserved)
65
+ * This program is free software; you can redistribute it and/or
66
+ * modify it under the terms of version 2 of the GNU General Public
67
+ * License published by the Free Software Foundation.
69
+ * This program is distributed in the hope that it will be useful,
70
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72
+ * GNU General Public License for more details.
74
+ * You should have received a copy of the GNU General Public License
75
+ * along with this program; if not, contact Novell, Inc. or Canonical
83
+#include "parser_yacc.h"
86
+void free_dbus_entry(struct dbus_entry *ent)
92
+ free(ent->peer_label);
94
+ free(ent->interface);
100
+static int list_len(struct value_list *v)
103
+ struct value_list *tmp;
105
+ list_for_each(v, tmp)
111
+static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent)
114
+ yyerror("dbus conditional \"%s\" can only be specified once\n",
117
+ *dst_ptr = cond_ent->vals->value;
118
+ cond_ent->vals->value = NULL;
121
+static void move_conditionals(struct dbus_entry *ent, struct cond_entry *conds)
123
+ struct cond_entry *cond_ent;
125
+ list_for_each(conds, cond_ent) {
126
+ /* for now disallow keyword 'in' (list) */
128
+ yyerror("keyword \"in\" is not allowed in dbus rules\n");
129
+ if (list_len(cond_ent->vals) > 1)
130
+ yyerror("dbus conditional \"%s\" only supports a single value\n",
133
+ if (strcmp(cond_ent->name, "bus") == 0) {
134
+ move_conditional_value(&ent->bus, cond_ent);
135
+ } else if (strcmp(cond_ent->name, "name") == 0) {
136
+ move_conditional_value(&ent->name, cond_ent);
137
+ } else if (strcmp(cond_ent->name, "label") == 0) {
138
+ move_conditional_value(&ent->peer_label, cond_ent);
139
+ } else if (strcmp(cond_ent->name, "path") == 0) {
140
+ move_conditional_value(&ent->path, cond_ent);
141
+ } else if (strcmp(cond_ent->name, "interface") == 0) {
142
+ move_conditional_value(&ent->interface, cond_ent);
143
+ } else if (strcmp(cond_ent->name, "member") == 0) {
144
+ move_conditional_value(&ent->member, cond_ent);
146
+ yyerror("invalid dbus conditional \"%s\"\n",
152
+struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds,
153
+ struct cond_entry *peer_conds)
155
+ struct dbus_entry *ent;
156
+ int name_is_subject_cond = 0, message_rule = 0, service_rule = 0;
158
+ ent = (struct dbus_entry*) calloc(1, sizeof(struct dbus_entry));
162
+ /* Move the global/subject conditionals over & check the results */
163
+ move_conditionals(ent, conds);
165
+ name_is_subject_cond = 1;
166
+ if (ent->peer_label)
167
+ yyerror("dbus \"label\" conditional can only be used inside of the \"peer=()\" grouping\n");
169
+ /* Move the peer conditionals */
170
+ move_conditionals(ent, peer_conds);
172
+ if (ent->path || ent->interface || ent->member || ent->peer_label ||
173
+ (ent->name && !name_is_subject_cond))
176
+ if (ent->name && name_is_subject_cond)
179
+ if (message_rule && service_rule)
180
+ yyerror("dbus rule contains message conditionals and service conditionals\n");
182
+ /* Copy mode. If no mode was specified, assign an implied mode. */
185
+ if (ent->mode & ~AA_VALID_DBUS_PERMS)
186
+ yyerror("mode contains unknown dbus accesss\n");
187
+ else if (message_rule && (ent->mode & AA_DBUS_BIND))
188
+ yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n");
189
+ else if (service_rule && (ent->mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)))
190
+ yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n");
192
+ ent->mode = AA_VALID_DBUS_PERMS;
194
+ ent->mode &= ~AA_DBUS_BIND;
195
+ else if (service_rule)
196
+ ent->mode &= ~(AA_DBUS_SEND | AA_DBUS_RECEIVE);
200
+ free_cond_list(conds);
205
+void print_dbus_entry(struct dbus_entry *ent)
208
+ fprintf(stderr, "audit ");
210
+ fprintf(stderr, "deny ");
212
+ fprintf(stderr, "dbus ( ");
214
+ if (ent->mode & AA_DBUS_SEND)
215
+ fprintf(stderr, "send ");
216
+ if (ent->mode & AA_DBUS_RECEIVE)
217
+ fprintf(stderr, "receive ");
218
+ if (ent->mode & AA_DBUS_BIND)
219
+ fprintf(stderr, "bind ");
220
+ fprintf(stderr, ")");
223
+ fprintf(stderr, " bus=\"%s\"", ent->bus);
224
+ if ((ent->mode & AA_DBUS_BIND) && ent->name)
225
+ fprintf(stderr, " name=\"%s\"", ent->name);
227
+ fprintf(stderr, " path=\"%s\"", ent->path);
228
+ if (ent->interface)
229
+ fprintf(stderr, " interface=\"%s\"", ent->interface);
231
+ fprintf(stderr, " member=\"%s\"", ent->member);
233
+ if (!(ent->mode & AA_DBUS_BIND) && (ent->peer_label || ent->name)) {
234
+ fprintf(stderr, " peer=( ");
235
+ if (ent->peer_label)
236
+ fprintf(stderr, "label=\"%s\" ", ent->peer_label);
238
+ fprintf(stderr, "name=\"%s\" ", ent->name);
239
+ fprintf(stderr, ")");
242
+ fprintf(stderr, ",\n");
244
Index: apparmor-2.8.0/parser/dbus.h
245
===================================================================
246
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
247
+++ apparmor-2.8.0/parser/dbus.h 2013-07-30 12:28:41.146534989 -0700
250
+ * Copyright (c) 2013
251
+ * Canonical, Ltd. (All rights reserved)
253
+ * This program is free software; you can redistribute it and/or
254
+ * modify it under the terms of version 2 of the GNU General Public
255
+ * License published by the Free Software Foundation.
257
+ * This program is distributed in the hope that it will be useful,
258
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
259
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
260
+ * GNU General Public License for more details.
262
+ * You should have received a copy of the GNU General Public License
263
+ * along with this program; if not, contact Novell, Inc. or Canonical
275
+ * Be careful! ->name can be the subject or the peer name, depending on
276
+ * whether the rule is a bind rule or a send/receive rule. See the
277
+ * comments in new_dbus_entry() for details.
288
+ struct dbus_entry *next;
291
+void free_dbus_entry(struct dbus_entry *ent);
292
+struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds,
293
+ struct cond_entry *peer_conds);
294
+void print_dbus_entry(struct dbus_entry *ent);
296
+#endif /* __AA_DBUS_H */
297
Index: apparmor-2.8.0/parser/immunix.h
298
===================================================================
299
--- apparmor-2.8.0.orig/parser/immunix.h 2013-07-30 12:28:41.166534988 -0700
300
+++ apparmor-2.8.0/parser/immunix.h 2013-07-30 12:28:41.150534989 -0700
302
#define AA_EXEC_MOD_2 (1 << 12)
303
#define AA_EXEC_MOD_3 (1 << 13)
305
+#define AA_DBUS_SEND AA_MAY_WRITE
306
+#define AA_DBUS_RECEIVE AA_MAY_READ
307
+#define AA_DBUS_BIND (1 << 6)
309
+#define AA_VALID_DBUS_PERMS (AA_DBUS_SEND | AA_DBUS_RECEIVE | \
312
#define AA_BASE_PERMS (AA_MAY_EXEC | AA_MAY_WRITE | \
313
AA_MAY_READ | AA_MAY_APPEND | \
314
AA_MAY_LINK | AA_MAY_LOCK | \
315
Index: apparmor-2.8.0/parser/parser.h
316
===================================================================
317
--- apparmor-2.8.0.orig/parser/parser.h 2013-07-30 12:28:41.166534988 -0700
318
+++ apparmor-2.8.0/parser/parser.h 2013-07-30 12:28:41.150534989 -0700
319
@@ -142,6 +142,7 @@ struct codomain {
321
char *exec_table[AA_EXEC_COUNT];
322
struct cod_entry *entries;
323
+ struct dbus_entry *dbus_ents;
324
struct mnt_entry *mnt_ents;
327
@@ -301,6 +302,8 @@ extern char *basedir;
329
extern int process_regex(struct codomain *cod);
330
extern int post_process_entry(struct cod_entry *entry);
331
+extern int process_dbus(struct codomain *cod);
333
extern void reset_regex(void);
335
extern int process_policydb(struct codomain *cod);
336
@@ -319,6 +322,7 @@ extern void free_value_list(struct value
337
extern void print_value_list(struct value_list *list);
338
extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list);
339
extern void free_cond_entry(struct cond_entry *ent);
340
+extern void free_cond_list(struct cond_entry *ents);
341
extern void print_cond_entry(struct cond_entry *ent);
342
extern char *processid(char *string, int len);
343
extern char *processquoted(char *string, int len);
344
@@ -328,6 +332,7 @@ extern int name_to_capability(const char
345
extern int get_rlimit(const char *name);
346
extern char *process_var(const char *var);
347
extern int parse_mode(const char *mode);
348
+extern int parse_dbus_mode(const char *str_mode, int *mode, int fail);
349
extern struct cod_entry *new_entry(char *namespace, char *id, int mode,
351
extern struct aa_network_entry *new_network_ent(unsigned int family,
352
@@ -344,6 +349,7 @@ extern int str_to_boolean(const char* st
353
extern struct cod_entry *copy_cod_entry(struct cod_entry *cod);
354
extern void free_cod_entries(struct cod_entry *list);
355
extern void free_mnt_entries(struct mnt_entry *list);
356
+extern void free_dbus_entries(struct dbus_entry *list);
358
/* parser_symtab.c */
360
@@ -385,6 +391,7 @@ extern void post_process_file_entries(st
361
extern void post_process_mnt_entries(struct codomain *cod);
362
extern int post_process_policy(int debug_only);
363
extern int process_hat_regex(struct codomain *cod);
364
+extern int process_hat_dbus(struct codomain *cod);
365
extern int process_hat_variables(struct codomain *cod);
366
extern int process_hat_policydb(struct codomain *cod);
367
extern int post_merge_rules(void);
368
Index: apparmor-2.8.0/parser/parser_lex.l
369
===================================================================
370
--- apparmor-2.8.0.orig/parser/parser_lex.l 2013-07-30 12:28:41.166534988 -0700
371
+++ apparmor-2.8.0/parser/parser_lex.l 2013-07-30 12:28:41.150534989 -0700
373
#define NPDEBUG(fmt, args...) /* Do nothing */
375
#define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
376
+#define RETURN_TOKEN(X) \
379
+ PDEBUG("Matched: %s\n", yytext); \
385
@@ -187,9 +193,11 @@ POST_VAR_ID_CHARS [^ \t\n"!,]{-}[=\+]
386
POST_VAR_ID {POST_VAR_ID_CHARS}|(,{POST_VAR_ID_CHARS})
387
LIST_VALUE_ID_CHARS [^ \t\n"!,]{-}[()]
388
LIST_VALUE_ID {LIST_VALUE_ID_CHARS}+
389
+QUOTED_LIST_VALUE_ID {LIST_VALUE_ID}|\"{LIST_VALUE_ID}\"
390
ID_CHARS_NOEQ [^ \t\n"!,]{-}[=]
391
+LEADING_ID_CHARS_NOEQ [^ \t\n"!,]{-}[=()]
392
ID_NOEQ {ID_CHARS_NOEQ}|(,{ID_CHARS_NOEQ})
394
+IDS_NOEQ {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}*
395
ALLOWED_QUOTED_ID [^\0"]|\\\"
396
QUOTED_ID \"{ALLOWED_QUOTED_ID}*\"
398
@@ -217,11 +225,16 @@ LT_EQUAL <=
407
+%x LIST_COND_PAREN_VAL
412
%x CHANGE_PROFILE_MODE
415
@@ -267,7 +280,7 @@ LT_EQUAL <=
416
if ( !YY_CURRENT_BUFFER ) yyterminate();
419
-<INITIAL,MOUNT_MODE>{
420
+<INITIAL,MOUNT_MODE,DBUS_MODE>{
421
{VARIABLE_NAME}/{WS}*= {
422
/* we match to the = in the lexer so that
423
* can switch scanner state. By the time
424
@@ -275,11 +288,19 @@ LT_EQUAL <=
425
* as bison may have requested the next
426
* token from the scanner
428
+ int token = get_keyword_token(yytext);
431
- PDEBUG("conditional %s=\n", yytext);
432
- yylval.id = processid(yytext, yyleng);
433
- yy_push_state(EXTCOND_MODE);
435
+ if (token == TOK_PEER) {
436
+ PDEBUG("conditional list %s=\n", yytext);
437
+ yy_push_state(EXTCONDLIST_MODE);
438
+ return TOK_CONDLISTID;
440
+ PDEBUG("conditional %s=\n", yytext);
441
+ yylval.id = processid(yytext, yyleng);
442
+ yy_push_state(EXTCOND_MODE);
446
{VARIABLE_NAME}/{WS}+in{WS}*\( {
447
/* we match to 'in' in the lexer so that
448
@@ -411,6 +432,116 @@ LT_EQUAL <=
453
+ {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
455
+ ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
457
+ yylval.id = processid(yytext, yyleng);
458
+ PDEBUG("listcond value: \"%s\"\n", yylval.id);
465
+ /* Something we didn't expect */
466
+ yyerror(_("Found unexpected character: '%s'"), yytext);
470
+<LIST_COND_PAREN_VAL>{
476
+ {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
478
+ ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
480
+ yylval.id = processid(yytext, yyleng);
481
+ PDEBUG("listcond paren value: \"%s\"\n", yylval.id);
487
+ /* Something we didn't expect */
488
+ yyerror(_("Found unexpected character: '%s'"), yytext);
495
+ PDEBUG("listcond: )\n");
497
+ return TOK_CLOSEPAREN;
500
+ {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
504
+ PDEBUG("listcond: , \n");
505
+ /* Eat comma, its an optional separator */
510
+ PDEBUG("listcond conditional %s=\n", yytext);
511
+ yylval.id = processid(yytext, yyleng);
515
+ {EQUALS}{WS}*{OPEN_PAREN} {
517
+ yy_push_state(LIST_COND_PAREN_VAL);
523
+ yy_push_state(LIST_COND_VAL);
529
+ /* Something we didn't expect */
530
+ yyerror(_("Found unexpected character: '%s'"), yytext);
535
+ {WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
544
+ PDEBUG("extcondlist (\n");
545
+ /* Don't push state here as this is a transition
546
+ * start condition and we want to return to the start
547
+ * condition that invoked <EXTCONDLIST_MODE> when
548
+ * LIST_VAL_ID is done
550
+ BEGIN(LIST_COND_MODE);
551
+ return TOK_OPENPAREN;
556
+ /* Something we didn't expect */
557
+ yyerror(_("Found unexpected character: '%s' %d"), yytext, *yytext);
563
{WS}+ { DUMP_PREPROCESS; /* Eat whitespace */ }
565
@@ -536,7 +667,23 @@ LT_EQUAL <=
571
+ send { RETURN_TOKEN(TOK_SEND); }
572
+ receive { RETURN_TOKEN(TOK_RECEIVE); }
573
+ bind { RETURN_TOKEN(TOK_BIND); }
574
+ read { RETURN_TOKEN(TOK_READ); }
575
+ write { RETURN_TOKEN(TOK_WRITE); }
577
+ yy_push_state(LIST_VAL_MODE);
578
+ RETURN_TOKEN(TOK_OPENPAREN);
580
+ (r|w|rw|wr)/([[:space:],]) {
581
+ yylval.mode = strdup(yytext);
582
+ RETURN_TOKEN(TOK_MODE);
586
+<MOUNT_MODE,DBUS_MODE>{
587
{WS}+ { DUMP_PREPROCESS; /* Ignoring whitespace */ }
590
@@ -698,6 +845,10 @@ LT_EQUAL <=
591
PDEBUG("Entering mount\n");
592
yy_push_state(MOUNT_MODE);
595
+ PDEBUG("Entering dbus\n");
596
+ yy_push_state(DBUS_MODE);
598
default: /* nothing */
601
Index: apparmor-2.8.0/parser/parser_misc.c
602
===================================================================
603
--- apparmor-2.8.0.orig/parser/parser_misc.c 2013-07-30 12:28:41.166534988 -0700
604
+++ apparmor-2.8.0/parser/parser_misc.c 2013-07-30 12:28:41.154534988 -0700
607
#include "parser_yacc.h"
613
@@ -85,6 +86,14 @@ static struct keyword_table keyword_tabl
614
{"unmount", TOK_UMOUNT},
615
{"pivot_root", TOK_PIVOTROOT},
617
+ {"dbus", TOK_DBUS},
618
+ {"send", TOK_SEND},
619
+ {"receive", TOK_RECEIVE},
620
+ {"bind", TOK_BIND},
621
+ {"read", TOK_READ},
622
+ {"write", TOK_WRITE},
623
+ {"peer", TOK_PEER},
628
@@ -718,6 +727,81 @@ int parse_mode(const char *str_mode)
632
+static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused)
637
+ PDEBUG("Parsing DBus mode: %s\n", str_mode);
649
+ case COD_READ_CHAR:
650
+ PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc);
651
+ mode |= AA_DBUS_RECEIVE;
654
+ case COD_WRITE_CHAR:
655
+ PDEBUG("Parsing DBus mode: found %s WRITE\n",
657
+ mode |= AA_DBUS_SEND;
663
+ lower = tolower(this);
665
+ case COD_READ_CHAR:
666
+ case COD_WRITE_CHAR:
667
+ PDEBUG("Parsing DBus mode: found invalid upper case char %c\n",
675
+ yyerror(_("Internal: unexpected DBus mode character '%c' in input"),
686
+ PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode);
692
+int parse_dbus_mode(const char *str_mode, int *mode, int fail)
695
+ if (!parse_dbus_sub_mode(str_mode, mode, fail, ""))
697
+ if (*mode & ~AA_VALID_DBUS_PERMS) {
699
+ yyerror(_("Internal error generated invalid DBus perm 0x%x\n"),
707
struct cod_entry *new_entry(char *namespace, char *id, int mode, char *link_id)
709
struct cod_entry *entry = NULL;
710
@@ -797,6 +881,16 @@ void free_mnt_entries(struct mnt_entry *
714
+void free_dbus_entries(struct dbus_entry *list)
719
+ free_dbus_entries(list->next);
721
+ free_dbus_entry(list);
724
static void debug_base_perm_mask(int mask)
726
if (HAS_MAY_READ(mask))
727
@@ -1047,6 +1141,15 @@ void free_cond_entry(struct cond_entry *
731
+void free_cond_list(struct cond_entry *ents)
733
+ struct cond_entry *entry, *tmp;
735
+ list_for_each_safe(ents, entry, tmp) {
736
+ free_cond_entry(entry);
740
void print_cond_entry(struct cond_entry *ent)
743
Index: apparmor-2.8.0/parser/parser_policy.c
744
===================================================================
745
--- apparmor-2.8.0.orig/parser/parser_policy.c 2013-07-30 12:28:41.166534988 -0700
746
+++ apparmor-2.8.0/parser/parser_policy.c 2013-07-30 12:28:41.154534988 -0700
752
#include "parser_yacc.h"
755
@@ -818,6 +819,7 @@ void free_policy(struct codomain *cod)
756
free_hat_table(cod->hat_table);
757
free_cod_entries(cod->entries);
758
free_mnt_entries(cod->mnt_ents);
759
+ free_dbus_entries(cod->dbus_ents);
761
aare_delete_ruleset(cod->dfarules);
763
Index: apparmor-2.8.0/parser/parser_regex.c
764
===================================================================
765
--- apparmor-2.8.0.orig/parser/parser_regex.c 2013-07-30 12:28:41.166534988 -0700
766
+++ apparmor-2.8.0/parser/parser_regex.c 2013-07-30 12:28:41.154534988 -0700
768
#include "libapparmor_re/apparmor_re.h"
769
#include "libapparmor_re/aare_rules.h"
772
#include "policydb.h"
775
@@ -1041,7 +1042,107 @@ fail:
779
-int post_process_policydb_ents(struct codomain *cod)
780
+static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry)
782
+ char busbuf[PATH_MAX + 3];
783
+ char namebuf[PATH_MAX + 3];
784
+ char peer_labelbuf[PATH_MAX + 3];
785
+ char pathbuf[PATH_MAX + 3];
786
+ char ifacebuf[PATH_MAX + 3];
787
+ char memberbuf[PATH_MAX + 3];
793
+ if (!entry) /* shouldn't happen */
797
+ p += sprintf(p, "\\x%02x", AA_CLASS_DBUS);
800
+ ptype = convert_aaregex_to_pcre(entry->bus, 0, p,
801
+ PATH_MAX+3 - (p - busbuf), &pos);
802
+ if (ptype == ePatternInvalid)
805
+ /* match any char except \000 0 or more times */
806
+ strcpy(p, "[^\\000]*");
811
+ ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf,
813
+ if (ptype == ePatternInvalid)
817
+ /* match any char except \000 0 or more times */
818
+ vec[1] = "[^\\000]*";
821
+ if (entry->peer_label) {
822
+ ptype = convert_aaregex_to_pcre(entry->peer_label, 0,
823
+ peer_labelbuf, PATH_MAX+3,
825
+ if (ptype == ePatternInvalid)
827
+ vec[2] = peer_labelbuf;
829
+ /* match any char except \000 0 or more times */
830
+ vec[2] = "[^\\000]*";
834
+ ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf,
836
+ if (ptype == ePatternInvalid)
840
+ /* match any char except \000 0 or more times */
841
+ vec[3] = "[^\\000]*";
844
+ if (entry->interface) {
845
+ ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf,
847
+ if (ptype == ePatternInvalid)
851
+ /* match any char except \000 0 or more times */
852
+ vec[4] = "[^\\000]*";
855
+ if (entry->member) {
856
+ ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf,
858
+ if (ptype == ePatternInvalid)
860
+ vec[5] = memberbuf;
862
+ /* match any char except \000 0 or more times */
863
+ vec[5] = "[^\\000]*";
866
+ if (entry->mode & AA_DBUS_BIND) {
867
+ if (!aare_add_rule_vec(dfarules, entry->deny, entry->mode & AA_DBUS_BIND, entry->audit & AA_DBUS_BIND, 2, vec, dfaflags))
870
+ if (entry->mode & ~AA_DBUS_BIND) {
871
+ if (!aare_add_rule_vec(dfarules, entry->deny, entry->mode, entry->audit, 6, vec, dfaflags))
880
+static int post_process_mnt_ents(struct codomain *cod)
884
@@ -1058,10 +1159,37 @@ int post_process_policydb_ents(struct co
885
} else if (cod->mnt_ents && !kernel_supports_mount)
886
pwarn("profile %s mount rules not enforced\n", cod->name);
888
- cod->policy_rule_count = count;
889
+ cod->policy_rule_count += count;
893
+static int post_process_dbus_ents(struct codomain *cod)
896
+ struct dbus_entry *entry;
899
+ list_for_each(cod->dbus_ents, entry) {
900
+ if (regex_type == AARE_DFA &&
901
+ !process_dbus_entry(cod->policy_rules, entry))
906
+ cod->policy_rule_count += count;
910
+int post_process_policydb_ents(struct codomain *cod)
912
+ if (!post_process_mnt_ents(cod))
914
+ if (!post_process_dbus_ents(cod))
920
int process_policydb(struct codomain *cod)
923
Index: apparmor-2.8.0/parser/parser_yacc.y
924
===================================================================
925
--- apparmor-2.8.0.orig/parser/parser_yacc.y 2013-07-30 12:28:41.166534988 -0700
926
+++ apparmor-2.8.0/parser/parser_yacc.y 2013-07-30 12:28:41.158534988 -0700
932
#include "parser_include.h"
934
#include <netinet/in.h>
935
@@ -81,6 +82,7 @@ void add_local_entry(struct codomain *co
939
+%token TOK_CONDLISTID
943
@@ -122,6 +124,13 @@ void add_local_entry(struct codomain *co
957
@@ -158,6 +167,7 @@ void add_local_entry(struct codomain *co
958
struct cod_net_entry *net_entry;
959
struct cod_entry *user_entry;
960
struct mnt_entry *mnt_entry;
961
+ struct dbus_entry *dbus_entry;
963
struct flagval flags;
965
@@ -174,6 +184,7 @@ void add_local_entry(struct codomain *co
968
%type <id> TOK_CONDID
969
+%type <id> TOK_CONDLISTID
970
%type <mode> TOK_MODE
971
%type <fmode> file_mode
972
%type <cod> profile_base
973
@@ -192,6 +203,8 @@ void add_local_entry(struct codomain *co
974
%type <mnt_entry> mnt_rule
975
%type <cond_entry> opt_conds
976
%type <cond_entry> cond
977
+%type <cond_entry> cond_list
978
+%type <cond_entry> opt_cond_list
980
%type <flags> flagvals
981
%type <flags> flagval
982
@@ -211,6 +224,10 @@ void add_local_entry(struct codomain *co
983
%type <boolean> opt_flags
984
%type <id> opt_namespace
986
+%type <fmode> dbus_perm
987
+%type <fmode> dbus_perms
988
+%type <fmode> opt_dbus_perm
989
+%type <dbus_entry> dbus_rule
990
%type <transition> opt_named_transition
991
%type <boolean> opt_unsafe
992
%type <boolean> opt_file
993
@@ -680,6 +697,25 @@ rules: rules opt_audit_flag mnt_rule
997
+rules: rules opt_audit_flag TOK_DENY dbus_rule
999
+ $4->deny = $4->mode;
1001
+ $4->audit = $4->mode;
1002
+ $4->next = $1->dbus_ents;
1003
+ $1->dbus_ents = $4;
1007
+rules: rules opt_audit_flag dbus_rule
1010
+ $3->audit = $3->mode;
1011
+ $3->next = $1->dbus_ents;
1012
+ $1->dbus_ents = $3;
1016
rules: rules change_profile
1018
PDEBUG("matched: rules change_profile\n");
1019
@@ -1103,6 +1139,14 @@ opt_conds: { /* nothing */ $$ = NULL; }
1023
+cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN
1028
+opt_cond_list: { /* nothing */ $$ = NULL; }
1029
+ | cond_list { $$ = $1; }
1031
mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
1033
$$ = do_mnt_rule($2, $3, NULL, NULL, AA_MAY_MOUNT);
1034
@@ -1142,6 +1186,51 @@ mnt_rule: TOK_PIVOTROOT opt_conds opt_id
1035
$$ = do_pivot_rule($2, $3, name);
1038
+dbus_perm: TOK_VALUE
1040
+ if (strcmp($1, "bind") == 0)
1041
+ $$ = AA_DBUS_BIND;
1042
+ else if (strcmp($1, "send") == 0 || strcmp($1, "write") == 0)
1043
+ $$ = AA_DBUS_SEND;
1044
+ else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0)
1045
+ $$ = AA_DBUS_RECEIVE;
1047
+ parse_dbus_mode($1, &$$, 1);
1054
+ | TOK_BIND { $$ = AA_DBUS_BIND; }
1055
+ | TOK_SEND { $$ = AA_DBUS_SEND; }
1056
+ | TOK_RECEIVE { $$ = AA_DBUS_RECEIVE; }
1057
+ | TOK_READ { $$ = AA_DBUS_RECEIVE; }
1058
+ | TOK_WRITE { $$ = AA_DBUS_SEND; }
1061
+ parse_dbus_mode($1, &$$, 1);
1064
+dbus_perms: { /* nothing */ $$ = 0; }
1065
+ | dbus_perms dbus_perm { $$ = $1 | $2; }
1066
+ | dbus_perms TOK_COMMA dbus_perm { $$ = $1 | $3; }
1068
+opt_dbus_perm: { /* nothing */ $$ = 0; }
1069
+ | dbus_perm { $$ = $1; }
1070
+ | TOK_OPENPAREN dbus_perms TOK_CLOSEPAREN { $$ = $2; }
1072
+dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE
1074
+ struct dbus_entry *ent;
1076
+ ent = new_dbus_entry($2, $3, $4);
1078
+ yyerror(_("Memory allocation error."));
1083
hat_start: TOK_CARET {}