~apparmor-dev/apparmor/apparmor-ubuntu-citrain-trusty

« back to all changes in this revision

Viewing changes to debian/patches/0050-parser-Add-support-for-DBus-rules.patch

  • Committer: Seth Arnold
  • Date: 2014-03-12 02:05:16 UTC
  • mto: This revision was merged to the branch mainline in revision 1496.
  • Revision ID: seth.arnold@canonical.com-20140312020516-zjike3pmw6hi861h
[ Jamie Strandboge ]
 * debian/debhelper/dh_apparmor: exit with error if aa-easyprof does not
   exist
 * debian/control: drop Depends on apparmor-easyprof to Suggests for
   dh-apparmor
[ Seth Arnold, Jamie Strandboge, Steve Beattie, John Johansen, Tyler Hicks ]
* New upstream snapshot (LP: #1278702, #1061693, #1285653) dropping very
  large Ubuntu delta and fixing the following bugs:
  - Adjust fonts abstraction for libthai (LP: #1278702)
  - Support translated XDG user directories (LP: #1061693)
  - Adjust abstractions/web-data to include /var/www/html (LP: #1285653)
    Refresh 0002-add-debian-integration-to-lighttpd.patch to include
    /etc/lighttpd/conf-available/*.conf
  - Adjust debian/libapparmor1.symbols to reflect new upstream versioning
    for the aa_query_label() function
  - Raise exceptions in Python bindings when something fails
* ship new Python replacements for previous Perl-based tools
  - debian/apparmor-utils.install: remove usr/share/perl5/Immunix/*.pm and add
    usr/sbin/aa-autodep, usr/sbin/aa-cleanprof and usr/sbin/aa-mergeprof
  - debian/control:
    + remove various Perl dependencies
    + add python-apparmor and python3-apparmor
    + python3-apparmor Breaks: apparmor-easyprof to move the file since it
      ships dist-packages/apparmor/__init__.py now
  - debian/apparmor-utils.manpages: ship new manpages for aa-cleanprof and
    aa-mergeprof
  - debian/rules: build and install Python tools
* debian/apparmor.install:
  - install apparmorfs, dovecot, kernelvars, securityfs, sys,
    and xdg-user-dirs tunables and xdg-user-dirs.d directory
* debian/apparmor.dirs:
  - install /etc/apparmor.d/tunables/xdg-user-dirs.d
* debian/apparmor.postinst: create xdg-user-dirs.d
* debian/apparmor.postrm: remove xdg-user-dirs.d
* Remaining patches:
  - 0001-add-chromium-browser.patch
  - 0002-add-debian-integration-to-lighttpd.patch
  - 0003-ubuntu-manpage-updates.patch
  - 0004-libapparmor-layout-deb.patch (renamed from 0008)
  - 0005-libapparmor-mention-dbus-method-in-getcon-man.patch (renamed from
    0068)
  - 0006-etc-writable.patch (renamed from 0070)
  - 0007-aa-utils_are_bilingual.patch (renamed from 0077)
  - 0008-remove-ptrace.patch
  - 0009-convert-to-rules.patch
  - 0010-list-fns.patch
  - 0011-parse-mode.patch
  - 0012-add-decimal-interp.patch
  - 0013-policy_mediates.patch
  - 0014-fix-failpath.patch
  - 0015-feature_file.patch
  - 0016-fix-network.patch
  - 0017-aare-to-class.patch
  - 0018-add-mediation-unix.patch
  - 0019-parser_version.patch
  - 0020-caching.patch
  - 0021-label-class.patch
  - 0022-signal.patch
  - 0023-fix-lexer-debug.patch
  - 0024-ptrace.patch
  - 0025-use-diff-encode.patch
  - 0026-fix-serialize.patch
  - 0027-fix-af.patch
  - 0028-opt_arg.patch
  - 0029-tests-cond-dbus.patch
  - 0030-tests.diff
* Move manpages from libapparmor1 to libapparmor-dev
  - debian/libapparmor-dev.manpages: install aa_change_hat.2,
    aa_change_profile.2, aa_find_mountpoint.2, aa_getcon.2
  - debian/control: libapparmor-dev Replaces: and Breaks: libapparmor1
* Move /usr/lib/python3/dist-packages/apparmor/__init__.py from
  apparmor-easyprof to python3-apparmor
  - debian/control: python3-apparmor Breaks: apparmor-easyprof
  - debian/apparmor-easyprof.install: remove
    usr/lib/python*.*/site-packages/apparmor*
* New profiles and abstractions:
  - debian/apparmor.install: tunables/dovecot, tunables/kernelvars,
    tunables/xdg-user-dirs, tunables/xdg-user-dirs.d
* Test merge from upstream new pyutils branch (rev 2385)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Description: parser: Add support for DBus rules
2
 
 .
3
 
 This patch implements the parsing of DBus rules.
4
 
 .
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.
8
 
 .
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.
12
 
 .
13
 
 The DBus rules are encoded as follows:
14
 
 .
15
 
 bus,name<bind_perm>,peer_label,path,interface,member<rw_perms>
16
 
 .
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
22
 
 of a rw rule.
23
 
 .
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
30
 
 
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
44
 
 
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 $@ $<
49
 
 
50
 
+dbus.o: dbus.c dbus.h parser.h immunix.h
51
 
+       $(CC) $(EXTRA_CFLAGS) -c -o $@ $<
52
 
+
53
 
 parser_version.h: Makefile
54
 
        @echo \#define PARSER_VERSION \"$(VERSION)\" > .ver
55
 
        @mv -f .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
60
 
@@ -0,0 +1,183 @@
61
 
+/*
62
 
+ *   Copyright (c) 2013
63
 
+ *   Canonical, Ltd. (All rights reserved)
64
 
+ *
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.
68
 
+ *
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.
73
 
+ *
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
76
 
+ *   Ltd.
77
 
+ */
78
 
+
79
 
+#include <stdlib.h>
80
 
+#include <string.h>
81
 
+
82
 
+#include "parser.h"
83
 
+#include "parser_yacc.h"
84
 
+#include "dbus.h"
85
 
+
86
 
+void free_dbus_entry(struct dbus_entry *ent)
87
 
+{
88
 
+       if (!ent)
89
 
+               return;
90
 
+       free(ent->bus);
91
 
+       free(ent->name);
92
 
+       free(ent->peer_label);
93
 
+       free(ent->path);
94
 
+       free(ent->interface);
95
 
+       free(ent->member);
96
 
+
97
 
+       free(ent);
98
 
+}
99
 
+
100
 
+static int list_len(struct value_list *v)
101
 
+{
102
 
+       int len = 0;
103
 
+       struct value_list *tmp;
104
 
+
105
 
+       list_for_each(v, tmp)
106
 
+               len++;
107
 
+
108
 
+       return len;
109
 
+}
110
 
+
111
 
+static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent)
112
 
+{
113
 
+       if (*dst_ptr)
114
 
+               yyerror("dbus conditional \"%s\" can only be specified once\n",
115
 
+                       cond_ent->name);
116
 
+
117
 
+       *dst_ptr = cond_ent->vals->value;
118
 
+       cond_ent->vals->value = NULL;
119
 
+}
120
 
+
121
 
+static void move_conditionals(struct dbus_entry *ent, struct cond_entry *conds)
122
 
+{
123
 
+       struct cond_entry *cond_ent;
124
 
+
125
 
+       list_for_each(conds, cond_ent) {
126
 
+               /* for now disallow keyword 'in' (list) */
127
 
+               if (!cond_ent->eq)
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",
131
 
+                               cond_ent->name);
132
 
+
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);
145
 
+               } else {
146
 
+                       yyerror("invalid dbus conditional \"%s\"\n",
147
 
+                               cond_ent->name);
148
 
+               }
149
 
+       }
150
 
+}
151
 
