~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to module/apparmor/match/match_pcre.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *      Copyright (C) 2002-2005 Novell/SUSE
3
 
 *
4
 
 *      This program is free software; you can redistribute it and/or
5
 
 *      modify it under the terms of the GNU General Public License as
6
 
 *      published by the Free Software Foundation, version 2 of the
7
 
 *      License.
8
 
 *
9
 
 *      http://forge.novell.com/modules/xfmod/project/?apparmor
10
 
 *
11
 
 *      AppArmor aamatch submodule (w/ pattern expansion).
12
 
 *
13
 
 *      This module makes use of a slightly modified version of the PCRE
14
 
 *      library developed by Philip Hazel <ph10@cam.ac.uk>.  See the files
15
 
 *      pcre_* in this directory.
16
 
 */
17
 
 
18
 
#include <linux/module.h>
19
 
#include "match.h"
20
 
#include "pcre_exec.h"
21
 
#include "pcre_tables.h"
22
 
 
23
 
static const char *features="literal tailglob pattern=pcre";
24
 
 
25
 
struct aamatch_entry
26
 
{
27
 
        char *pattern;
28
 
        pcre *compiled;
29
 
};
30
 
 
31
 
void* aamatch_alloc(enum entry_match_type entry_type)
32
 
{
33
 
void *ptr=NULL;
34
 
 
35
 
        if (entry_type == aa_entry_pattern) {
36
 
                ptr = kmalloc(sizeof(struct aamatch_entry), GFP_KERNEL);
37
 
                if (ptr)
38
 
                        memset(ptr, 0, sizeof(struct aamatch_entry));
39
 
                else
40
 
                        ptr=ERR_PTR(-ENOMEM);
41
 
        } else if (entry_type != aa_entry_literal &&
42
 
                   entry_type != aa_entry_tailglob) {
43
 
                ptr = ERR_PTR(-EINVAL);
44
 
        }
45
 
 
46
 
        return ptr;
47
 
}
48
 
 
49
 
void aamatch_free(void *ptr)
50
 
{
51
 
        if (ptr) {
52
 
                struct aamatch_entry *ed = (struct aamatch_entry *) ptr;
53
 
                kfree(ed->pattern);
54
 
                kfree(ed->compiled);    /* allocated by AA_READ_X */
55
 
        }
56
 
        kfree(ptr);
57
 
}
58
 
 
59
 
const char *aamatch_features(void)
60
 
{
61
 
        return features;
62
 
}
63
 
 
64
 
int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
65
 
                      aamatch_serializecb cb)
66
 
{
67
 
#define AA_READ_X(E, C, D, N) \
68
 
        do { \
69
 
                if (!cb((E), (C), (D), (N))) { \
70
 
                        error = -EINVAL; \
71
 
                        goto done; \
72
 
                }\
73
 
        } while (0)
74
 
 
75
 
        int error = 0;
76
 
        u32 size, magic, opts;
77
 
        u8 t_char;
78
 
        struct aamatch_entry *ed = (struct aamatch_entry *) entry_extradata;
79
 
 
80
 
        if (ed == NULL)
81
 
                goto done;
82
 
 
83
 
        AA_READ_X(e, AA_DYN_STRING, &ed->pattern, NULL);
84
 
 
85
 
        /* size determines the real size of the pcre struct,
86
 
           it is size_t - sizeof(pcre) on user side.
87
 
           uschar must be the same in user and kernel space */
88
 
        /* check that we are processing the correct structure */
89
 
        AA_READ_X(e, AA_STRUCT, NULL, "pcre");
90
 
        AA_READ_X(e, AA_U32, &size, NULL);
91
 
        AA_READ_X(e, AA_U32, &magic, NULL);
92
 
 
93
 
        /* the allocation of pcre is delayed because it depends on the size
94
 
         * of the pattern */
95
 
        ed->compiled = (pcre *) kmalloc(size + sizeof(pcre), GFP_KERNEL);
96
 
        if (!ed->compiled) {
97
 
                error = -ENOMEM;
98
 
                goto done;
99
 
        }
100
 
 
101
 
        memset(ed->compiled, 0, size + sizeof(pcre));
102
 
        ed->compiled->magic_number = magic;
103
 
        ed->compiled->size = size + sizeof(pcre);
104
 
 
105
 
        AA_READ_X(e, AA_U32, &opts, NULL);
106
 
        ed->compiled->options = opts;
107
 
        AA_READ_X(e, AA_U16, &ed->compiled->top_bracket, NULL);
108
 
        AA_READ_X(e, AA_U16, &ed->compiled->top_backref, NULL);
109
 
        AA_READ_X(e, AA_U8, &t_char, NULL);
110
 
        ed->compiled->first_char = t_char;
111
 
        AA_READ_X(e, AA_U8, &t_char, NULL);
112
 
        ed->compiled->req_char = t_char;
113
 
        AA_READ_X(e, AA_U8, &t_char, NULL);
114
 
        ed->compiled->code[0] = t_char;
115
 
 
116
 
        AA_READ_X(e, AA_STATIC_BLOB, &ed->compiled->code[1], NULL);
117
 
 
118
 
        AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
119
 
 
120
 
        /* stitch in pcre patterns, it was NULLed out by parser
121
 
         * pcre_default_tables defined in pcre_tables.h */
122
 
        ed->compiled->tables = pcre_default_tables;
123
 
 
124
 
done:
125
 
        if (error != 0 && ed) {
126
 
                kfree(ed->pattern); /* allocated by AA_READ_X */
127
 
                kfree(ed->compiled);
128
 
                ed->pattern = NULL;
129
 
                ed->compiled = NULL;
130
 
        }
131
 
 
132
 
        return error;
133
 
}
134
 
 
135
 
unsigned int aamatch_match(const char *pathname, const char *entry_name,
136
 
                           enum entry_match_type entry_type, void *entry_extradata)
137
 
{
138
 
        int ret;
139
 
 
140
 
        if (entry_type == aa_entry_pattern) {
141
 
                int pcreret;
142
 
                struct aamatch_entry *ed =
143
 
                        (struct aamatch_entry *) entry_extradata;
144
 
 
145
 
                pcreret = pcre_exec(ed->compiled, NULL,
146
 
                                    pathname, strlen(pathname),
147
 
                                    0, 0, NULL, 0);
148
 
 
149
 
                ret = (pcreret >= 0);
150
 
 
151
 
                // XXX - this needs access to subdomain_debug,  hmmm
152
 
                //AA_DEBUG("%s(%d): %s %s %d\n", __FUNCTION__,
153
 
                //       ret, pathname, ed->pattern, pcreret);
154
 
        } else {
155
 
                ret = aamatch_match_common(pathname, entry_name, entry_type);
156
 
        }
157
 
 
158
 
        return ret;
159
 
}
160
 
 
161
 
EXPORT_SYMBOL_GPL(aamatch_alloc);
162
 
EXPORT_SYMBOL_GPL(aamatch_free);
163
 
EXPORT_SYMBOL_GPL(aamatch_features);
164
 
EXPORT_SYMBOL_GPL(aamatch_serialize);
165
 
EXPORT_SYMBOL_GPL(aamatch_match);
166
 
 
167
 
MODULE_DESCRIPTION("AppArmor aa_match module [pcre]");
168
 
MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
169
 
MODULE_LICENSE("GPL");