~ubuntu-branches/ubuntu/trusty/apparmor/trusty-security

« back to all changes in this revision

Viewing changes to .pc/0024-lp1091642-parser-reset_matchflags.patch/parser/libapparmor_re/aare_rules.cc

  • Committer: Package Import Robot
  • Author(s): Seth Arnold, Jamie Strandboge, Seth Arnold, Jamie Strandboge, Steve Beattie, John Johansen, Tyler Hicks
  • Date: 2014-03-19 20:29:27 UTC
  • mfrom: (1.1.26)
  • Revision ID: package-import@ubuntu.com-20140319202927-ul597pahqsvsl2ea
Tags: 2.8.95~2430-0ubuntu1
[ 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/rules: delete upstream-provided xdg-user-dirs.d/site.local
* debian/apparmor.postinst: create xdg-user-dirs.d/site.local
* debian/apparmor.postrm: remove xdg-user-dirs.d
* Remaining patches:
  - add-chromium-browser.patch
  - add-debian-integration-to-lighttpd.patch
  - ubuntu-manpage-updates.patch
  - libapparmor-layout-deb.patch
  - libapparmor-mention-dbus-method-in-getcon-man.patch
  - etc-writable.patch
  - aa-utils_are_bilingual.patch
* New patches:
  - convert-to-rules.patch
  - list-fns.patch
  - parse-mode.patch
  - add-decimal-interp.patch
  - policy_mediates.patch
  - fix-failpath.patch
  - feature_file.patch
  - fix-network.patch
  - aare-to-class.patch
  - add-mediation-unix.patch
  - parser_version.patch
  - caching.patch
  - label-class.patch
  - fix-lexer-debug.patch
  - use-diff-encode.patch
  - fix-serialize.patch
  - fix-ppc-endian-ftbfs.patch
  - opt_arg.patch
  - tests-cond-dbus.patch
* 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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * (C) 2006, 2007 Andreas Gruenbacher <agruen@suse.de>
3
 
 * Copyright (c) 2003-2008 Novell, Inc. (All rights reserved)
4
 
 * Copyright 2009-2012 Canonical Ltd.
5
 
 *
6
 
 * The libapparmor library is licensed under the terms of the GNU
7
 
 * Lesser General Public License, version 2.1. Please see the file
8
 
 * COPYING.LGPL.
9
 
 *
10
 
 * This library is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU Lesser General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU Lesser General Public License
16
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
 *
18
 
 *
19
 
 * Wrapper around the dfa to convert aa rules into a dfa
20
 
 */
21
 
 
22
 
#include <ostream>
23
 
#include <iostream>
24
 
#include <fstream>
25
 
#include <sstream>
26
 
#include <ext/stdio_filebuf.h>
27
 
#include <assert.h>
28
 
#include <stdlib.h>
29
 
 
30
 
#include "aare_rules.h"
31
 
#include "expr-tree.h"
32
 
#include "parse.h"
33
 
#include "hfa.h"
34
 
#include "chfa.h"
35
 
#include "../immunix.h"
36
 
 
37
 
struct aare_ruleset {
38
 
        int reverse;
39
 
        Node *root;
40
 
};
41
 
 
42
 
extern "C" aare_ruleset_t *aare_new_ruleset(int reverse)
43
 
{
44
 
        aare_ruleset_t *container = (aare_ruleset_t *) malloc(sizeof(aare_ruleset_t));
45
 
        if (!container)
46
 
                return NULL;
47
 
 
48
 
        container->root = NULL;
49
 
        container->reverse = reverse;
50
 
 
51
 
        return container;
52
 
}
53
 
 
54
 
extern "C" void aare_delete_ruleset(aare_ruleset_t *rules)
55
 
{
56
 
        if (rules) {
57
 
                if (rules->root)
58
 
                        rules->root->release();
59
 
                free(rules);
60
 
        }
61
 
}
62
 
 
63
 
extern "C" int aare_add_rule(aare_ruleset_t *rules, char *rule, int deny,
64
 
                             uint32_t perms, uint32_t audit, dfaflags_t flags)
65
 
{
66
 
        return aare_add_rule_vec(rules, deny, perms, audit, 1, &rule, flags);
67
 
}
68
 
 
69
 
#define FLAGS_WIDTH 2
70
 
#define MATCH_FLAGS_SIZE (sizeof(uint32_t) * 8 - 1)
71
 
MatchFlag *match_flags[FLAGS_WIDTH][MATCH_FLAGS_SIZE];
72
 
DenyMatchFlag *deny_flags[FLAGS_WIDTH][MATCH_FLAGS_SIZE];
73
 
#define EXEC_MATCH_FLAGS_SIZE (AA_EXEC_COUNT *2 * 2 * 2)        /* double for each of ix pux, unsafe x bits * u::o */
74
 
MatchFlag *exec_match_flags[FLAGS_WIDTH][EXEC_MATCH_FLAGS_SIZE];        /* mods + unsafe + ix + pux * u::o */
75
 
ExactMatchFlag *exact_match_flags[FLAGS_WIDTH][EXEC_MATCH_FLAGS_SIZE];  /* mods + unsafe + ix + pux *u::o */
76
 
 
77
 
extern "C" void aare_reset_matchflags(void)
78
 
{
79
 
        uint32_t i, j;
80
 
#define RESET_FLAGS(group, size) { \
81
 
        for (i = 0; i < FLAGS_WIDTH; i++) { \
82
 
                for (j = 0; j < size; j++) { \
83
 
                    if ((group)[i][j]) delete (group)[i][j];    \
84
 
                        (group)[i][j] = NULL; \
85
 
                } \
86
 
        } \
87
 
}
88
 
        RESET_FLAGS(match_flags, MATCH_FLAGS_SIZE);
89
 
        RESET_FLAGS(deny_flags, MATCH_FLAGS_SIZE);
90
 
        RESET_FLAGS(exec_match_flags, EXEC_MATCH_FLAGS_SIZE);
91
 
        RESET_FLAGS(exact_match_flags, EXEC_MATCH_FLAGS_SIZE);
92
 
#undef RESET_FLAGS
93
 
}
94
 
 
95
 
extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny,
96
 
                                 uint32_t perms, uint32_t audit,
97
 
                                 int count, char **rulev, dfaflags_t flags)
98
 
{
99
 
        Node *tree = NULL, *accept;
100
 
        int exact_match;
101
 
        uint32_t allow = perms;
102
 
 
103
 
        assert(perms != 0);
104
 
 
105
 
        if (regex_parse(&tree, rulev[0]))
106
 
                return 0;
107
 
        for (int i = 1; i < count; i++) {
108
 
                Node *subtree = NULL;
109
 
                Node *node = new CharNode(0);
110
 
                if (!node)
111
 
                        return 0;
112
 
                tree = new CatNode(tree, node);
113
 
                if (regex_parse(&subtree, rulev[i]))
114
 
                        return 0;
115
 
                tree = new CatNode(tree, subtree);
116
 
        }
117
 
 
118
 
        /*
119
 
         * Check if we have an expression with or without wildcards. This
120
 
         * determines how exec modifiers are merged in accept_perms() based
121
 
         * on how we split permission bitmasks here.
122
 
         */
123
 
        exact_match = 1;
124
 
        for (depth_first_traversal i(tree); i; i++) {
125
 
                if (dynamic_cast<StarNode *>(*i) ||
126
 
                    dynamic_cast<PlusNode *>(*i) ||
127
 
                    dynamic_cast<AnyCharNode *>(*i) ||
128
 
                    dynamic_cast<CharSetNode *>(*i) ||
129
 
                    dynamic_cast<NotCharSetNode *>(*i))
130
 
                        exact_match = 0;
131
 
        }
132
 
 
133
 
        if (rules->reverse)
134
 
                flip_tree(tree);
135
 
 
136
 
/* 0x7f == 4 bits x mods + 1 bit unsafe mask + 1 bit ix, + 1 pux after shift */
137
 
#define EXTRACT_X_INDEX(perm, shift) (((perm) >> (shift + 7)) & 0x7f)
138
 
 
139
 
//if (perms & ALL_AA_EXEC_TYPE && (!perms & AA_EXEC_BITS))
140
 
//      fprintf(stderr, "adding X rule without MAY_EXEC: 0x%x %s\n", perms, rulev[0]);
141
 
 
142
 
//if (perms & ALL_EXEC_TYPE)
143
 
//    fprintf(stderr, "adding X rule %s 0x%x\n", rulev[0], perms);
144
 
 
145
 
//if (audit)
146
 
//fprintf(stderr, "adding rule with audit bits set: 0x%x %s\n", audit, rulev[0]);
147
 
 
148
 
//if (perms & AA_CHANGE_HAT)
149
 
//    fprintf(stderr, "adding change_hat rule %s\n", rulev[0]);
150
 
 
151
 
/* the permissions set is assumed to be non-empty if any audit
152
 
 * bits are specified */
153
 
        accept = NULL;
154
 
        for (unsigned int n = 0; perms && n < (sizeof(perms) * 8); n++) {
155
 
                uint32_t mask = 1 << n;
156
 
 
157
 
                if (!(perms & mask))
158
 
                        continue;
159
 
 
160
 
                int ai = audit & mask ? 1 : 0;
161
 
                perms &= ~mask;
162
 
 
163
 
                Node *flag;
164
 
                if (mask & ALL_AA_EXEC_TYPE)
165
 
                        /* these cases are covered by EXEC_BITS */
166
 
                        continue;
167
 
                if (deny) {
168
 
                        if (deny_flags[ai][n]) {
169
 
                                flag = deny_flags[ai][n];
170
 
                        } else {
171
 
//fprintf(stderr, "Adding deny ai %d mask 0x%x audit 0x%x\n", ai, mask, audit & mask);
172
 
                                deny_flags[ai][n] = new DenyMatchFlag(mask, audit & mask);
173
 
                                flag = deny_flags[ai][n];
174
 
                        }
175
 
                } else if (mask & AA_EXEC_BITS) {
176
 
                        uint32_t eperm = 0;
177
 
                        uint32_t index = 0;
178
 
                        if (mask & AA_USER_EXEC) {
179
 
                                eperm = mask | (perms & AA_USER_EXEC_TYPE);
180
 
                                index = EXTRACT_X_INDEX(eperm, AA_USER_SHIFT);
181
 
                        } else {
182
 
                                eperm = mask | (perms & AA_OTHER_EXEC_TYPE);
183
 
                                index = EXTRACT_X_INDEX(eperm, AA_OTHER_SHIFT) + (AA_EXEC_COUNT << 2);
184
 
                        }
185
 
//fprintf(stderr, "index %d eperm 0x%x\n", index, eperm);
186
 
                        if (exact_match) {
187
 
                                if (exact_match_flags[ai][index]) {
188
 
                                        flag = exact_match_flags[ai][index];
189
 
                                } else {
190
 
                                        exact_match_flags[ai][index] = new ExactMatchFlag(eperm, audit & mask);
191
 
                                        flag = exact_match_flags[ai][index];
192
 
                                }
193
 
                        } else {
194
 
                                if (exec_match_flags[ai][index]) {
195
 
                                        flag = exec_match_flags[ai][index];
196
 
                                } else {
197
 
                                        exec_match_flags[ai][index] = new MatchFlag(eperm, audit & mask);
198
 
                                        flag = exec_match_flags[ai][index];
199
 
                                }
200
 
                        }
201
 
                } else {
202
 
                        if (match_flags[ai][n]) {
203
 
                                flag = match_flags[ai][n];
204
 
                        } else {
205
 
                                match_flags[ai][n] = new MatchFlag(mask, audit & mask);
206
 
                                flag = match_flags[ai][n];
207
 
                        }
208
 
                }
209
 
                if (accept)
210
 
                        accept = new AltNode(accept, flag);
211
 
                else
212
 
                        accept = flag;
213
 
        } /* for ... */
214
 
 
215
 
        if (flags & DFA_DUMP_RULE_EXPR) {
216
 
                cerr << "rule: ";
217
 
                cerr << rulev[0];
218
 
                for (int i = 1; i < count; i++) {
219
 
                        cerr << "\\x00";
220
 
                        cerr << rulev[i];
221
 
                }
222
 
                cerr << "  ->  ";
223
 
                tree->dump(cerr);
224
 
                if (deny)
225
 
                        cerr << " deny";
226
 
                cerr << " (0x" << hex << allow <<"/" << audit << dec << ")";
227
 
                accept->dump(cerr);
228
 
                cerr << "\n\n";
229
 
        }
230
 
 
231
 
        if (rules->root)
232
 
                rules->root = new AltNode(rules->root, new CatNode(tree, accept));
233
 
        else
234
 
                rules->root = new CatNode(tree, accept);
235
 
 
236
 
        return 1;
237
 
 
238
 
}
239
 
 
240
 