+
152
 
+struct dbus_entry *new_dbus_entry(int mode, struct cond_entry *conds,
153
 
+                                 struct cond_entry *peer_conds)
154
 
+{
155
 
+       struct dbus_entry *ent;
156
 
+       int name_is_subject_cond = 0, message_rule = 0, service_rule = 0;
157
 
+
158
 
+       ent = (struct dbus_entry*) calloc(1, sizeof(struct dbus_entry));
159
 
+       if (!ent)
160
 
+               goto out;
161
 
+
162
 
+       /* Move the global/subject conditionals over & check the results */
163
 
+       move_conditionals(ent, conds);
164
 
+       if (ent->name)
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");
168
 
+
169
 
+       /* Move the peer conditionals */
170
 
+       move_conditionals(ent, peer_conds);
171
 
+
172
 
+       if (ent->path || ent->interface || ent->member || ent->peer_label ||
173
 
+           (ent->name && !name_is_subject_cond))
174
 
+               message_rule = 1;
175
 
+
176
 
+       if (ent->name && name_is_subject_cond)
177
 
+               service_rule = 1;
178
 
+
179
 
+       if (message_rule && service_rule)
180
 
+               yyerror("dbus rule contains message conditionals and service conditionals\n");
181
 
+
182
 
+       /* Copy mode. If no mode was specified, assign an implied mode. */
183
 
+       if (mode) {
184
 
+               ent->mode = 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");
191
 
+       } else {
192
 
+               ent->mode = AA_VALID_DBUS_PERMS;
193
 
+               if (message_rule)
194
 
+                       ent->mode &= ~AA_DBUS_BIND;
195
 
+               else if (service_rule)
196
 
+                       ent->mode &= ~(AA_DBUS_SEND | AA_DBUS_RECEIVE);
197
 
+       }
198
 
+
199
 
+out:
200
 
+       free_cond_list(conds);
201
 
+       return ent;
202
 
+}
203
 
+
204
 
+
205
 
+void print_dbus_entry(struct dbus_entry *ent)
206
 
+{
207
 
+       if (ent->audit)
208
 
+               fprintf(stderr, "audit ");
209
 
+       if (ent->deny)
210
 
+               fprintf(stderr, "deny ");
211
 
+
212
 
+       fprintf(stderr, "dbus ( ");
213
 
+
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, ")");
221
 
+
222
 
+       if (ent->bus)
223
 
+               fprintf(stderr, " bus=\"%s\"", ent->bus);
224
 
+       if ((ent->mode & AA_DBUS_BIND) && ent->name)
225
 
+               fprintf(stderr, " name=\"%s\"", ent->name);
226
 
+       if (ent->path)
227
 
+               fprintf(stderr, " path=\"%s\"", ent->path);
228
 
+       if (ent->interface)
229
 
+               fprintf(stderr, " interface=\"%s\"", ent->interface);
230
 
+       if (ent->member)
231
 
+               fprintf(stderr, " member=\"%s\"", ent->member);
232
 
+
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);
237
 
+               if (ent->name)
238
 
+                       fprintf(stderr, "name=\"%s\" ", ent->name);
239
 
+               fprintf(stderr, ")");
240
 
+       }
241
 
+
242
 
+       fprintf(stderr, ",\n");
243
 
+}
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
248
 
@@ -0,0 +1,48 @@
249
 
+/*
250
 
+ *   Copyright (c) 2013
251
 
+ *   Canonical, Ltd. (All rights reserved)
252
 
+ *
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.
256
 
+ *
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.
261
 
+ *
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
264
 
+ *   Ltd.
265
 
+ */
266
 
+
267
 
+#ifndef __AA_DBUS_H
268
 
+#define __AA_DBUS_H
269
 
+
270
 
+#include "parser.h"
271
 
+
272
 
+struct dbus_entry {
273
 
+       char *bus;
274
 
+       /**
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.
278
 
+        */
279
 
+       char *name;
280
 
+       char *peer_label;
281
 
+       char *path;
282
 
+       char *interface;
283
 
+       char *member;
284
 
+       int mode;
285
 
+       int audit;
286
 
+       int deny;
287
 
+
288
 
+       struct dbus_entry *next;
289
 
+};
290
 
+
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);
295
 
+
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
301
 
@@ -40,6 +40,13 @@
302
 
 #define AA_EXEC_MOD_2                  (1 << 12)
303
 
 #define AA_EXEC_MOD_3                  (1 << 13)
304
 
 
305
 
+#define AA_DBUS_SEND                   AA_MAY_WRITE
306
 
+#define AA_DBUS_RECEIVE                        AA_MAY_READ
307
 
+#define AA_DBUS_BIND                   (1 << 6)
308
 
+
309
 
+#define AA_VALID_DBUS_PERMS            (AA_DBUS_SEND | AA_DBUS_RECEIVE | \
310
 
+                                        AA_DBUS_BIND)
311
 
+
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 {
320
 
 
321
 
        char *exec_table[AA_EXEC_COUNT];
322
 
        struct cod_entry *entries;
323
 
+       struct dbus_entry *dbus_ents;
324
 
        struct mnt_entry *mnt_ents;
325
 
 
326
 
        void *hat_table;
327
 
@@ -301,6 +302,8 @@ extern char *basedir;
328
 
 /* parser_regex.c */
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);
332
 
+
333
 
 extern void reset_regex(void);
334
 
 
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,
350
 
                                   char *link_id);
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);
357
 
 
358
 
 /* parser_symtab.c */
359
 
 struct set_value {;
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
372
 
@@ -52,6 +52,12 @@
373
 
 #define NPDEBUG(fmt, args...)  /* Do nothing */
374
 
 
375
 
 #define DUMP_PREPROCESS do { if (preprocess_only) ECHO; } while (0)
376
 
+#define RETURN_TOKEN(X) \
377
 
+do { \
378
 
+       DUMP_PREPROCESS; \
379
 
+       PDEBUG("Matched: %s\n", yytext); \
380
 
+       return (X); \
381
 
+} while (0)
382
 
 
383
 
 #define YY_NO_INPUT
384
 
 
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})
393
 
-IDS_NOEQ       {ID_NOEQ}+
394
 