/* create a dfa from the ruleset
241
 
 * returns: buffer contain dfa tables, @size set to the size of the tables
242
 
 *          else NULL on failure
243
 
 */
244
 
extern "C" void *aare_create_dfa(aare_ruleset_t *rules, size_t *size,
245
 
                                 dfaflags_t flags)
246
 
{
247
 
        char *buffer = NULL;
248
 
 
249
 
        label_nodes(rules->root);
250
 
        if (flags & DFA_DUMP_TREE) {
251
 
                cerr << "\nDFA: Expression Tree\n";
252
 
                rules->root->dump(cerr);
253
 
                cerr << "\n\n";
254
 
        }
255
 
 
256
 
        if (flags & DFA_CONTROL_TREE_SIMPLE) {
257
 
                rules->root = simplify_tree(rules->root, flags);
258
 
 
259
 
                if (flags & DFA_DUMP_SIMPLE_TREE) {
260
 
                        cerr << "\nDFA: Simplified Expression Tree\n";
261
 
                        rules->root->dump(cerr);
262
 
                        cerr << "\n\n";
263
 
                }
264
 
        }
265
 
 
266
 
        stringstream stream;
267
 
        try {
268
 
                DFA dfa(rules->root, flags);
269
 
                if (flags & DFA_DUMP_UNIQ_PERMS)
270
 
                        dfa.dump_uniq_perms("dfa");
271
 
 
272
 
                if (flags & DFA_CONTROL_MINIMIZE) {
273
 
                        dfa.minimize(flags);
274
 
 
275
 
                        if (flags & DFA_DUMP_MIN_UNIQ_PERMS)
276
 
                                dfa.dump_uniq_perms("minimized dfa");
277
 
                }
278
 
 
279
 
                if (flags & DFA_CONTROL_FILTER_DENY &&
280
 
                    flags & DFA_CONTROL_MINIMIZE &&
281
 
                    dfa.apply_and_clear_deny()) {
282
 
                        /* Do a second minimization pass as removal of deny
283
 
                         * information has moved some states from accepting
284
 
                         * to none accepting partitions
285
 
                         *
286
 
                         * TODO: add this as a tail pass to minimization
287
 
                         *       so we don't need to do a full second pass
288
 
                         */
289
 
                        dfa.minimize(flags);
290
 
 
291
 
                        if (flags & DFA_DUMP_MIN_UNIQ_PERMS)
292
 
                                dfa.dump_uniq_perms("minimized dfa");
293
 
                }
294
 
 
295
 
                if (flags & DFA_CONTROL_REMOVE_UNREACHABLE)
296
 
                        dfa.remove_unreachable(flags);
297
 
 
298
 
                if (flags & DFA_DUMP_STATES)
299
 
                        dfa.dump(cerr);
300
 
 
301
 
                if (flags & DFA_DUMP_GRAPH)
302
 
                        dfa.dump_dot_graph(cerr);
303
 
 
304
 
                map<uchar, uchar> eq;
305
 
                if (flags & DFA_CONTROL_EQUIV) {
306
 
                        eq = dfa.equivalence_classes(flags);
307
 
                        dfa.apply_equivalence_classes(eq);
308
 
 
309
 
                        if (flags & DFA_DUMP_EQUIV) {
310
 
                                cerr << "\nDFA equivalence class\n";
311
 
                                dump_equivalence_classes(cerr, eq);
312
 
                        }
313
 
                } else if (flags & DFA_DUMP_EQUIV)
314
 
                        cerr << "\nDFA did not generate an equivalence class\n";
315
 
 
316
 
                CHFA chfa(dfa, eq, flags);
317
 
                if (flags & DFA_DUMP_TRANS_TABLE)
318
 
                        chfa.dump(cerr);
319
 
                chfa.flex_table(stream, "");
320
 
        }
321
 
        catch(int error) {
322
 
                *size = 0;
323
 
                return NULL;
324
 
        }
325
 
 
326
 
        stringbuf *buf = stream.rdbuf();
327
 
 
328
 
        buf->pubseekpos(0);
329
 
        *size = buf->in_avail();
330
 
 
331
 
        buffer = (char *)malloc(*size);
332
 
        if (!buffer)
333
 
                return NULL;
334
 
        buf->sgetn(buffer, *size);
335
 
        return buffer;
336
 
}