+IDS_NOEQ       {LEADING_ID_CHARS_NOEQ}{ID_NOEQ}*
395
 
 ALLOWED_QUOTED_ID      [^\0"]|\\\"
396
 
 QUOTED_ID      \"{ALLOWED_QUOTED_ID}*\"
397
 
 
398
 
@@ -217,11 +225,16 @@ LT_EQUAL  <=
399
 
 %x SUB_ID
400
 
 %x SUB_VALUE
401
 
 %x EXTCOND_MODE
402
 
+%x EXTCONDLIST_MODE
403
 
 %x NETWORK_MODE
404
 
 %x LIST_VAL_MODE
405
 
+%x LIST_COND_MODE
406
 
+%x LIST_COND_VAL
407
 
+%x LIST_COND_PAREN_VAL
408
 
 %x ASSIGN_MODE
409
 
 %x RLIMIT_MODE
410
 
 %x MOUNT_MODE
411
 
+%x DBUS_MODE
412
 
 %x CHANGE_PROFILE_MODE
413
 
 %x INCLUDE
414
 
 
415
 
@@ -267,7 +280,7 @@ LT_EQUAL    <=
416
 
        if ( !YY_CURRENT_BUFFER ) yyterminate();
417
 
 }
418
 
 
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
427
 
                                 */
428
 
+                               int token = get_keyword_token(yytext);
429
 
+
430
 
                                DUMP_PREPROCESS;
431
 
-                               PDEBUG("conditional %s=\n", yytext);
432
 
-                               yylval.id = processid(yytext, yyleng);
433
 
-                               yy_push_state(EXTCOND_MODE);
434
 
-                               return TOK_CONDID;
435
 
+                               if (token == TOK_PEER) {
436
 
+                                       PDEBUG("conditional list %s=\n", yytext);
437
 
+                                       yy_push_state(EXTCONDLIST_MODE);
438
 
+                                       return TOK_CONDLISTID;
439
 
+                               } else {
440
 
+                                       PDEBUG("conditional %s=\n", yytext);
441
 
+                                       yylval.id = processid(yytext, yyleng);
442
 
+                                       yy_push_state(EXTCOND_MODE);
443
 
+                                       return TOK_CONDID;
444
 
+                               }
445
 
                        }
446
 
        {VARIABLE_NAME}/{WS}+in{WS}*\(  {
447
 
                                /* we match to 'in' in the lexer so that
448
 
@@ -411,6 +432,116 @@ LT_EQUAL  <=
449
 
 
450
 
 }
451
 
 
452
 
+<LIST_COND_VAL>{
453
 
+       {WS}+           { DUMP_PREPROCESS; /* Eat whitespace */ }
454
 
+
455
 
+       ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
456
 
+                       DUMP_PREPROCESS;
457
 
+                       yylval.id = processid(yytext, yyleng);
458
 
+                       PDEBUG("listcond value: \"%s\"\n",  yylval.id);
459
 
+                       yy_pop_state();
460
 
+                       return TOK_VALUE;
461
 
+               }
462
 
+
463
 
+       [^\n]   {
464
 
+                       DUMP_PREPROCESS;
465
 
+                       /* Something we didn't expect */
466
 
+                       yyerror(_("Found unexpected character: '%s'"), yytext);
467
 
+               }
468
 
+}
469
 
+
470
 
+<LIST_COND_PAREN_VAL>{
471
 
+       {CLOSE_PAREN}   {
472
 
+                       DUMP_PREPROCESS;
473
 
+                       yy_pop_state();
474
 
+                       }
475
 
+
476
 
+       {WS}+           { DUMP_PREPROCESS; /* Eat whitespace */ }
477
 
+
478
 
+       ({LIST_VALUE_ID}|{QUOTED_LIST_VALUE_ID}) {
479
 
+                       DUMP_PREPROCESS;
480
 
+                       yylval.id = processid(yytext, yyleng);
481
 
+                       PDEBUG("listcond paren value: \"%s\"\n",  yylval.id);
482
 
+                       return TOK_VALUE;
483
 
+               }
484
 
+
485
 
+       [^\n]   {
486
 
+                       DUMP_PREPROCESS;
487
 
+                       /* Something we didn't expect */
488
 
+                       yyerror(_("Found unexpected character: '%s'"), yytext);
489
 
+               }
490
 
+}
491
 
+
492
 
+<LIST_COND_MODE>{
493
 
+       {CLOSE_PAREN}   {
494
 
+                       DUMP_PREPROCESS;
495
 
+                       PDEBUG("listcond: )\n");
496
 
+                       yy_pop_state();
497
 
+                       return TOK_CLOSEPAREN;
498
 
+                       }
499
 
+
500
 
+       {WS}+           { DUMP_PREPROCESS; /* Eat whitespace */ }
501
 
+
502
 
+       {COMMA}         {
503
 
+                       DUMP_PREPROCESS;
504
 
+                       PDEBUG("listcond: , \n");
505
 
+                       /* Eat comma, its an optional separator */
506
 
+                       }
507
 
+
508
 
+       {ID_CHARS_NOEQ}+        {
509
 
+                       DUMP_PREPROCESS;
510
 
+                       PDEBUG("listcond conditional %s=\n", yytext);
511
 
+                       yylval.id = processid(yytext, yyleng);
512
 
+                       return TOK_CONDID;
513
 
+                       }
514
 
+
515
 
+       {EQUALS}{WS}*{OPEN_PAREN}       {
516
 
+                       DUMP_PREPROCESS;
517
 
+                       yy_push_state(LIST_COND_PAREN_VAL);
518
 
+                       return TOK_EQUALS;
519
 
+                       }
520
 
+
521
 
+       {EQUALS}        {
522
 
+                       DUMP_PREPROCESS;
523
 
+                       yy_push_state(LIST_COND_VAL);
524
 
+                       return TOK_EQUALS;
525
 
+                       }
526
 
+
527
 
+       [^\n]           {
528
 
+                       DUMP_PREPROCESS;
529
 
+                       /* Something we didn't expect */
530
 
+                       yyerror(_("Found unexpected character: '%s'"), yytext);
531
 
+                       }
532
 
+}
533
 
+
534
 
+<EXTCONDLIST_MODE>{
535
 
+       {WS}+           { DUMP_PREPROCESS; /* Eat whitespace */ }
536
 
+
537
 
+       {EQUALS}        {
538
 
+                       DUMP_PREPROCESS;
539
 
+                       return TOK_EQUALS;
540
 
+               }
541
 
+
542
 
+       {OPEN_PAREN}    {
543
 
+                       DUMP_PREPROCESS;
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
549
 
+                        */
550
 
+                       BEGIN(LIST_COND_MODE);
551
 
+                       return TOK_OPENPAREN;
552
 
+               }
553
 
+
554
 
+       [^\n]   {
555
 
+                       DUMP_PREPROCESS;
556
 
+                       /* Something we didn't expect */
557
 
+                       yyerror(_("Found unexpected character: '%s' %d"), yytext, *yytext);
558
 
+               }
559
 
+
560
 
+}
561
 
+
562
 
 <ASSIGN_MODE>{
563
 
        {WS}+           { DUMP_PREPROCESS; /* Eat whitespace */ }
564
 
 
565
 
@@ -536,7 +667,23 @@ LT_EQUAL   <=
566
 
                        }
567
 
 }
568
 
 
569
 
-<MOUNT_MODE>{
570
 
+<DBUS_MODE>{
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); }
576
 
+       {OPEN_PAREN}    {
577
 
+                       yy_push_state(LIST_VAL_MODE);
578
 
+                       RETURN_TOKEN(TOK_OPENPAREN);
579
 
+                       }
580
 
+       (r|w|rw|wr)/([[:space:],])      {
581
 
+                       yylval.mode = strdup(yytext);
582
 
+                       RETURN_TOKEN(TOK_MODE);
583
 
+                       }
584
 
+}
585
 
+
586
 
+<MOUNT_MODE,DBUS_MODE>{
587
 
        {WS}+           {  DUMP_PREPROCESS; /* Ignoring whitespace */ }
588
 
 
589
 
        {ARROW}         {
590
 
@@ -698,6 +845,10 @@ LT_EQUAL   <=
591
 
                                PDEBUG("Entering mount\n");
592
 
                                yy_push_state(MOUNT_MODE);
593
 
                                break;
594
 
+                       case TOK_DBUS:
595
 
+                               PDEBUG("Entering dbus\n");
596
 
+                               yy_push_state(DBUS_MODE);
597
 
+                               break;
598
 
                        default: /* nothing */
599
 
                                break;
600
 
                        }
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
605
 
@@ -38,6 +38,7 @@
606
 
 #include "parser.h"
607
 
 #include "parser_yacc.h"
608
 
 #include "mount.h"
609
 
+#include "dbus.h"
610
 
 
611
 
 /* #define DEBUG */
612
 
 #ifdef DEBUG
613
 
@@ -85,6 +86,14 @@ static struct keyword_table keyword_tabl
614
 
        {"unmount",             TOK_UMOUNT},
615
 
        {"pivot_root",          TOK_PIVOTROOT},
616
 
        {"in",                  TOK_IN},
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},
624
 
+
625
 
        /* terminate */
626
 
        {NULL, 0}
627
 
 };
628
 
@@ -718,6 +727,81 @@ int parse_mode(const char *str_mode)
629
 
        return mode;
630
 
 }
631
 
 
632
 
+static int parse_dbus_sub_mode(const char *str_mode, int *result, int fail, const char *mode_desc __unused)
633
 
+{
634
 
+       int mode = 0;
635
 
+       const char *p;
636
 
+
637
 
+       PDEBUG("Parsing DBus mode: %s\n", str_mode);
638
 
+
639
 
+       if (!str_mode)
640
 
+               return 0;
641
 
+
642
 
+       p = str_mode;
643
 
+       while (*p) {
644
 
+               char this = *p;
645
 
+               char lower;
646
 
+
647
 
+reeval:
648
 
+               switch (this) {
649
 
+               case COD_READ_CHAR:
650
 
+                       PDEBUG("Parsing DBus mode: found %s READ\n", mode_desc);
651
 
+                       mode |= AA_DBUS_RECEIVE;
652
 
+                       break;
653
 
+
654
 
+               case COD_WRITE_CHAR:
655
 
+                       PDEBUG("Parsing DBus mode: found %s WRITE\n",
656
 
+                              mode_desc);
657
 
+                       mode |= AA_DBUS_SEND;
658
 
+                       break;
659
 
+
660
 
+               /* error cases */
661
 
+
662
 
+               default:
663
 
+                       lower = tolower(this);
664
 
+                       switch (lower) {
665
 
+                       case COD_READ_CHAR:
666
 
+                       case COD_WRITE_CHAR:
667
 
+                               PDEBUG("Parsing DBus mode: found invalid upper case char %c\n",
668
 
+                                      this);
669
 
+                               warn_uppercase();
670
 
+                               this = lower;
671
 
+                               goto reeval;
672
 
+                               break;
673
 
+                       default:
674
 
+                               if (fail)
675
 
+                                       yyerror(_("Internal: unexpected DBus mode character '%c' in input"),
676
 
+                                               this);
677
 
+                               else
678
 
+                                       return 0;
679
 
+                               break;
680
 
+                       }
681
 
+                       break;
682
 
+               }
683
 
+               p++;
684
 
+       }
685
 
+
686
 
+       PDEBUG("Parsed DBus mode: %s 0x%x\n", str_mode, mode);
687
 
+
688
 
+       *result = mode;
689
 
+       return 1;
690
 
+}
691
 
+
692
 
+int parse_dbus_mode(const char *str_mode, int *mode, int fail)
693
 
+{
694
 
+       *mode = 0;
695
 
+       if (!parse_dbus_sub_mode(str_mode, mode, fail, ""))
696
 
+               return 0;
697
 
+       if (*mode & ~AA_VALID_DBUS_PERMS) {
698
 
+               if (fail)
699
 
+                       yyerror(_("Internal error generated invalid DBus perm 0x%x\n"),
700
 
+                                 mode);
701
 
+               else
702
 
+                       return 0;
703
 
+       }
704
 
+       return 1;
705
 
+}
706
 
+
707
 
 struct cod_entry *new_entry(char *namespace, char *id, int mode, char *link_id)
708
 
 {
709
 
        struct cod_entry *entry = NULL;
710
 
@@ -797,6 +881,16 @@ void free_mnt_entries(struct mnt_entry *
711
 
        free(list);
712
 
 }
713
 
 
714
 
+void free_dbus_entries(struct dbus_entry *list)
715
 
+{
716
 
+       if (!list)
717
 
+               return;
718
 
+       if (list->next)
719
 
+               free_dbus_entries(list->next);
720
 
+
721
 
+       free_dbus_entry(list);
722
 
+}
723
 
+
724
 
 static void debug_base_perm_mask(int mask)
725
 
 {
726
 
        if (HAS_MAY_READ(mask))
727
 
@@ -1047,6 +1141,15 @@ void free_cond_entry(struct cond_entry *
728
 
        }
729
 
 }
730
 
 
731
 
+void free_cond_list(struct cond_entry *ents)
732
 
+{
733
 
+       struct cond_entry *entry, *tmp;
734
 
+
735
 
+       list_for_each_safe(ents, entry, tmp) {
736
 
+               free_cond_entry(entry);
737
 
+       }
738
 
+}
739
 
+
740
 
 void print_cond_entry(struct cond_entry *ent)
741
 
 {
742
 
        if (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
747
 
@@ -30,6 +30,7 @@
748
 
 
749
 
 #include "parser.h"
750
 
 #include "mount.h"
751
 
+#include "dbus.h"
752
 
 #include "parser_yacc.h"
753
 
 
754
 
 /* #define DEBUG */
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);
760
 
        if (cod->dfarules)
761
 
                aare_delete_ruleset(cod->dfarules);
762
 
        if (cod->dfa)
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
767
 
@@ -29,6 +29,7 @@
768
 
 #include "libapparmor_re/apparmor_re.h"
769
 
 #include "libapparmor_re/aare_rules.h"
770
 
 #include "mount.h"
771
 
+#include "dbus.h"
772
 
 #include "policydb.h"
773
 
 
774
 
 enum error_type {
775
 
@@ -1041,7 +1042,107 @@ fail:
776
 
 }
777
 
 
778
 
 
779
 
-int post_process_policydb_ents(struct codomain *cod)
780
 
+static int process_dbus_entry(aare_ruleset_t *dfarules, struct dbus_entry *entry)
781
 
+{
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];
788
 
+       char *p, *vec[6];
789
 
+
790
 
+       pattern_t ptype;
791
 
+       int pos;
792
 
+
793
 
+       if (!entry)             /* shouldn't happen */
794
 
+               return TRUE;
795
 
+
796
 
+       p = busbuf;
797
 
+       p += sprintf(p, "\\x%02x", AA_CLASS_DBUS);
798
 
+
799
 
+       if (entry->bus) {
800
 
+               ptype = convert_aaregex_to_pcre(entry->bus, 0, p,
801
 
+                                               PATH_MAX+3 - (p - busbuf), &pos);
802
 
+               if (ptype == ePatternInvalid)
803
 
+                       goto fail;
804
 
+       } else {
805
 
+               /* match any char except \000 0 or more times */
806
 
+               strcpy(p, "[^\\000]*");
807
 
+       }
808
 
+       vec[0] = busbuf;
809
 
+
810
 
+       if (entry->name) {
811
 
+               ptype = convert_aaregex_to_pcre(entry->name, 0, namebuf,
812
 
+                                               PATH_MAX+3, &pos);
813
 
+               if (ptype == ePatternInvalid)
814
 
+                       goto fail;
815
 
+               vec[1] = namebuf;
816
 
+       } else {
817
 
+               /* match any char except \000 0 or more times */
818
 
+               vec[1] = "[^\\000]*";
819
 
+       }
820
 
+
821
 
+       if (entry->peer_label) {
822
 
+               ptype = convert_aaregex_to_pcre(entry->peer_label, 0,
823
 
+                                               peer_labelbuf, PATH_MAX+3,
824
 
+                                               &pos);
825
 
+               if (ptype == ePatternInvalid)
826
 
+                       goto fail;
827
 
+               vec[2] = peer_labelbuf;
828
 
+       } else {
829
 
+               /* match any char except \000 0 or more times */
830
 
+               vec[2] = "[^\\000]*";
831
 
+       }
832
 
+
833
 
+       if (entry->path) {
834
 
+               ptype = convert_aaregex_to_pcre(entry->path, 0, pathbuf,
835
 
+                                               PATH_MAX+3, &pos);
836
 
+               if (ptype == ePatternInvalid)
837
 
+                       goto fail;
838
 
+               vec[3] = pathbuf;
839
 
+       } else {
840
 
+               /* match any char except \000 0 or more times */
841
 
+               vec[3] = "[^\\000]*";
842
 
+       }
843
 
+
844
 
+       if (entry->interface) {
845
 
+               ptype = convert_aaregex_to_pcre(entry->interface, 0, ifacebuf,
846
 
+                                               PATH_MAX+3, &pos);
847
 
+               if (ptype == ePatternInvalid)
848
 
+                       goto fail;
849
 
+               vec[4] = ifacebuf;
850
 
+       } else {
851
 
+               /* match any char except \000 0 or more times */
852
 
+               vec[4] = "[^\\000]*";
853
 
+       }
854
 
+
855
 
+       if (entry->member) {
856
 
+               ptype = convert_aaregex_to_pcre(entry->member, 0, memberbuf,
857
 
+                                               PATH_MAX+3, &pos);
858
 
+               if (ptype == ePatternInvalid)
859
 
+                       goto fail;
860
 
+               vec[5] = memberbuf;
861
 
+       } else {
862
 
+               /* match any char except \000 0 or more times */
863
 
+               vec[5] = "[^\\000]*";
864
 
+       }
865
 
+
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))
868
 
+                       goto fail;
869
 
+       }
870
 
+       if (entry->mode & ~AA_DBUS_BIND) {
871
 
+               if (!aare_add_rule_vec(dfarules, entry->deny, entry->mode, entry->audit, 6, vec, dfaflags))
872
 
+                       goto fail;
873
 
+       }
874
 
+       return TRUE;
875
 
+
876
 
+fail:
877
 
+       return FALSE;
878
 
+}
879
 
+
880
 
+static int post_process_mnt_ents(struct codomain *cod)
881
 
 {
882
 
        int ret = TRUE;
883
 
        int count = 0;
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);
887
 
 
888
 
-       cod->policy_rule_count = count;
889
 
+       cod->policy_rule_count += count;
890
 
        return ret;
891
 
 }
892
 
 
893
 
+static int post_process_dbus_ents(struct codomain *cod)
894
 
+{
895
 
+       int ret = TRUE;
896
 
+       struct dbus_entry *entry;
897
 
+       int count = 0;
898
 
+
899
 
+       list_for_each(cod->dbus_ents, entry) {
900
 
+               if (regex_type == AARE_DFA &&
901
 
+                   !process_dbus_entry(cod->policy_rules, entry))
902
 
+                       ret = FALSE;
903
 
+               count++;
904
 
+       }
905
 
+
906
 
+       cod->policy_rule_count += count;
907
 
+       return ret;
908
 
+}
909
 
+
910
 
+int post_process_policydb_ents(struct codomain *cod)
911
 
+{
912
 
+       if (!post_process_mnt_ents(cod))
913
 
+               return FALSE;
914
 
+       if (!post_process_dbus_ents(cod))
915
 
+               return FALSE;
916
 
+
917
 
+       return TRUE;
918
 
+}
919
 
+
920
 
 int process_policydb(struct codomain *cod)
921
 
 {
922
 
        int error = -1;
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
927
 
@@ -33,6 +33,7 @@
928
 
 
929
 
 #include "parser.h"
930
 
 #include "mount.h"
931
 
+#include "dbus.h"
932
 
 #include "parser_include.h"
933
 
 #include <unistd.h>
934
 
 #include <netinet/in.h>
935
 
@@ -81,6 +82,7 @@ void add_local_entry(struct codomain *co
936
 
 
937
 
 %token TOK_ID
938
 
 %token TOK_CONDID
939
 
+%token TOK_CONDLISTID
940
 
 %token TOK_CARET
941
 
 %token TOK_OPEN
942
 
 %token TOK_CLOSE
943
 
@@ -122,6 +124,13 @@ void add_local_entry(struct codomain *co
944
 
 %token TOK_UMOUNT
945
 
 %token TOK_PIVOTROOT
946
 
 %token TOK_IN
947
 
+%token TOK_DBUS
948
 
+%token TOK_SEND
949
 
+%token TOK_RECEIVE
950
 
+%token TOK_BIND
951
 
+%token TOK_READ
952
 
+%token TOK_WRITE
953
 
+%token TOK_PEER
954
 
 
955
 
  /* rlimits */
956
 
 %token TOK_RLIMIT
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;
962
 
 
963
 
        struct flagval flags;
964
 
        int fmode;
965
 
@@ -174,6 +184,7 @@ void add_local_entry(struct codomain *co
966
 
 
967
 
 %type <id>     TOK_ID
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
979
 
 %type <flags>  flags
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
985
 
 %type <id>     opt_id
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
994
 
                $$ = $1;
995
 
        }
996
 
 
997
 
+rules:  rules opt_audit_flag TOK_DENY dbus_rule
998
 
+       {
999
 
+               $4->deny = $4->mode;
1000
 
+               if ($2)
1001
 
+                       $4->audit = $4->mode;
1002
 
+               $4->next = $1->dbus_ents;
1003
 
+               $1->dbus_ents = $4;
1004
 
+               $$ = $1;
1005
 
+       }
1006
 
+
1007
 
+rules: rules opt_audit_flag dbus_rule
1008
 
+       {
1009
 
+               if ($2)
1010
 
+                       $3->audit = $3->mode;
1011
 
+               $3->next = $1->dbus_ents;
1012
 
+               $1->dbus_ents = $3;
1013
 
+               $$ = $1;
1014
 
+       }
1015
 
+
1016
 
 rules: rules change_profile
1017
 
        {
1018
 
                PDEBUG("matched: rules change_profile\n");
1019
 
@@ -1103,6 +1139,14 @@ opt_conds: { /* nothing */ $$ = NULL; }
1020
 
                $$ = $2;
1021
 
        }
1022
 
 
1023
 
+cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN
1024
 
+       {
1025
 
+               $$ = $4;
1026
 
+       }
1027
 
+
1028
 
+opt_cond_list: { /* nothing */ $$ = NULL; }
1029
 
+       | cond_list { $$ = $1; }
1030
 
+
1031
 
 mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
1032
 
        {
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);
1036
 
        }
1037
 
 
1038
 
+dbus_perm: TOK_VALUE
1039
 
+       {
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;
1046
 
+               else if ($1) {
1047
 
+                       parse_dbus_mode($1, &$$, 1);
1048
 
+               } else
1049
 
+                       $$ = 0;
1050
 
+
1051
 
+               if ($1)
1052
 
+                       free($1);
1053
 
+       }
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; }
1059
 
+       | TOK_MODE
1060
 
+       {
1061
 
+               parse_dbus_mode($1, &$$, 1);
1062
 
+       }
1063
 
+
1064
 
+dbus_perms: { /* nothing */ $$ = 0; }
1065
 
+       | dbus_perms dbus_perm { $$ = $1 | $2; }
1066
 
+       | dbus_perms TOK_COMMA dbus_perm { $$ = $1 | $3; }
1067
 
+
1068
 
+opt_dbus_perm: { /* nothing */ $$ = 0; }
1069
 
+       | dbus_perm  { $$ = $1; }
1070
 
+       | TOK_OPENPAREN dbus_perms TOK_CLOSEPAREN { $$ = $2; }
1071
 
+
1072
 
+dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE
1073
 
+       {
1074
 
+               struct dbus_entry *ent;
1075
 
+
1076
 
+               ent = new_dbus_entry($2, $3, $4);
1077
 
+               if (!ent) {
1078
 
+                       yyerror(_("Memory allocation error."));
1079
 
+               }
1080
 
+               $$ = ent;
1081
 
+       }
1082
 
+
1083
 
 hat_start: TOK_CARET {}
1084
 
        | TOK_HAT {}
1085