~ubuntu-branches/ubuntu/jaunty/checkpolicy/jaunty

« back to all changes in this revision

Viewing changes to module_compiler.c

  • Committer: Bazaar Package Importer
  • Author(s): Manoj Srivastava
  • Date: 2006-10-20 17:51:00 UTC
  • mfrom: (1.1.6 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20061020175100-hg5grqaote5ukt8c
Tags: 1.32-1
* New upstream release
  * Merged user and range_transition support for modules from Darrel
    Goeddel 
  * Updated version for release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "module_compiler.h"
23
23
 
24
24
union stack_item_u {
25
 
        avrule_block_t *avrule;
26
 
        cond_list_t *cond_list;
 
25
        avrule_block_t *avrule;
 
26
        cond_list_t *cond_list;
27
27
};
28
28
 
29
29
typedef struct scope_stack {
30
 
        union stack_item_u u;
31
 
        int type;  /* for above union: 1 = avrule block, 2 = conditional */
32
 
        avrule_decl_t *decl;  /* if in an avrule block, which
33
 
                               * declaration is current */
34
 
        avrule_t *last_avrule;
35
 
        int in_else;          /* if in an avrule block, within ELSE branch */
36
 
        int require_given;    /* 1 if this block had at least one require */
37
 
        struct scope_stack *parent, *child;
 
30
        union stack_item_u u;
 
31
        int type;               /* for above union: 1 = avrule block, 2 = conditional */
 
32
        avrule_decl_t *decl;    /* if in an avrule block, which
 
33
                                 * declaration is current */
 
34
        avrule_t *last_avrule;
 
35
        int in_else;            /* if in an avrule block, within ELSE branch */
 
36
        int require_given;      /* 1 if this block had at least one require */
 
37
        struct scope_stack *parent, *child;
38
38
} scope_stack_t;
39
39
 
40
40
extern policydb_t *policydbp;
50
50
static avrule_block_t *last_block;
51
51
static uint32_t next_decl_id = 1;
52
52
 
53
 
int define_policy(int pass, int module_header_given) {
54
 
        char *id;
55
 
        
56
 
        if (module_header_given) {
57
 
                if (policydbp->policy_type != POLICY_MOD) {
58
 
                        yyerror("Module specification found while not building a policy module.\n");
59
 
                        return -1;
60
 
                }
61
 
 
62
 
                if (pass == 2) {
63
 
                        while ((id = queue_remove(id_queue)) != NULL)
64
 
                                free(id);
65
 
                }
66
 
                else {
67
 
                        id = (char *) queue_remove(id_queue);
68
 
                        if (!id) {
69
 
                                yyerror("no module name");
70
 
                                return -1;
71
 
                        }
72
 
                        policydbp->name = id;
73
 
                        if ((policydbp->version = queue_remove(id_queue)) == NULL) {
74
 
                                yyerror("Expected a module version but none was found.");
75
 
                                return -1;
76
 
                        }
77
 
                }
78
 
        }
79
 
        else {
80
 
                if (policydbp->policy_type == POLICY_MOD) {
81
 
                        yyerror("Building a policy module, but no module specification found.\n");
82
 
                        return -1;
83
 
                }
84
 
        }
 
53
int define_policy(int pass, int module_header_given)
 
54
{
 
55
        char *id;
 
56
 
 
57
        if (module_header_given) {
 
58
                if (policydbp->policy_type != POLICY_MOD) {
 
59
                        yyerror
 
60
                            ("Module specification found while not building a policy module.\n");
 
61
                        return -1;
 
62
                }
 
63
 
 
64
                if (pass == 2) {
 
65
                        while ((id = queue_remove(id_queue)) != NULL)
 
66
                                free(id);
 
67
                } else {
 
68
                        id = (char *)queue_remove(id_queue);
 
69
                        if (!id) {
 
70
                                yyerror("no module name");
 
71
                                return -1;
 
72
                        }
 
73
                        policydbp->name = id;
 
74
                        if ((policydbp->version =
 
75
                             queue_remove(id_queue)) == NULL) {
 
76
                                yyerror
 
77
                                    ("Expected a module version but none was found.");
 
78
                                return -1;
 
79
                        }
 
80
                }
 
81
        } else {
 
82
                if (policydbp->policy_type == POLICY_MOD) {
 
83
                        yyerror
 
84
                            ("Building a policy module, but no module specification found.\n");
 
85
                        return -1;
 
86
                }
 
87
        }
85
88
        /* the first declaration within the global avrule
86
 
          block will always have an id of 1 */
 
89
           block will always have an id of 1 */
87
90
        next_decl_id = 2;
88
91
 
89
 
        /* reset the scoping stack */
90
 
        while (stack_top != NULL) {
91
 
                pop_stack();
92
 
        }
93
 
        if (push_stack(1, policydbp->global, policydbp->global->branch_list) == -1) {
94
 
                return -1;
95
 
        }
96
 
        last_block = policydbp->global;
97
 
        return 0;
 
92
        /* reset the scoping stack */
 
93
        while (stack_top != NULL) {
 
94
                pop_stack();
 
95
        }
 
96
        if (push_stack(1, policydbp->global, policydbp->global->branch_list) ==
 
97
            -1) {
 
98
                return -1;
 
99
        }
 
100
        last_block = policydbp->global;
 
101
        return 0;
98
102
}
99
103
 
100
104
/* Given the current parse stack, returns 1 if a declaration would be
102
106
 * allowed in conditionals, so if there are any conditionals in the
103
107
 * current scope stack then this would return a 0.
104
108
 */
105
 
static int is_declaration_allowed(void) {
106
 
        if (stack_top->type != 1 ||
107
 
            stack_top->in_else) {
108
 
                return 0;
109
 
        }
110
 
        return 1;
 
109
static int is_declaration_allowed(void)
 
110
{
 
111
        if (stack_top->type != 1 || stack_top->in_else) {
 
112
                return 0;
 
113
        }
 
114
        return 1;
111
115
}
112
116
 
113
117
/* Attempt to declare a symbol within the current declaration.  If
120
124
 * of memory, return -3.  Note that dest_value and datum_value might
121
125
 * not be restricted pointers. */
122
126
int declare_symbol(uint32_t symbol_type,
123
 
                   hashtab_key_t key, hashtab_datum_t datum,
124
 
                   uint32_t *dest_value, uint32_t *datum_value) {
125
 
        avrule_decl_t *decl = stack_top->decl;
126
 
        int retval;
 
127
                   hashtab_key_t key, hashtab_datum_t datum,
 
128
                   uint32_t * dest_value, uint32_t * datum_value)
 
129
{
 
130
        avrule_decl_t *decl = stack_top->decl;
 
131
        int retval;
127
132
 
128
 
        /* first check that symbols may be declared here */
129
 
        if (!is_declaration_allowed()) {
130
 
                return -1;
131
 
        }
132
 
        retval = symtab_insert(policydbp, symbol_type, key, datum,
133
 
                               SCOPE_DECL, decl->decl_id,
134
 
                               dest_value);
135
 
        if (retval == 1) {
136
 
                /* because C has no polymorphism, make the
137
 
                 * [outrageous] assumption that the first field of all
138
 
                 * symbol table data is a uint32_t representing its
139
 
                 * value */
140
 
                uint32_t *v = (uint32_t *) hashtab_search(policydbp->symtab[symbol_type].table, key);
141
 
                assert(v != NULL);
142
 
                *dest_value = *v;
143
 
        }
144
 
        else if (retval == -2) {
145
 
                return -2;
146
 
        }
147
 
        else if (retval < 0) {
148
 
                return -3;
149
 
        }
150
 
        else {  /* fall through possible if retval is 0 */
151
 
        }
152
 
        if (datum_value != NULL) {
153
 
                if (ebitmap_set_bit(decl->declared.scope + symbol_type,
154
 
                                    *datum_value - 1,
155
 
                                    1)) {
156
 
                        return -3;
157
 
                }
158
 
        }
159
 
        return retval;
 
133
        /* first check that symbols may be declared here */
 
134
        if (!is_declaration_allowed()) {
 
135
                return -1;
 
136
        }
 
137
        retval = symtab_insert(policydbp, symbol_type, key, datum,
 
138
                               SCOPE_DECL, decl->decl_id, dest_value);
 
139
        if (retval == 1) {
 
140
                symtab_datum_t *s =
 
141
                    (symtab_datum_t *) hashtab_search(policydbp->
 
142
                                                      symtab[symbol_type].table,
 
143
                                                      key);
 
144
                assert(s != NULL);
 
145
                *dest_value = s->value;
 
146
        } else if (retval == -2) {
 
147
                return -2;
 
148
        } else if (retval < 0) {
 
149
                return -3;
 
150
        } else {                /* fall through possible if retval is 0 */
 
151
        }
 
152
        if (datum_value != NULL) {
 
153
                if (ebitmap_set_bit(decl->declared.scope + symbol_type,
 
154
                                    *datum_value - 1, 1)) {
 
155
                        return -3;
 
156
                }
 
157
        }
 
158
        return retval;
160
159
}
161
160
 
162
161
role_datum_t *declare_role(void)
163
162
{
164
 
        char *id = queue_remove(id_queue), *dest_id = NULL;
 
163
        char *id = queue_remove(id_queue), *dest_id = NULL;
165
164
        role_datum_t *role = NULL, *dest_role = NULL;
166
 
        int retval;
167
 
        uint32_t value;
168
 
 
169
 
        if (id == NULL) {
170
 
                yyerror("no role name");
171
 
                return NULL;
172
 
        }
173
 
        if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) {
174
 
                yyerror("Out of memory!");
175
 
                free(id);
176
 
                return NULL;
177
 
        }
178
 
        role_datum_init(role);
179
 
 
180
 
        retval = declare_symbol(SYM_ROLES, id, (hashtab_datum_t*)role, &value, &value);
181
 
        if (retval == 0) {
182
 
                role->value = value;
183
 
                if ((dest_id = strdup(id)) == NULL) {
184
 
                        yyerror("Out of memory!");
185
 
                        return NULL;
186
 
                }
187
 
        }
188
 
        else {
189
 
                /* this role was already declared in this module, or error */
190
 
                dest_id = id;
191
 
                role_datum_destroy(role);
192
 
                free(role);
193
 
        }
194
 
        if (retval == 0 || retval == 1) {
195
 
                /* create a new role_datum_t for this decl, if necessary */
196
 
                hashtab_t roles_tab;
197
 
                assert(stack_top->type == 1);
198
 
                if (stack_top->parent == NULL) {
199
 
                        /* in parent, so use global symbol table */
200
 
                        roles_tab = policydbp->p_roles.table;
201
 
                }
202
 
                else {
203
 
                        roles_tab = stack_top->decl->p_roles.table;
204
 
                }
205
 
                dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id);
206
 
                if (dest_role == NULL) {
207
 
                        if ((dest_role = (role_datum_t *) malloc(sizeof(*dest_role))) == NULL) {
208
 
                                yyerror("Out of memory!");
209
 
                                free(dest_id);
210
 
                                return NULL;
211
 
                        }
212
 
                        role_datum_init(dest_role);
213
 
                        dest_role->value = value;
214
 
                        if (hashtab_insert(roles_tab, dest_id, dest_role)) {
215
 
                                yyerror("Out of memory!");
216
 
                                free(dest_id);
217
 
                                role_datum_destroy(dest_role);
218
 
                                free(dest_role);
219
 
                                return NULL;
220
 
                        }
221
 
                }
222
 
                else {
223
 
                        free(dest_id);
224
 
                }
225
 
        }
226
 
        else {
227
 
                free(dest_id);
228
 
        }
229
 
        switch(retval) {
230
 
        case -3: {
231
 
                yyerror("Out of memory!");
232
 
                return NULL;
233
 
        }
234
 
        case -2: {
235
 
                yyerror("duplicate declaration of role");
236
 
                return NULL;
237
 
        }
238
 
        case -1: {
239
 
                yyerror("could not declare role here");
240
 
                return NULL;
241
 
        }
242
 
        case 0: {
243
 
                if (ebitmap_set_bit(&role->dominates, role->value - 1, 1)) {
244
 
                        yyerror("out of memory");
245
 
                        return NULL;
246
 
                }
247
 
                return dest_role;
248
 
        }
249
 
        case 1: {
250
 
                return dest_role; /* role already declared for this block */
251
 
        }
252
 
        default: {
253
 
                assert(0);  /* should never get here */
254
 
        }
255
 
        }
 
165
        int retval;
 
166
        uint32_t value;
 
167
 
 
168
        if (id == NULL) {
 
169
                yyerror("no role name");
 
170
                return NULL;
 
171
        }
 
172
        if ((role = (role_datum_t *) malloc(sizeof(*role))) == NULL) {
 
173
                yyerror("Out of memory!");
 
174
                free(id);
 
175
                return NULL;
 
176
        }
 
177
        role_datum_init(role);
 
178
 
 
179
        retval =
 
180
            declare_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &value,
 
181
                           &value);
 
182
        if (retval == 0) {
 
183
                role->s.value = value;
 
184
                if ((dest_id = strdup(id)) == NULL) {
 
185
                        yyerror("Out of memory!");
 
186
                        return NULL;
 
187
                }
 
188
        } else {
 
189
                /* this role was already declared in this module, or error */
 
190
                dest_id = id;
 
191
                role_datum_destroy(role);
 
192
                free(role);
 
193
        }
 
194
        if (retval == 0 || retval == 1) {
 
195
                /* create a new role_datum_t for this decl, if necessary */
 
196
                hashtab_t roles_tab;
 
197
                assert(stack_top->type == 1);
 
198
                if (stack_top->parent == NULL) {
 
199
                        /* in parent, so use global symbol table */
 
200
                        roles_tab = policydbp->p_roles.table;
 
201
                } else {
 
202
                        roles_tab = stack_top->decl->p_roles.table;
 
203
                }
 
204
                dest_role = (role_datum_t *) hashtab_search(roles_tab, dest_id);
 
205
                if (dest_role == NULL) {
 
206
                        if ((dest_role =
 
207
                             (role_datum_t *) malloc(sizeof(*dest_role))) ==
 
208
                            NULL) {
 
209
                                yyerror("Out of memory!");
 
210
                                free(dest_id);
 
211
                                return NULL;
 
212
                        }
 
213
                        role_datum_init(dest_role);
 
214
                        dest_role->s.value = value;
 
215
                        if (hashtab_insert(roles_tab, dest_id, dest_role)) {
 
216
                                yyerror("Out of memory!");
 
217
                                free(dest_id);
 
218
                                role_datum_destroy(dest_role);
 
219
                                free(dest_role);
 
220
                                return NULL;
 
221
                        }
 
222
                } else {
 
223
                        free(dest_id);
 
224
                }
 
225
        } else {
 
226
                free(dest_id);
 
227
        }
 
228
        switch (retval) {
 
229
        case -3:{
 
230
                        yyerror("Out of memory!");
 
231
                        return NULL;
 
232
                }
 
233
        case -2:{
 
234
                        yyerror("duplicate declaration of role");
 
235
                        return NULL;
 
236
                }
 
237
        case -1:{
 
238
                        yyerror("could not declare role here");
 
239
                        return NULL;
 
240
                }
 
241
        case 0:{
 
242
                        if (ebitmap_set_bit
 
243
                            (&dest_role->dominates, role->s.value - 1, 1)) {
 
244
                                yyerror("out of memory");
 
245
                                return NULL;
 
246
                        }
 
247
                        return dest_role;
 
248
                }
 
249
        case 1:{
 
250
                        return dest_role;       /* role already declared for this block */
 
251
                }
 
252
        default:{
 
253
                        assert(0);      /* should never get here */
 
254
                }
 
255
        }
256
256
}
257
257
 
258
 
type_datum_t *declare_type(unsigned char primary, unsigned char isattr) {
259
 
        char *id, *dest_id = NULL;
260
 
        type_datum_t *typdatum, *dest_typdatum = NULL;
 
258
type_datum_t *declare_type(unsigned char primary, unsigned char isattr)
 
259
{
 
260
        char *id;
 
261
        type_datum_t *typdatum;
261
262
        int retval;
262
263
        uint32_t value = 0;
263
264
 
264
 
        id = (char *) queue_remove(id_queue);
 
265
        id = (char *)queue_remove(id_queue);
265
266
        if (!id) {
266
 
                yyerror("no type/attribute name?");
267
 
                return NULL;
268
 
        }
269
 
        if (strcmp(id, "self") == 0) {
270
 
                yyerror("'self' is a reserved type name and may not be declared.");
271
 
                free(id);
272
 
                return NULL;
273
 
        }
 
267
                yyerror("no type/attribute name?");
 
268
                return NULL;
 
269
        }
 
270
        if (strcmp(id, "self") == 0) {
 
271
                yyerror
 
272
                    ("'self' is a reserved type name and may not be declared.");
 
273
                free(id);
 
274
                return NULL;
 
275
        }
274
276
 
275
277
        typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
276
278
        if (!typdatum) {
277
279
                yyerror("Out of memory!");
278
 
                free(id);
 
280
                free(id);
279
281
                return NULL;
280
282
        }
281
 
        type_datum_init(typdatum);
282
 
        typdatum->primary = primary;
283
 
        typdatum->isattr = isattr;
284
 
        
285
 
        retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value);
286
 
        if (retval == 0 || retval == 1) {
287
 
                if (typdatum->primary) {
288
 
                        typdatum->value = value;
289
 
                }
290
 
                if ((dest_id = strdup(id)) == NULL) {
291
 
                        yyerror("Out of memory!");
292
 
                        return NULL;
293
 
                }
294
 
                if ((dest_typdatum = get_local_type(dest_id, value)) == NULL) {
295
 
                        yyerror("Out of memory!");
296
 
                        return NULL;
297
 
                }       
298
 
        }
299
 
        else {
300
 
                /* error occurred (can't have duplicate type declarations) */
 
283
        type_datum_init(typdatum);
 
284
        typdatum->primary = primary;
 
285
        typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
 
286
 
 
287
        retval = declare_symbol(SYM_TYPES, id, typdatum, &value, &value);
 
288
        if (retval == 0 || retval == 1) {
 
289
                if (typdatum->primary) {
 
290
                        typdatum->s.value = value;
 
291
                }
 
292
        } else {
 
293
                /* error occurred (can't have duplicate type declarations) */
301
294
                free(id);
302
 
                type_datum_destroy(typdatum);
303
 
                free(typdatum);
304
 
        }
305
 
        switch(retval) {
306
 
        case -3: {
307
 
                yyerror("Out of memory!");
308
 
                return NULL;
309
 
        }
310
 
        case -2: {
311
 
                yyerror2("duplicate declaration of type/attribute");
312
 
                return NULL;
313
 
        }
314
 
        case -1: {
315
 
                yyerror("could not declare type/attribute here");
316
 
                return NULL;
317
 
        }
318
 
        case 0:
319
 
        case 1: {
320
 
                return dest_typdatum;
321
 
        }
322
 
        default: {
323
 
                assert(0);  /* should never get here */
324
 
        }
325
 
        }
 
295
                type_datum_destroy(typdatum);
 
296
                free(typdatum);
 
297
        }
 
298
        switch (retval) {
 
299
        case -3:{
 
300
                        yyerror("Out of memory!");
 
301
                        return NULL;
 
302
                }
 
303
        case -2:{
 
304
                        yyerror2("duplicate declaration of type/attribute");
 
305
                        return NULL;
 
306
                }
 
307
        case -1:{
 
308
                        yyerror("could not declare type/attribute here");
 
309
                        return NULL;
 
310
                }
 
311
        case 0:
 
312
        case 1:{
 
313
                        return typdatum;
 
314
                }
 
315
        default:{
 
316
                        assert(0);      /* should never get here */
 
317
                }
 
318
        }
326
319
}
327
320
 
328
 
user_datum_t *declare_user(void) {
329
 
        char *id = queue_remove(id_queue), *dest_id = NULL;
330
 
        user_datum_t *user = NULL, *dest_user = NULL;
331
 
        int retval;
332
 
        uint32_t value = 0;
333
 
        
334
 
        if (id == NULL) {
335
 
                yyerror("no user name");
336
 
                return NULL;
337
 
        }
338
 
        if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
339
 
                yyerror("Out of memory!");
340
 
                free(id);
341
 
                return NULL;
342
 
        }
343
 
        user_datum_init(user);
344
 
        
345
 
        retval = declare_symbol(SYM_USERS, id, (hashtab_datum_t*)user, &value, &value);
346
 
 
347
 
        if (retval == 0) {
348
 
                user->value = value;
349
 
                if ((dest_id = strdup(id)) == NULL) {
350
 
                        yyerror("Out of memory!");
351
 
                        return NULL;
352
 
                }
353
 
        }
354
 
        else {
355
 
                /* this user was already declared in this module, or error */
356
 
                dest_id = id;
357
 
                user_datum_destroy(user);
358
 
                free(user);
359
 
        }
360
 
         if (retval == 0 || retval == 1) {
361
 
                /* create a new user_datum_t for this decl, if necessary */
362
 
                hashtab_t users_tab;
363
 
                assert(stack_top->type == 1);
364
 
                if (stack_top->parent == NULL) {
365
 
                        /* in parent, so use global symbol table */
366
 
                        users_tab = policydbp->p_users.table;
367
 
                }
368
 
                else {
369
 
                        users_tab = stack_top->decl->p_users.table;
370
 
                }
371
 
                dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
372
 
                if (dest_user == NULL) {
373
 
                        if ((dest_user = (user_datum_t *) malloc(sizeof(*dest_user))) == NULL) {
374
 
                                yyerror("Out of memory!");
375
 
                                free(dest_id);
376
 
                                return NULL;
377
 
                        }
378
 
                        user_datum_init(dest_user);
379
 
                        dest_user->value = value;
380
 
                        if (hashtab_insert(users_tab, dest_id, dest_user)) {
381
 
                                yyerror("Out of memory!");
382
 
                                free(dest_id);
383
 
                                user_datum_destroy(dest_user);
384
 
                                free(dest_user);
385
 
                                return NULL;
386
 
                        }
387
 
                }
388
 
                else {
389
 
                        free(dest_id);
390
 
                }
391
 
        }
392
 
        else {
393
 
                free(dest_id);
394
 
        }
395
 
        switch(retval) {
396
 
        case -3: {
397
 
                yyerror("Out of memory!");
398
 
                return NULL;
399
 
        }
400
 
        case -2: {
401
 
                yyerror("duplicate declaration of user");
402
 
                return NULL;
403
 
        }
404
 
        case -1: {
405
 
                yyerror("could not declare user here");
406
 
                return NULL;
407
 
        }
408
 
        case 0: {
409
 
                return dest_user;
410
 
        }
411
 
        case 1: {
412
 
                return dest_user; /* user already declared for this block */
413
 
        }
414
 
        default: {
415
 
                assert(0);  /* should never get here */
416
 
        }
417
 
        }
 
321
user_datum_t *declare_user(void)
 
322
{
 
323
        char *id = queue_remove(id_queue), *dest_id = NULL;
 
324
        user_datum_t *user = NULL, *dest_user = NULL;
 
325
        int retval;
 
326
        uint32_t value = 0;
 
327
 
 
328
        if (id == NULL) {
 
329
                yyerror("no user name");
 
330
                return NULL;
 
331
        }
 
332
        if ((user = (user_datum_t *) malloc(sizeof(*user))) == NULL) {
 
333
                yyerror("Out of memory!");
 
334
                free(id);
 
335
                return NULL;
 
336
        }
 
337
        user_datum_init(user);
 
338
 
 
339
        retval =
 
340
            declare_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &value,
 
341
                           &value);
 
342
 
 
343
        if (retval == 0) {
 
344
                user->s.value = value;
 
345
                if ((dest_id = strdup(id)) == NULL) {
 
346
                        yyerror("Out of memory!");
 
347
                        return NULL;
 
348
                }
 
349
        } else {
 
350
                /* this user was already declared in this module, or error */
 
351
                dest_id = id;
 
352
                user_datum_destroy(user);
 
353
                free(user);
 
354
        }
 
355
        if (retval == 0 || retval == 1) {
 
356
                /* create a new user_datum_t for this decl, if necessary */
 
357
                hashtab_t users_tab;
 
358
                assert(stack_top->type == 1);
 
359
                if (stack_top->parent == NULL) {
 
360
                        /* in parent, so use global symbol table */
 
361
                        users_tab = policydbp->p_users.table;
 
362
                } else {
 
363
                        users_tab = stack_top->decl->p_users.table;
 
364
                }
 
365
                dest_user = (user_datum_t *) hashtab_search(users_tab, dest_id);
 
366
                if (dest_user == NULL) {
 
367
                        if ((dest_user =
 
368
                             (user_datum_t *) malloc(sizeof(*dest_user))) ==
 
369
                            NULL) {
 
370
                                yyerror("Out of memory!");
 
371
                                free(dest_id);
 
372
                                return NULL;
 
373
                        }
 
374
                        user_datum_init(dest_user);
 
375
                        dest_user->s.value = value;
 
376
                        if (hashtab_insert(users_tab, dest_id, dest_user)) {
 
377
                                yyerror("Out of memory!");
 
378
                                free(dest_id);
 
379
                                user_datum_destroy(dest_user);
 
380
                                free(dest_user);
 
381
                                return NULL;
 
382
                        }
 
383
                } else {
 
384
                        free(dest_id);
 
385
                }
 
386
        } else {
 
387
                free(dest_id);
 
388
        }
 
389
        switch (retval) {
 
390
        case -3:{
 
391
                        yyerror("Out of memory!");
 
392
                        return NULL;
 
393
                }
 
394
        case -2:{
 
395
                        yyerror("duplicate declaration of user");
 
396
                        return NULL;
 
397
                }
 
398
        case -1:{
 
399
                        yyerror("could not declare user here");
 
400
                        return NULL;
 
401
                }
 
402
        case 0:{
 
403
                        return dest_user;
 
404
                }
 
405
        case 1:{
 
406
                        return dest_user;       /* user already declared for this block */
 
407
                }
 
408
        default:{
 
409
                        assert(0);      /* should never get here */
 
410
                }
 
411
        }
418
412
}
419
413
 
420
414
/* Return a type_datum_t for the local avrule_decl with the given ID.
425
419
 * NOTE: this function usurps ownership of id afterwards.  The caller
426
420
 * shall not reference it nor free() it afterwards.
427
421
 */
428
 
type_datum_t *get_local_type(char *id, uint32_t value) {
429
 
        type_datum_t *dest_typdatum;
430
 
        hashtab_t types_tab;
431
 
        assert(stack_top->type == 1);
432
 
        if (stack_top->parent == NULL) {
433
 
                /* in parent, so use global symbol table */
434
 
                types_tab = policydbp->p_types.table;
435
 
        }
436
 
        else {
437
 
                types_tab = stack_top->decl->p_types.table;
438
 
        }
439
 
        if ((dest_typdatum = hashtab_search(types_tab, id)) == NULL) {
440
 
                dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
441
 
                if (dest_typdatum == NULL) {
442
 
                        free(id);
443
 
                        return NULL;
444
 
                }
445
 
                type_datum_init(dest_typdatum);
446
 
                dest_typdatum->value = value;
447
 
                if (hashtab_insert(types_tab, id, dest_typdatum)) {
448
 
                        free(id);
449
 
                        type_datum_destroy(dest_typdatum);
450
 
                        free(dest_typdatum);
451
 
                        return NULL;
452
 
                }
453
 
  
454
 
        } else {
 
422
type_datum_t *get_local_type(char *id, uint32_t value, unsigned char isattr)
 
423
{
 
424
        type_datum_t *dest_typdatum;
 
425
        hashtab_t types_tab;
 
426
        assert(stack_top->type == 1);
 
427
        if (stack_top->parent == NULL) {
 
428
                /* in global, so use global symbol table */
 
429
                types_tab = policydbp->p_types.table;
 
430
        } else {
 
431
                types_tab = stack_top->decl->p_types.table;
 
432
        }
 
433
        dest_typdatum = hashtab_search(types_tab, id);
 
434
        if (!dest_typdatum) {
 
435
                dest_typdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
 
436
                if (dest_typdatum == NULL) {
 
437
                        free(id);
 
438
                        return NULL;
 
439
                }
 
440
                type_datum_init(dest_typdatum);
 
441
                dest_typdatum->s.value = value;
 
442
                dest_typdatum->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
 
443
                dest_typdatum->primary = 1;
 
444
                if (hashtab_insert(types_tab, id, dest_typdatum)) {
 
445
                        free(id);
 
446
                        type_datum_destroy(dest_typdatum);
 
447
                        free(dest_typdatum);
 
448
                        return NULL;
 
449
                }
 
450
 
 
451
        } else {
455
452
                free(id);
 
453
                if (dest_typdatum->flavor != isattr ? TYPE_ATTRIB : TYPE_TYPE) {
 
454
                        return NULL;
 
455
                }
456
456
        }
457
 
        return dest_typdatum;
 
457
        return dest_typdatum;
458
458
}
459
459
 
460
460
/* Given the current parse stack, returns 1 if a requirement would be
461
461
 * allowed here or 0 if not.  For example, the ELSE branch may never
462
462
 * have its own requirements.
463
463
 */
464
 
static int is_require_allowed(void) {
465
 
        if (stack_top->type == 1 && !stack_top->in_else) {
466
 
                return 1;
467
 
        }
468
 
        return 0;
 
464
static int is_require_allowed(void)
 
465
{
 
466
        if (stack_top->type == 1 && !stack_top->in_else) {
 
467
                return 1;
 
468
        }
 
469
        return 0;
469
470
}
470
471
 
471
472
/* Attempt to require a symbol within the current scope.  If currently
477
478
 * restricted pointers.
478
479
 */
479
480
int require_symbol(uint32_t symbol_type,
480
 
                   hashtab_key_t key, hashtab_datum_t datum,
481
 
                   uint32_t *dest_value, uint32_t *datum_value) {
482
 
        avrule_decl_t *decl = stack_top->decl;
483
 
        int retval;
484
 
 
485
 
        /* first check that symbols may be required here */
486
 
        if (!is_require_allowed()) {
487
 
                return -1;
488
 
        }
489
 
        retval = symtab_insert(policydbp, symbol_type, key, datum,
490
 
                               SCOPE_REQ, decl->decl_id,
491
 
                               dest_value);
492
 
        if (retval == 1) {
493
 
                /* because C has no polymorphism, make the
494
 
                 * [outrageous] assumption that the first field of all
495
 
                 * symbol table data is a uint32_t representing its
496
 
                 * value */
497
 
                uint32_t *v = (uint32_t *) hashtab_search(policydbp->symtab[symbol_type].table, key);
498
 
                assert(v != NULL);
499
 
                *dest_value = *v;
500
 
        }
501
 
        else if (retval == -2) {
502
 
                /* ignore require statements if that symbol was
503
 
                 * previously declared and is in current scope */
504
 
                int prev_declaration_ok = 0;
505
 
                if (is_id_in_scope(symbol_type, key)) {
506
 
                        if (symbol_type == SYM_TYPES) {
507
 
                                /* check that previous symbol has same
508
 
                                 * type/attribute-ness */
509
 
                                unsigned char new_isattr = ((type_datum_t *) datum)->isattr;
510
 
                                type_datum_t *old_datum = (type_datum_t *) hashtab_search(policydbp->symtab[SYM_TYPES].table, key);
511
 
                                assert(old_datum != NULL);
512
 
                                unsigned char old_isattr = old_datum->isattr;
513
 
                                prev_declaration_ok = (old_isattr == new_isattr ? 1 : 0);
514
 
                        }
515
 
                        else {
516
 
                                prev_declaration_ok = 1;
517
 
                        }
518
 
                }
519
 
                if (prev_declaration_ok) {
520
 
                        /* ignore this require statement because it
521
 
                         * was already declared within my scope */
522
 
                        stack_top->require_given = 1;
523
 
                        return 1;
524
 
                }
525
 
                else {
526
 
                        /* previous declaration was not in scope or
527
 
                         * had a mismatched type/attribute, so
528
 
                         * generate an error */
529
 
                        return -2;
530
 
                }
531
 
        }
532
 
        else if (retval < 0) {
533
 
                return -3;
534
 
        }
535
 
        else {  /* fall through possible if retval is 0 or 1 */
536
 
        }
537
 
        if (datum_value != NULL) {
538
 
                if (ebitmap_set_bit(decl->required.scope + symbol_type,
539
 
                                    *datum_value - 1,
540
 
                                    1)) {
541
 
                        return -3;
542
 
                }
543
 
        }
544
 
        stack_top->require_given = 1;
545
 
        return retval;
546
 
}
547
 
 
548
 
int add_perm_to_class(uint32_t perm_value, uint32_t class_value) {
549
 
        avrule_decl_t *decl = stack_top->decl;
550
 
        scope_index_t *scope;
551
 
 
552
 
        assert(perm_value >= 1);
553
 
        assert(class_value >= 1);        
554
 
        scope = &decl->required;
555
 
        if (class_value > scope->class_perms_len) {
556
 
                int i;
557
 
                ebitmap_t *new_map = realloc(scope->class_perms_map,
558
 
                                             class_value * sizeof(*new_map));
559
 
                if (new_map == NULL) {
560
 
                        return -1;
561
 
                }
562
 
                scope->class_perms_map = new_map;
563
 
                for (i = scope->class_perms_len; i < class_value; i++) {
564
 
                        ebitmap_init(scope->class_perms_map + i);
565
 
                }
566
 
                scope->class_perms_len = class_value;
567
 
        }
568
 
        if (ebitmap_set_bit(scope->class_perms_map + class_value - 1,
569
 
                            perm_value - 1, 1)) {
570
 
                return -1;
571
 
        }
572
 
        return 0;
573
 
}
574
 
 
575
 
static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p __attribute__ ((unused)))
 
481
                   hashtab_key_t key, hashtab_datum_t datum,
 
482
                   uint32_t * dest_value, uint32_t * datum_value)
 
483
{
 
484
        avrule_decl_t *decl = stack_top->decl;
 
485
        int retval;
 
486
 
 
487
        /* first check that symbols may be required here */
 
488
        if (!is_require_allowed()) {
 
489
                return -1;
 
490
        }
 
491
        retval = symtab_insert(policydbp, symbol_type, key, datum,
 
492
                               SCOPE_REQ, decl->decl_id, dest_value);
 
493
        if (retval == 1) {
 
494
                symtab_datum_t *s =
 
495
                    (symtab_datum_t *) hashtab_search(policydbp->
 
496
                                                      symtab[symbol_type].table,
 
497
                                                      key);
 
498
                assert(s != NULL);
 
499
                *dest_value = s->value;
 
500
        } else if (retval == -2) {
 
501
                /* ignore require statements if that symbol was
 
502
                 * previously declared and is in current scope */
 
503
                int prev_declaration_ok = 0;
 
504
                if (is_id_in_scope(symbol_type, key)) {
 
505
                        if (symbol_type == SYM_TYPES) {
 
506
                                /* check that previous symbol has same
 
507
                                 * type/attribute-ness */
 
508
                                unsigned char new_isattr =
 
509
                                    ((type_datum_t *) datum)->flavor;
 
510
                                type_datum_t *old_datum =
 
511
                                    (type_datum_t *) hashtab_search(policydbp->
 
512
                                                                    symtab
 
513
                                                                    [SYM_TYPES].
 
514
                                                                    table, key);
 
515
                                assert(old_datum != NULL);
 
516
                                unsigned char old_isattr = old_datum->flavor;
 
517
                                prev_declaration_ok =
 
518
                                    (old_isattr == new_isattr ? 1 : 0);
 
519
                        } else {
 
520
                                prev_declaration_ok = 1;
 
521
                        }
 
522
                }
 
523
                if (prev_declaration_ok) {
 
524
                        /* ignore this require statement because it
 
525
                         * was already declared within my scope */
 
526
                        stack_top->require_given = 1;
 
527
                        return 1;
 
528
                } else {
 
529
                        /* previous declaration was not in scope or
 
530
                         * had a mismatched type/attribute, so
 
531
                         * generate an error */
 
532
                        return -2;
 
533
                }
 
534
        } else if (retval < 0) {
 
535
                return -3;
 
536
        } else {                /* fall through possible if retval is 0 or 1 */
 
537
        }
 
538
        if (datum_value != NULL) {
 
539
                if (ebitmap_set_bit(decl->required.scope + symbol_type,
 
540
                                    *datum_value - 1, 1)) {
 
541
                        return -3;
 
542
                }
 
543
        }
 
544
        stack_top->require_given = 1;
 
545
        return retval;
 
546
}
 
547
 
 
548
int add_perm_to_class(uint32_t perm_value, uint32_t class_value)
 
549
{
 
550
        avrule_decl_t *decl = stack_top->decl;
 
551
        scope_index_t *scope;
 
552
 
 
553
        assert(perm_value >= 1);
 
554
        assert(class_value >= 1);
 
555
        scope = &decl->required;
 
556
        if (class_value > scope->class_perms_len) {
 
557
                int i;
 
558
                ebitmap_t *new_map = realloc(scope->class_perms_map,
 
559
                                             class_value * sizeof(*new_map));
 
560
                if (new_map == NULL) {
 
561
                        return -1;
 
562
                }
 
563
                scope->class_perms_map = new_map;
 
564
                for (i = scope->class_perms_len; i < class_value; i++) {
 
565
                        ebitmap_init(scope->class_perms_map + i);
 
566
                }
 
567
                scope->class_perms_len = class_value;
 
568
        }
 
569
        if (ebitmap_set_bit(scope->class_perms_map + class_value - 1,
 
570
                            perm_value - 1, 1)) {
 
571
                return -1;
 
572
        }
 
573
        return 0;
 
574
}
 
575
 
 
576
static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
 
577
                        __attribute__ ((unused)))
576
578
{
577
579
        if (key)
578
580
                free(key);
580
582
        return 0;
581
583
}
582
584
 
583
 
static void class_datum_destroy(class_datum_t *cladatum) {
584
 
        if (cladatum != NULL) {
585
 
                hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
586
 
                hashtab_destroy(cladatum->permissions.table);
587
 
                free(cladatum);
588
 
        }
 
585
static void class_datum_destroy(class_datum_t * cladatum)
 
586
{
 
587
        if (cladatum != NULL) {
 
588
                hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
 
589
                hashtab_destroy(cladatum->permissions.table);
 
590
                free(cladatum);
 
591
        }
589
592
}
590
593
 
591
594
int require_class(int pass)
592
595
{
593
 
        char *class_id = queue_remove(id_queue);
594
 
        char *perm_id = NULL;
595
 
        class_datum_t *datum = NULL;
596
 
        perm_datum_t *perm = NULL;
597
 
        int ret, ret2;
598
 
 
599
 
        if (pass == 2) {
600
 
                free(class_id);
601
 
                while ((perm_id = queue_remove(id_queue)) != NULL)
602
 
                        free(perm_id);
603
 
                return 0;
604
 
        }
605
 
 
606
 
        /* first add the class if it is not already there */
607
 
        if (class_id == NULL) {
608
 
                yyerror("no class name for class definition?");
609
 
                return -1;
610
 
        }
611
 
 
612
 
        if ((datum = calloc(1, sizeof(*datum))) == NULL ||
613
 
            symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) {
614
 
                yyerror("Out of memory!");
615
 
                goto cleanup;
616
 
        }
617
 
        ret = require_symbol(SYM_CLASSES, class_id, datum, &datum->value, &datum->value);
618
 
        switch (ret) {
619
 
        case -3: {
620
 
                yyerror("Out of memory!");
621
 
                free(class_id);
622
 
                class_datum_destroy(datum);
623
 
                goto cleanup;
624
 
        }
625
 
        case -2: {
626
 
                yyerror("duplicate declaration of class");
627
 
                free(class_id);
628
 
                class_datum_destroy(datum);
629
 
                goto cleanup;
630
 
        }
631
 
        case -1: {
632
 
                yyerror("could not require class here");
633
 
                free(class_id);
634
 
                class_datum_destroy(datum);
635
 
                goto cleanup;
636
 
        }
637
 
        case 0: {
638
 
                /* a new class was added; reindex everything */
639
 
                if (policydb_index_classes(policydbp)) {
640
 
                        yyerror("Out of memory!");
641
 
                        goto cleanup;
642
 
                }
643
 
                break;
644
 
        }
645
 
        case 1: {
646
 
                class_datum_destroy(datum);
647
 
                datum = hashtab_search(policydbp->p_classes.table, class_id);
648
 
                assert(datum);     /* the class datum should have existed */
649
 
                free(class_id);
650
 
                break;
651
 
        }
652
 
        default: {
653
 
                assert(0);  /* should never get here */
654
 
        }
655
 
        }
656
 
 
657
 
        /* now add each of the permissions to this class's requirements */
658
 
        while ((perm_id = queue_remove(id_queue)) != NULL) {
 
596
        char *class_id = queue_remove(id_queue);
 
597
        char *perm_id = NULL;
 
598
        class_datum_t *datum = NULL;
 
599
        perm_datum_t *perm = NULL;
 
600
        int ret;
 
601
 
 
602
        if (pass == 2) {
 
603
                free(class_id);
 
604
                while ((perm_id = queue_remove(id_queue)) != NULL)
 
605
                        free(perm_id);
 
606
                return 0;
 
607
        }
 
608
 
 
609
        /* first add the class if it is not already there */
 
610
        if (class_id == NULL) {
 
611
                yyerror("no class name for class definition?");
 
612
                return -1;
 
613
        }
 
614
 
 
615
        if ((datum = calloc(1, sizeof(*datum))) == NULL ||
 
616
            symtab_init(&datum->permissions, PERM_SYMTAB_SIZE)) {
 
617
                yyerror("Out of memory!");
 
618
                goto cleanup;
 
619
        }
 
620
        ret =
 
621
            require_symbol(SYM_CLASSES, class_id, datum, &datum->s.value,
 
622
                           &datum->s.value);
 
623
        switch (ret) {
 
624
        case -3:{
 
625
                        yyerror("Out of memory!");
 
626
                        free(class_id);
 
627
                        class_datum_destroy(datum);
 
628
                        goto cleanup;
 
629
                }
 
630
        case -2:{
 
631
                        yyerror("duplicate declaration of class");
 
632
                        free(class_id);
 
633
                        class_datum_destroy(datum);
 
634
                        goto cleanup;
 
635
                }
 
636
        case -1:{
 
637
                        yyerror("could not require class here");
 
638
                        free(class_id);
 
639
                        class_datum_destroy(datum);
 
640
                        goto cleanup;
 
641
                }
 
642
        case 0:{
 
643
                        /* a new class was added; reindex everything */
 
644
                        if (policydb_index_classes(policydbp)) {
 
645
                                yyerror("Out of memory!");
 
646
                                goto cleanup;
 
647
                        }
 
648
                        break;
 
649
                }
 
650
        case 1:{
 
651
                        class_datum_destroy(datum);
 
652
                        datum =
 
653
                            hashtab_search(policydbp->p_classes.table,
 
654
                                           class_id);
 
655
                        assert(datum);  /* the class datum should have existed */
 
656
                        free(class_id);
 
657
                        break;
 
658
                }
 
659
        default:{
 
660
                        assert(0);      /* should never get here */
 
661
                }
 
662
        }
 
663
 
 
664
        /* now add each of the permissions to this class's requirements */
 
665
        while ((perm_id = queue_remove(id_queue)) != NULL) {
659
666
                int allocated = 0;
660
667
 
661
668
                /* Is the permission already in the table? */
662
669
                perm = hashtab_search(datum->permissions.table, perm_id);
663
670
                if (!perm && datum->comdatum)
664
 
                        perm = hashtab_search(datum->comdatum->permissions.table, perm_id);
 
671
                        perm =
 
672
                            hashtab_search(datum->comdatum->permissions.table,
 
673
                                           perm_id);
665
674
                if (perm) {
666
675
                        /* Yes, drop the name. */
667
676
                        free(perm_id);
668
677
                } else {
669
678
                        /* No - allocate and insert an entry for it. */
 
679
                        if (policydbp->policy_type == POLICY_BASE) {
 
680
                                yyerror2
 
681
                                    ("Base policy - require of permission %s without prior declaration.",
 
682
                                     perm_id);
 
683
                                free(perm_id);
 
684
                                goto cleanup;
 
685
                        }
670
686
                        allocated = 1;
671
687
                        if ((perm = malloc(sizeof(*perm))) == NULL) {
672
688
                                yyerror("Out of memory!");
674
690
                                goto cleanup;
675
691
                        }
676
692
                        memset(perm, 0, sizeof(*perm));
677
 
                        ret = hashtab_insert(datum->permissions.table, perm_id, perm);
 
693
                        ret =
 
694
                            hashtab_insert(datum->permissions.table, perm_id,
 
695
                                           perm);
678
696
                        if (ret) {
679
697
                                yyerror("Out of memory!");
680
698
                                free(perm_id);
681
699
                                free(perm);
682
700
                                goto cleanup;
683
701
                        }
684
 
                        perm->value = datum->permissions.nprim + 1;
685
 
                }
686
 
                
687
 
                if (add_perm_to_class(perm->value, datum->value) == -1) {
688
 
                        yyerror("Out of memory!");
689
 
                        goto cleanup;
690
 
                }
 
702
                        perm->s.value = datum->permissions.nprim + 1;
 
703
                }
 
704
 
 
705
                if (add_perm_to_class(perm->s.value, datum->s.value) == -1) {
 
706
                        yyerror("Out of memory!");
 
707
                        goto cleanup;
 
708
                }
691
709
 
692
710
                /* Update number of primitives if we allocated one. */
693
711
                if (allocated)
694
 
                        datum->permissions.nprim++;
695
 
        }
696
 
        return 0;
697
 
 cleanup:
698
 
        return -1;
 
712
                        datum->permissions.nprim++;
 
713
        }
 
714
        return 0;
 
715
      cleanup:
 
716
        return -1;
699
717
}
700
718
 
701
 
 
702
719
int require_role(int pass)
703
720
{
704
 
        char *id = queue_remove(id_queue);
705
 
        role_datum_t *role = NULL;
706
 
        int retval;
707
 
        if (pass == 1) {
708
 
                free(id);
709
 
                return 0;
710
 
        }
711
 
        if (id == NULL) {
712
 
                yyerror("no role name");
713
 
                return -1;
714
 
        }
715
 
        if ((role = malloc(sizeof (*role))) == NULL) {
716
 
                free(id);
717
 
                yyerror("Out of memory!");
718
 
                return -1;
719
 
        }
720
 
        role_datum_init(role);
721
 
        retval = require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role, &role->value, &role->value);
722
 
        if (retval != 0) {
723
 
                free(id);
724
 
                role_datum_destroy(role);
725
 
                free(role);
726
 
        }
727
 
        switch (retval) {
728
 
        case -3: {
729
 
                yyerror("Out of memory!");
730
 
                return -1;
731
 
        }
732
 
        case -2: {
733
 
                yyerror("duplicate declaration of role");
734
 
                return -1;
735
 
        }
736
 
        case -1: {
737
 
                yyerror("could not require role here");
738
 
                return -1;
739
 
        }
740
 
        case 0: {
741
 
                /* all roles dominate themselves */
742
 
                if (ebitmap_set_bit(&role->dominates, role->value - 1, 1)) {
743
 
                        yyerror("Out of memory");
744
 
                        return -1;
745
 
                }
746
 
                return 0;
747
 
        }
748
 
        case 1: {
749
 
                return 0;  /* role already required */
750
 
        }
751
 
        default: {
752
 
                assert(0);  /* should never get here */
753
 
        }
754
 
        }
755
 
}
756
 
 
757
 
 
758
 
static int require_type_or_attribute(int pass, unsigned char isattr) {
759
 
        char *id = queue_remove(id_queue);
760
 
        type_datum_t *type = NULL;
761
 
        int retval;
762
 
        if (pass == 2) {
763
 
                free(id);
764
 
                return 0;
765
 
        }
766
 
        if (id == NULL) {
767
 
                yyerror("no type name");
768
 
                return -1;
769
 
        }
770
 
        if ((type = malloc(sizeof(*type))) == NULL) {
771
 
                free(id);
772
 
                yyerror("Out of memory!");
773
 
                return -1;
774
 
        }
775
 
        type_datum_init(type);
776
 
        type->primary = 1;
777
 
        type->isattr = isattr;
778
 
        retval = require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type, &type->value, &type->value);
779
 
        if (retval != 0) {
780
 
                free(id);
781
 
                free(type);
782
 
        }
783
 
        switch (retval) {
784
 
        case -3: {
785
 
                yyerror("Out of memory!");
786
 
                return -1;
787
 
        }
788
 
        case -2: {
789
 
                yyerror("duplicate declaration of type/attribute");
790
 
                return -1;
791
 
        }
792
 
        case -1: {
793
 
                yyerror("could not require type/attribute here");
794
 
                return -1;
795
 
        }
796
 
        case 0: {
797
 
                return 0;
798
 
        }
799
 
        case 1: {
800
 
                return 0;    /* type already required */
801
 
        }
802
 
        default: {
803
 
                assert(0);  /* should never get here */
804
 
        }
805
 
        }       
806
 
}
807
 
 
808
 
int require_type(int pass) {
809
 
        return require_type_or_attribute(pass, 0);
810
 
}
811
 
 
812
 
int require_attribute(int pass) {
813
 
        return require_type_or_attribute(pass, 1);
 
721
        char *id = queue_remove(id_queue);
 
722
        role_datum_t *role = NULL;
 
723
        int retval;
 
724
        if (pass == 2) {
 
725
                free(id);
 
726
                return 0;
 
727
        }
 
728
        if (id == NULL) {
 
729
                yyerror("no role name");
 
730
                return -1;
 
731
        }
 
732
        if ((role = malloc(sizeof(*role))) == NULL) {
 
733
                free(id);
 
734
                yyerror("Out of memory!");
 
735
                return -1;
 
736
        }
 
737
        role_datum_init(role);
 
738
        retval =
 
739
            require_symbol(SYM_ROLES, id, (hashtab_datum_t *) role,
 
740
                           &role->s.value, &role->s.value);
 
741
        if (retval != 0) {
 
742
                free(id);
 
743
                role_datum_destroy(role);
 
744
                free(role);
 
745
        }
 
746
        switch (retval) {
 
747
        case -3:{
 
748
                        yyerror("Out of memory!");
 
749
                        return -1;
 
750
                }
 
751
        case -2:{
 
752
                        yyerror("duplicate declaration of role");
 
753
                        return -1;
 
754
                }
 
755
        case -1:{
 
756
                        yyerror("could not require role here");
 
757
                        return -1;
 
758
                }
 
759
        case 0:{
 
760
                        /* all roles dominate themselves */
 
761
                        if (ebitmap_set_bit
 
762
                            (&role->dominates, role->s.value - 1, 1)) {
 
763
                                yyerror("Out of memory");
 
764
                                return -1;
 
765
                        }
 
766
                        return 0;
 
767
                }
 
768
        case 1:{
 
769
                        return 0;       /* role already required */
 
770
                }
 
771
        default:{
 
772
                        assert(0);      /* should never get here */
 
773
                }
 
774
        }
 
775
}
 
776
 
 
777
static int require_type_or_attribute(int pass, unsigned char isattr)
 
778
{
 
779
        char *id = queue_remove(id_queue);
 
780
        type_datum_t *type = NULL;
 
781
        int retval;
 
782
        if (pass == 2) {
 
783
                free(id);
 
784
                return 0;
 
785
        }
 
786
        if (id == NULL) {
 
787
                yyerror("no type name");
 
788
                return -1;
 
789
        }
 
790
        if ((type = malloc(sizeof(*type))) == NULL) {
 
791
                free(id);
 
792
                yyerror("Out of memory!");
 
793
                return -1;
 
794
        }
 
795
        type_datum_init(type);
 
796
        type->primary = 1;
 
797
        type->flavor = isattr ? TYPE_ATTRIB : TYPE_TYPE;
 
798
        retval =
 
799
            require_symbol(SYM_TYPES, id, (hashtab_datum_t *) type,
 
800
                           &type->s.value, &type->s.value);
 
801
        if (retval != 0) {
 
802
                free(id);
 
803
                free(type);
 
804
        }
 
805
        switch (retval) {
 
806
        case -3:{
 
807
                        yyerror("Out of memory!");
 
808
                        return -1;
 
809
                }
 
810
        case -2:{
 
811
                        yyerror("duplicate declaration of type/attribute");
 
812
                        return -1;
 
813
                }
 
814
        case -1:{
 
815
                        yyerror("could not require type/attribute here");
 
816
                        return -1;
 
817
                }
 
818
        case 0:{
 
819
                        return 0;
 
820
                }
 
821
        case 1:{
 
822
                        return 0;       /* type already required */
 
823
                }
 
824
        default:{
 
825
                        assert(0);      /* should never get here */
 
826
                }
 
827
        }
 
828
}
 
829
 
 
830
int require_type(int pass)
 
831
{
 
832
        return require_type_or_attribute(pass, 0);
 
833
}
 
834
 
 
835
int require_attribute(int pass)
 
836
{
 
837
        return require_type_or_attribute(pass, 1);
814
838
}
815
839
 
816
840
int require_user(int pass)
817
841
{
818
 
        char *id = queue_remove(id_queue);
819
 
        user_datum_t *user = NULL;
820
 
        int retval;
821
 
        if (pass == 1) {
822
 
                free(id);
823
 
                return 0;
824
 
        }
825
 
        if (id == NULL) {
826
 
                yyerror("no user name");
827
 
                return -1;
828
 
        }
829
 
        if ((user = malloc(sizeof (*user))) == NULL) {
830
 
                free(id);
831
 
                yyerror("Out of memory!");
832
 
                return -1;
833
 
        }
834
 
        user_datum_init(user);
835
 
        retval = require_symbol(SYM_USERS, id, (hashtab_datum_t *) user, &user->value, &user->value);
836
 
        if (retval != 0) {
837
 
                free(id);
838
 
                user_datum_destroy(user);
839
 
        }
840
 
        switch (retval) {
841
 
        case -3: {
842
 
                yyerror("Out of memory!");
843
 
                return -1;
844
 
        }
845
 
        case -2: {
846
 
                yyerror("duplicate declaration of user");
847
 
                return -1;
848
 
        }
849
 
        case -1: {
850
 
                yyerror("could not require user here");
851
 
                return -1;
852
 
        }
853
 
        case 0: {
854
 
                return 0;
855
 
        }
856
 
        case 1: {
857
 
                return 0;  /* user already required */
858
 
        }
859
 
        default: {
860
 
                assert(0);  /* should never get here */
861
 
        }
862
 
        }
 
842
        char *id = queue_remove(id_queue);
 
843
        user_datum_t *user = NULL;
 
844
        int retval;
 
845
        if (pass == 1) {
 
846
                free(id);
 
847
                return 0;
 
848
        }
 
849
        if (id == NULL) {
 
850
                yyerror("no user name");
 
851
                return -1;
 
852
        }
 
853
        if ((user = malloc(sizeof(*user))) == NULL) {
 
854
                free(id);
 
855
                yyerror("Out of memory!");
 
856
                return -1;
 
857
        }
 
858
        user_datum_init(user);
 
859
        retval =
 
860
            require_symbol(SYM_USERS, id, (hashtab_datum_t *) user,
 
861
                           &user->s.value, &user->s.value);
 
862
        if (retval != 0) {
 
863
                free(id);
 
864
                user_datum_destroy(user);
 
865
        }
 
866
        switch (retval) {
 
867
        case -3:{
 
868
                        yyerror("Out of memory!");
 
869
                        return -1;
 
870
                }
 
871
        case -2:{
 
872
                        yyerror("duplicate declaration of user");
 
873
                        return -1;
 
874
                }
 
875
        case -1:{
 
876
                        yyerror("could not require user here");
 
877
                        return -1;
 
878
                }
 
879
        case 0:{
 
880
                        return 0;
 
881
                }
 
882
        case 1:{
 
883
                        return 0;       /* user already required */
 
884
                }
 
885
        default:{
 
886
                        assert(0);      /* should never get here */
 
887
                }
 
888
        }
863
889
}
864
890
 
865
891
int require_bool(int pass)
866
892
{
867
 
        char *id = queue_remove(id_queue);
868
 
        cond_bool_datum_t *booldatum = NULL;
869
 
        int retval;
870
 
        if (pass == 2) {
871
 
                free(id);
872
 
                return 0;
873
 
        }
874
 
        if (id == NULL) {
875
 
                yyerror("no boolean name");
876
 
                return -1;
877
 
        }
878
 
        if ((booldatum = calloc(1, sizeof (*booldatum))) == NULL) {
879
 
                cond_destroy_bool(id, booldatum, NULL);
880
 
                yyerror("Out of memory!");
881
 
                return -1;
882
 
        }
883
 
        retval = require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum, &booldatum->value, &booldatum->value);
884
 
        if (retval != 0) {
885
 
                cond_destroy_bool(id, booldatum, NULL);
886
 
        }
887
 
        switch (retval) {
888
 
        case -3: {
889
 
                yyerror("Out of memory!");
890
 
                return -1;
891
 
        }
892
 
        case -2: {
893
 
                yyerror("duplicate declaration of boolean");
894
 
                return -1;
895
 
        }
896
 
        case -1: {
897
 
                yyerror("could not require boolean here");
898
 
                return -1;
899
 
        }
900
 
        case 0: {
901
 
                return 0;
902
 
        }
903
 
        case 1: {
904
 
                return 0;  /* boolean already required */
905
 
        }
906
 
        default: {
907
 
                assert(0);  /* should never get here */
908
 
        }
909
 
        }
910
 
}
911
 
 
912
 
static int is_scope_in_stack(scope_datum_t *scope, scope_stack_t *stack) {
913
 
        int i;
914
 
        if (stack == NULL) {
915
 
                return 0;  /* no matching scope found */
916
 
        }
917
 
        if (stack->type == 1) {
918
 
                avrule_decl_t *decl = stack->decl;
919
 
                for (i = 0; i < scope->decl_ids_len; i++) {
920
 
                        if (scope->decl_ids[i] == decl->decl_id) {
921
 
                                return 1;
922
 
                        }
923
 
                }
924
 
        }
925
 
        else {
926
 
                /* note that conditionals can't declare or require
927
 
                 * symbols, so skip this level */
928
 
        }
929
 
 
930
 
        /* not within scope of this stack, so try its parent */
931
 
        return is_scope_in_stack(scope, stack->parent);
932
 
}
933
 
 
934
 
int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id) {
935
 
        scope_datum_t *scope = (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].table, id);
936
 
        if (scope == NULL) {
937
 
                return 1;  /* id is not known, so return success */
938
 
        }
939
 
        return is_scope_in_stack(scope, stack_top);
940
 
}
941
 
 
942
 
static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value, scope_index_t *scope) {
943
 
        if (class_value > scope->class_perms_len) {
944
 
                return 1;
945
 
        }
946
 
        if (ebitmap_get_bit(scope->class_perms_map + class_value - 1,
947
 
                            perm_value - 1)) {
948
 
                return 1;
949
 
        }
950
 
        return 0;
951
 
}
952
 
 
953
 
static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value, scope_stack_t *stack) {
954
 
        if (stack == NULL) {
955
 
                return 0;  /* no matching scope found */
956
 
        }
957
 
        if (stack->type == 1) {
958
 
                avrule_decl_t *decl = stack->decl;
959
 
                if (is_perm_in_scope_index(perm_value, class_value, &decl->required) ||
960
 
                    is_perm_in_scope_index(perm_value, class_value, &decl->declared)) {
961
 
                        return 1;
962
 
                }
963
 
        }
964
 
        else {
965
 
                /* note that conditionals can't declare or require
966
 
                 * symbols, so skip this level */
967
 
        }
968
 
 
969
 
        /* not within scope of this stack, so try its parent */
970
 
        return is_perm_in_stack(perm_value, class_value, stack->parent);
971
 
}
972
 
 
973
 
int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id) {
974
 
        class_datum_t *cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
975
 
                                                                   class_id);
976
 
        perm_datum_t *perdatum;
977
 
        if (cladatum == NULL) {
978
 
                return 1;
979
 
        }
980
 
        perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
981
 
                                                   perm_id);
982
 
        if (perdatum == NULL) {
983
 
                return 1;
984
 
        }
985
 
        return is_perm_in_stack(perdatum->value, cladatum->value, stack_top);
986
 
}
987
 
 
988
 
cond_list_t *get_current_cond_list(cond_list_t *cond) {
989
 
        /* FIX ME: do something different here if in a nested
990
 
         * conditional? */
991
 
        avrule_decl_t *decl = stack_top->decl;
992
 
        return get_decl_cond_list(policydbp, decl, cond);
 
893
        char *id = queue_remove(id_queue);
 
894
        cond_bool_datum_t *booldatum = NULL;
 
895
        int retval;
 
896
        if (pass == 2) {
 
897
                free(id);
 
898
                return 0;
 
899
        }
 
900
        if (id == NULL) {
 
901
                yyerror("no boolean name");
 
902
                return -1;
 
903
        }
 
904
        if ((booldatum = calloc(1, sizeof(*booldatum))) == NULL) {
 
905
                cond_destroy_bool(id, booldatum, NULL);
 
906
                yyerror("Out of memory!");
 
907
                return -1;
 
908
        }
 
909
        retval =
 
910
            require_symbol(SYM_BOOLS, id, (hashtab_datum_t *) booldatum,
 
911
                           &booldatum->s.value, &booldatum->s.value);
 
912
        if (retval != 0) {
 
913
                cond_destroy_bool(id, booldatum, NULL);
 
914
        }
 
915
        switch (retval) {
 
916
        case -3:{
 
917
                        yyerror("Out of memory!");
 
918
                        return -1;
 
919
                }
 
920
        case -2:{
 
921
                        yyerror("duplicate declaration of boolean");
 
922
                        return -1;
 
923
                }
 
924
        case -1:{
 
925
                        yyerror("could not require boolean here");
 
926
                        return -1;
 
927
                }
 
928
        case 0:{
 
929
                        return 0;
 
930
                }
 
931
        case 1:{
 
932
                        return 0;       /* boolean already required */
 
933
                }
 
934
        default:{
 
935
                        assert(0);      /* should never get here */
 
936
                }
 
937
        }
 
938
}
 
939
 
 
940
int require_sens(int pass)
 
941
{
 
942
        char *id = queue_remove(id_queue);
 
943
        level_datum_t *level = NULL;
 
944
        int retval;
 
945
        if (pass == 2) {
 
946
                free(id);
 
947
                return 0;
 
948
        }
 
949
        if (!id) {
 
950
                yyerror("no sensitivity name");
 
951
                return -1;
 
952
        }
 
953
        level = malloc(sizeof(level_datum_t));
 
954
        if (!level) {
 
955
                free(id);
 
956
                yyerror("Out of memory!");
 
957
                return -1;
 
958
        }
 
959
        level_datum_init(level);
 
960
        level->level = malloc(sizeof(mls_level_t));
 
961
        if (!level->level) {
 
962
                free(id);
 
963
                level_datum_destroy(level);
 
964
                free(level);
 
965
                yyerror("Out of memory!");
 
966
                return -1;
 
967
        }
 
968
        mls_level_init(level->level);
 
969
        retval = require_symbol(SYM_LEVELS, id, (hashtab_datum_t *) level,
 
970
                                &level->level->sens, &level->level->sens);
 
971
        if (retval != 0) {
 
972
                free(id);
 
973
                mls_level_destroy(level->level);
 
974
                free(level->level);
 
975
                level_datum_destroy(level);
 
976
                free(level);
 
977
        }
 
978
        switch (retval) {
 
979
        case -3:{
 
980
                        yyerror("Out of memory!");
 
981
                        return -1;
 
982
                }
 
983
        case -2:{
 
984
                        yyerror("duplicate declaration of sensitivity");
 
985
                        return -1;
 
986
                }
 
987
        case -1:{
 
988
                        yyerror("could not require sensitivity here");
 
989
                        return -1;
 
990
                }
 
991
        case 0:{
 
992
                        return 0;
 
993
                }
 
994
        case 1:{
 
995
                        return 0;       /* sensitivity already required */
 
996
                }
 
997
        default:{
 
998
                        assert(0);      /* should never get here */
 
999
                }
 
1000
        }
 
1001
}
 
1002
 
 
1003
int require_cat(int pass)
 
1004
{
 
1005
        char *id = queue_remove(id_queue);
 
1006
        cat_datum_t *cat = NULL;
 
1007
        int retval;
 
1008
        if (pass == 2) {
 
1009
                free(id);
 
1010
                return 0;
 
1011
        }
 
1012
        if (!id) {
 
1013
                yyerror("no category name");
 
1014
                return -1;
 
1015
        }
 
1016
        cat = malloc(sizeof(cat_datum_t));
 
1017
        if (!cat) {
 
1018
                free(id);
 
1019
                yyerror("Out of memory!");
 
1020
                return -1;
 
1021
        }
 
1022
        cat_datum_init(cat);
 
1023
 
 
1024
        retval = require_symbol(SYM_CATS, id, (hashtab_datum_t *) cat,
 
1025
                                &cat->s.value, &cat->s.value);
 
1026
        if (retval != 0) {
 
1027
                free(id);
 
1028
                cat_datum_destroy(cat);
 
1029
                free(cat);
 
1030
        }
 
1031
        switch (retval) {
 
1032
        case -3:{
 
1033
                        yyerror("Out of memory!");
 
1034
                        return -1;
 
1035
                }
 
1036
        case -2:{
 
1037
                        yyerror("duplicate declaration of category");
 
1038
                        return -1;
 
1039
                }
 
1040
        case -1:{
 
1041
                        yyerror("could not require category here");
 
1042
                        return -1;
 
1043
                }
 
1044
        case 0:{
 
1045
                        return 0;
 
1046
                }
 
1047
        case 1:{
 
1048
                        return 0;       /* category already required */
 
1049
                }
 
1050
        default:{
 
1051
                        assert(0);      /* should never get here */
 
1052
                }
 
1053
        }
 
1054
}
 
1055
 
 
1056
static int is_scope_in_stack(scope_datum_t * scope, scope_stack_t * stack)
 
1057
{
 
1058
        int i;
 
1059
        if (stack == NULL) {
 
1060
                return 0;       /* no matching scope found */
 
1061
        }
 
1062
        if (stack->type == 1) {
 
1063
                avrule_decl_t *decl = stack->decl;
 
1064
                for (i = 0; i < scope->decl_ids_len; i++) {
 
1065
                        if (scope->decl_ids[i] == decl->decl_id) {
 
1066
                                return 1;
 
1067
                        }
 
1068
                }
 
1069
        } else {
 
1070
                /* note that conditionals can't declare or require
 
1071
                 * symbols, so skip this level */
 
1072
        }
 
1073
 
 
1074
        /* not within scope of this stack, so try its parent */
 
1075
        return is_scope_in_stack(scope, stack->parent);
 
1076
}
 
1077
 
 
1078
int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id)
 
1079
{
 
1080
        scope_datum_t *scope =
 
1081
            (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].
 
1082
                                             table, id);
 
1083
        if (scope == NULL) {
 
1084
                return 1;       /* id is not known, so return success */
 
1085
        }
 
1086
        return is_scope_in_stack(scope, stack_top);
 
1087
}
 
1088
 
 
1089
static int is_perm_in_scope_index(uint32_t perm_value, uint32_t class_value,
 
1090
                                  scope_index_t * scope)
 
1091
{
 
1092
        if (class_value > scope->class_perms_len) {
 
1093
                return 1;
 
1094
        }
 
1095
        if (ebitmap_get_bit(scope->class_perms_map + class_value - 1,
 
1096
                            perm_value - 1)) {
 
1097
                return 1;
 
1098
        }
 
1099
        return 0;
 
1100
}
 
1101
 
 
1102
static int is_perm_in_stack(uint32_t perm_value, uint32_t class_value,
 
1103
                            scope_stack_t * stack)
 
1104
{
 
1105
        if (stack == NULL) {
 
1106
                return 0;       /* no matching scope found */
 
1107
        }
 
1108
        if (stack->type == 1) {
 
1109
                avrule_decl_t *decl = stack->decl;
 
1110
                if (is_perm_in_scope_index
 
1111
                    (perm_value, class_value, &decl->required)
 
1112
                    || is_perm_in_scope_index(perm_value, class_value,
 
1113
                                              &decl->declared)) {
 
1114
                        return 1;
 
1115
                }
 
1116
        } else {
 
1117
                /* note that conditionals can't declare or require
 
1118
                 * symbols, so skip this level */
 
1119
        }
 
1120
 
 
1121
        /* not within scope of this stack, so try its parent */
 
1122
        return is_perm_in_stack(perm_value, class_value, stack->parent);
 
1123
}
 
1124
 
 
1125
int is_perm_in_scope(hashtab_key_t perm_id, hashtab_key_t class_id)
 
1126
{
 
1127
        class_datum_t *cladatum =
 
1128
            (class_datum_t *) hashtab_search(policydbp->p_classes.table,
 
1129
                                             class_id);
 
1130
        perm_datum_t *perdatum;
 
1131
        if (cladatum == NULL) {
 
1132
                return 1;
 
1133
        }
 
1134
        perdatum = (perm_datum_t *) hashtab_search(cladatum->permissions.table,
 
1135
                                                   perm_id);
 
1136
        if (perdatum == NULL) {
 
1137
                return 1;
 
1138
        }
 
1139
        return is_perm_in_stack(perdatum->s.value, cladatum->s.value,
 
1140
                                stack_top);
 
1141
}
 
1142
 
 
1143
cond_list_t *get_current_cond_list(cond_list_t * cond)
 
1144
{
 
1145
        /* FIX ME: do something different here if in a nested
 
1146
         * conditional? */
 
1147
        avrule_decl_t *decl = stack_top->decl;
 
1148
        return get_decl_cond_list(policydbp, decl, cond);
993
1149
}
994
1150
 
995
1151
/* Append the new conditional node to the existing ones.  During
996
1152
 * expansion the list will be reversed -- i.e., the last AV rule will
997
1153
 * be the first one listed in the policy.  This matches the behavior
998
1154
 * of the upstream compiler. */
999
 
void append_cond_list(cond_list_t *cond) {
1000
 
        cond_list_t *old_cond = get_current_cond_list(cond);
1001
 
        avrule_t *tmp;
1002
 
        assert(old_cond != NULL); /* probably out of memory */
1003
 
        if (old_cond->avtrue_list == NULL) {
1004
 
                old_cond->avtrue_list = cond->avtrue_list;
1005
 
        }
1006
 
        else {
1007
 
                for (tmp = old_cond->avtrue_list; tmp->next != NULL; tmp = tmp->next)
1008
 
                        ;
1009
 
                tmp->next = cond->avtrue_list;
1010
 
        }
1011
 
        if (old_cond->avfalse_list == NULL) {
1012
 
                old_cond->avfalse_list = cond->avfalse_list;
1013
 
        }
1014
 
        else {
1015
 
                for (tmp = old_cond->avfalse_list; tmp->next != NULL; tmp = tmp->next)
1016
 
                        ;
1017
 
                tmp->next = cond->avfalse_list;
1018
 
        }
1019
 
}
1020
 
 
1021
 
void append_avrule(avrule_t *avrule) {
1022
 
        avrule_decl_t *decl = stack_top->decl;
1023
 
 
1024
 
        /* currently avrules follow a completely different code path
1025
 
         * for handling avrules and compute types
1026
 
         * (define_cond_avrule_te_avtab, define_cond_compute_type);
1027
 
         * therefore there ought never be a conditional on top of the
1028
 
         * scope stack */
1029
 
        assert(stack_top->type == 1);
1030
 
 
1031
 
        if (stack_top->last_avrule == NULL) {
1032
 
                decl->avrules = avrule;
1033
 
        }
1034
 
        else {
1035
 
                stack_top->last_avrule->next = avrule;
1036
 
        }
1037
 
        stack_top->last_avrule = avrule;
1038
 
}
1039
 
 
1040
 
/* this doesn't actually append, but really prepends it */
1041
 
void append_role_trans(role_trans_rule_t *role_tr_rules) {
1042
 
        avrule_decl_t *decl = stack_top->decl;
1043
 
 
1044
 
        /* role transitions are not allowed within conditionals */
1045
 
        assert(stack_top->type == 1);
1046
 
 
1047
 
        role_tr_rules->next = decl->role_tr_rules;
1048
 
        decl->role_tr_rules = role_tr_rules;
1049
 
}
1050
 
 
1051
 
/* this doesn't actually append, but really prepends it */
1052
 
void append_role_allow(role_allow_rule_t *role_allow_rules) {
1053
 
        avrule_decl_t *decl = stack_top->decl;
1054
 
 
1055
 
        /* role allows are not allowed within conditionals */
1056
 
        assert(stack_top->type == 1);
1057
 
 
1058
 
        role_allow_rules->next = decl->role_allow_rules;
1059
 
        decl->role_allow_rules = role_allow_rules;
1060
 
}
1061
 
 
1062
 
int begin_optional(int pass) {
1063
 
        avrule_block_t *block = NULL;
1064
 
        avrule_decl_t *decl;
1065
 
        if (pass == 1) {
1066
 
                /* allocate a new avrule block for this optional block */
1067
 
                if ((block = avrule_block_create()) == NULL ||
1068
 
                    (decl = avrule_decl_create(next_decl_id)) == NULL) {
1069
 
                        goto cleanup;
1070
 
                }
1071
 
                block->branch_list = decl;
1072
 
                last_block->next = block;
1073
 
        }
1074
 
        else {
1075
 
                /* select the next block from the chain built during pass 1 */
1076
 
                block = last_block->next;
1077
 
                assert(block != NULL &&
1078
 
                       block->branch_list != NULL &&
1079
 
                       block->branch_list->decl_id == next_decl_id);
1080
 
                decl = block->branch_list;
1081
 
        }
1082
 
        if (push_stack(1, block, decl) == -1) {
1083
 
                goto cleanup;
1084
 
        }
1085
 
        stack_top->last_avrule = NULL;
1086
 
        last_block = block;
1087
 
        next_decl_id++;
1088
 
        return 0;
1089
 
 cleanup:
1090
 
        yyerror("Out of memory!");
1091
 
        avrule_block_destroy(block);
1092
 
        return -1;
1093
 
}
1094
 
 
1095
 
int end_optional(int pass) {
1096
 
        /* once nested conditionals are allowed, do the stack unfolding here */
1097
 
        pop_stack();
1098
 
        return 0;
1099
 
}
1100
 
 
1101
 
int begin_optional_else(int pass) {
1102
 
        avrule_decl_t *decl;
1103
 
        assert(stack_top->type == 1 && stack_top->in_else == 0);
1104
 
        if (pass == 1) {
1105
 
                /* allocate a new declaration and add it to the
1106
 
                 * current chain */
1107
 
                if ((decl = avrule_decl_create(next_decl_id)) == NULL) {
1108
 
                        yyerror("Out of memory!");
1109
 
                        return -1;
1110
 
                }
1111
 
                stack_top->decl->next = decl;
1112
 
        }
1113
 
        else {
1114
 
                /* pick the (hopefully last) declaration of this
1115
 
                   avrule block, built from pass 1 */
1116
 
                decl = stack_top->decl->next;
1117
 
                assert(decl != NULL &&
1118
 
                       decl->next == NULL &&
1119
 
                       decl->decl_id == next_decl_id);
1120
 
        }
1121
 
        stack_top->in_else = 1;
1122
 
        stack_top->decl = decl;
1123
 
        stack_top->last_avrule = NULL;
1124
 
        stack_top->require_given = 0;
1125
 
        next_decl_id++;
1126
 
        return 0;
1127
 
}
1128
 
 
1129
 
static int copy_requirements(avrule_decl_t *dest, scope_stack_t *stack) {
1130
 
        int i;
1131
 
        if (stack == NULL) {
1132
 
                return 0;
1133
 
        }
1134
 
        if (stack->type == 1) {
1135
 
                scope_index_t *src_scope = &stack->decl->required;
1136
 
                scope_index_t *dest_scope = &dest->required;
1137
 
                for (i = 0; i < SYM_NUM; i++) {
1138
 
                        ebitmap_t *src_bitmap = &src_scope->scope[i];
1139
 
                        ebitmap_t *dest_bitmap = &dest_scope->scope[i];
1140
 
                        if (ebitmap_union(dest_bitmap, src_bitmap)) {
1141
 
                                yyerror("Out of memory!");
1142
 
                                return -1;
1143
 
                        }
1144
 
                }
1145
 
                /* now copy class permissions */
1146
 
                if (src_scope->class_perms_len > dest_scope->class_perms_len) {
1147
 
                        ebitmap_t *new_map = realloc(dest_scope->class_perms_map,
1148
 
                                                     src_scope->class_perms_len * sizeof(*new_map));
1149
 
                        if (new_map == NULL) {
1150
 
                                yyerror("Out of memory!");
1151
 
                                return -1;
1152
 
                        }
1153
 
                        dest_scope->class_perms_map = new_map;
1154
 
                        for (i = dest_scope->class_perms_len; i < src_scope->class_perms_len; i++) {
1155
 
                                ebitmap_init(dest_scope->class_perms_map + i);
1156
 
                        }
1157
 
                        dest_scope->class_perms_len = src_scope->class_perms_len;
1158
 
                }
1159
 
                for (i = 0; i < src_scope->class_perms_len; i++) {
1160
 
                        ebitmap_t *src_bitmap = &src_scope->class_perms_map[i];
1161
 
                        ebitmap_t *dest_bitmap = &dest_scope->class_perms_map[i];
1162
 
                        if (ebitmap_union(dest_bitmap, src_bitmap)) {
1163
 
                                yyerror("Out of memory!");
1164
 
                                return -1;
1165
 
                        }
1166
 
                }
1167
 
        }
1168
 
        return copy_requirements(dest, stack->parent);
 
1155
void append_cond_list(cond_list_t * cond)
 
1156
{
 
1157
        cond_list_t *old_cond = get_current_cond_list(cond);
 
1158
        avrule_t *tmp;
 
1159
        assert(old_cond != NULL);       /* probably out of memory */
 
1160
        if (old_cond->avtrue_list == NULL) {
 
1161
                old_cond->avtrue_list = cond->avtrue_list;
 
1162
        } else {
 
1163
                for (tmp = old_cond->avtrue_list; tmp->next != NULL;
 
1164
                     tmp = tmp->next) ;
 
1165
                tmp->next = cond->avtrue_list;
 
1166
        }
 
1167
        if (old_cond->avfalse_list == NULL) {
 
1168
                old_cond->avfalse_list = cond->avfalse_list;
 
1169
        } else {
 
1170
                for (tmp = old_cond->avfalse_list; tmp->next != NULL;
 
1171
                     tmp = tmp->next) ;
 
1172
                tmp->next = cond->avfalse_list;
 
1173
        }
 
1174
}
 
1175
 
 
1176
void append_avrule(avrule_t * avrule)
 
1177
{
 
1178
        avrule_decl_t *decl = stack_top->decl;
 
1179
 
 
1180
        /* currently avrules follow a completely different code path
 
1181
         * for handling avrules and compute types
 
1182
         * (define_cond_avrule_te_avtab, define_cond_compute_type);
 
1183
         * therefore there ought never be a conditional on top of the
 
1184
         * scope stack */
 
1185
        assert(stack_top->type == 1);
 
1186
 
 
1187
        if (stack_top->last_avrule == NULL) {
 
1188
                decl->avrules = avrule;
 
1189
        } else {
 
1190
                stack_top->last_avrule->next = avrule;
 
1191
        }
 
1192
        stack_top->last_avrule = avrule;
 
1193
}
 
1194
 
 
1195
/* this doesn't actually append, but really prepends it */
 
1196
void append_role_trans(role_trans_rule_t * role_tr_rules)
 
1197
{
 
1198
        avrule_decl_t *decl = stack_top->decl;
 
1199
 
 
1200
        /* role transitions are not allowed within conditionals */
 
1201
        assert(stack_top->type == 1);
 
1202
 
 
1203
        role_tr_rules->next = decl->role_tr_rules;
 
1204
        decl->role_tr_rules = role_tr_rules;
 
1205
}
 
1206
 
 
1207
/* this doesn't actually append, but really prepends it */
 
1208
void append_role_allow(role_allow_rule_t * role_allow_rules)
 
1209
{
 
1210
        avrule_decl_t *decl = stack_top->decl;
 
1211
 
 
1212
        /* role allows are not allowed within conditionals */
 
1213
        assert(stack_top->type == 1);
 
1214
 
 
1215
        role_allow_rules->next = decl->role_allow_rules;
 
1216
        decl->role_allow_rules = role_allow_rules;
 
1217
}
 
1218
 
 
1219
/* this doesn't actually append, but really prepends it */
 
1220
void append_range_trans(range_trans_rule_t * range_tr_rules)
 
1221
{
 
1222
        avrule_decl_t *decl = stack_top->decl;
 
1223
 
 
1224
        /* range transitions are not allowed within conditionals */
 
1225
        assert(stack_top->type == 1);
 
1226
 
 
1227
        range_tr_rules->next = decl->range_tr_rules;
 
1228
        decl->range_tr_rules = range_tr_rules;
 
1229
}
 
1230
 
 
1231
int begin_optional(int pass)
 
1232
{
 
1233
        avrule_block_t *block = NULL;
 
1234
        avrule_decl_t *decl;
 
1235
        if (pass == 1) {
 
1236
                /* allocate a new avrule block for this optional block */
 
1237
                if ((block = avrule_block_create()) == NULL ||
 
1238
                    (decl = avrule_decl_create(next_decl_id)) == NULL) {
 
1239
                        goto cleanup;
 
1240
                }
 
1241
                block->flags |= AVRULE_OPTIONAL;
 
1242
                block->branch_list = decl;
 
1243
                last_block->next = block;
 
1244
        } else {
 
1245
                /* select the next block from the chain built during pass 1 */
 
1246
                block = last_block->next;
 
1247
                assert(block != NULL &&
 
1248
                       block->branch_list != NULL &&
 
1249
                       block->branch_list->decl_id == next_decl_id);
 
1250
                decl = block->branch_list;
 
1251
        }
 
1252
        if (push_stack(1, block, decl) == -1) {
 
1253
                goto cleanup;
 
1254
        }
 
1255
        stack_top->last_avrule = NULL;
 
1256
        last_block = block;
 
1257
        next_decl_id++;
 
1258
        return 0;
 
1259
      cleanup:
 
1260
        yyerror("Out of memory!");
 
1261
        avrule_block_destroy(block);
 
1262
        return -1;
 
1263
}
 
1264
 
 
1265
int end_optional(int pass)
 
1266
{
 
1267
        /* once nested conditionals are allowed, do the stack unfolding here */
 
1268
        pop_stack();
 
1269
        return 0;
 
1270
}
 
1271
 
 
1272
int begin_optional_else(int pass)
 
1273
{
 
1274
        avrule_decl_t *decl;
 
1275
        assert(stack_top->type == 1 && stack_top->in_else == 0);
 
1276
        if (pass == 1) {
 
1277
                /* allocate a new declaration and add it to the
 
1278
                 * current chain */
 
1279
                if ((decl = avrule_decl_create(next_decl_id)) == NULL) {
 
1280
                        yyerror("Out of memory!");
 
1281
                        return -1;
 
1282
                }
 
1283
                stack_top->decl->next = decl;
 
1284
        } else {
 
1285
                /* pick the (hopefully last) declaration of this
 
1286
                   avrule block, built from pass 1 */
 
1287
                decl = stack_top->decl->next;
 
1288
                assert(decl != NULL &&
 
1289
                       decl->next == NULL && decl->decl_id == next_decl_id);
 
1290
        }
 
1291
        stack_top->in_else = 1;
 
1292
        stack_top->decl = decl;
 
1293
        stack_top->last_avrule = NULL;
 
1294
        stack_top->require_given = 0;
 
1295
        next_decl_id++;
 
1296
        return 0;
 
1297
}
 
1298
 
 
1299
static int copy_requirements(avrule_decl_t * dest, scope_stack_t * stack)
 
1300
{
 
1301
        int i;
 
1302
        if (stack == NULL) {
 
1303
                return 0;
 
1304
        }
 
1305
        if (stack->type == 1) {
 
1306
                scope_index_t *src_scope = &stack->decl->required;
 
1307
                scope_index_t *dest_scope = &dest->required;
 
1308
                for (i = 0; i < SYM_NUM; i++) {
 
1309
                        ebitmap_t *src_bitmap = &src_scope->scope[i];
 
1310
                        ebitmap_t *dest_bitmap = &dest_scope->scope[i];
 
1311
                        if (ebitmap_union(dest_bitmap, src_bitmap)) {
 
1312
                                yyerror("Out of memory!");
 
1313
                                return -1;
 
1314
                        }
 
1315
                }
 
1316
                /* now copy class permissions */
 
1317
                if (src_scope->class_perms_len > dest_scope->class_perms_len) {
 
1318
                        ebitmap_t *new_map =
 
1319
                            realloc(dest_scope->class_perms_map,
 
1320
                                    src_scope->class_perms_len *
 
1321
                                    sizeof(*new_map));
 
1322
                        if (new_map == NULL) {
 
1323
                                yyerror("Out of memory!");
 
1324
                                return -1;
 
1325
                        }
 
1326
                        dest_scope->class_perms_map = new_map;
 
1327
                        for (i = dest_scope->class_perms_len;
 
1328
                             i < src_scope->class_perms_len; i++) {
 
1329
                                ebitmap_init(dest_scope->class_perms_map + i);
 
1330
                        }
 
1331
                        dest_scope->class_perms_len =
 
1332
                            src_scope->class_perms_len;
 
1333
                }
 
1334
                for (i = 0; i < src_scope->class_perms_len; i++) {
 
1335
                        ebitmap_t *src_bitmap = &src_scope->class_perms_map[i];
 
1336
                        ebitmap_t *dest_bitmap =
 
1337
                            &dest_scope->class_perms_map[i];
 
1338
                        if (ebitmap_union(dest_bitmap, src_bitmap)) {
 
1339
                                yyerror("Out of memory!");
 
1340
                                return -1;
 
1341
                        }
 
1342
                }
 
1343
        }
 
1344
        return copy_requirements(dest, stack->parent);
1169
1345
}
1170
1346
 
1171
1347
/* During pass 1, check that at least one thing was required within
1172
1348
 * this block, for those places where a REQUIRED is necessary.  During
1173
1349
 * pass 2, have this block inherit its parents' requirements.  Return
1174
1350
 * 0 on success, -1 on failure. */
1175
 
int end_avrule_block(int pass) {
1176
 
        avrule_decl_t *decl = stack_top->decl;
1177
 
        assert(stack_top->type == 1);
1178
 
        if (pass == 2) {
1179
 
                /* this avrule_decl inherits all of its parents'
1180
 
                 * requirements */
1181
 
                if (copy_requirements(decl, stack_top->parent) == -1) {
1182
 
                        return -1;
1183
 
                }
1184
 
                return 0;
1185
 
        }
1186
 
        if (!stack_top->in_else && !stack_top->require_given) {
1187
 
                if (policydbp->policy_type == POLICY_BASE && stack_top->parent != NULL) {
 
1351
int end_avrule_block(int pass)
 
1352
{
 
1353
        avrule_decl_t *decl = stack_top->decl;
 
1354
        assert(stack_top->type == 1);
 
1355
        if (pass == 2) {
 
1356
                /* this avrule_decl inherits all of its parents'
 
1357
                 * requirements */
 
1358
                if (copy_requirements(decl, stack_top->parent) == -1) {
 
1359
                        return -1;
 
1360
                }
 
1361
                return 0;
 
1362
        }
 
1363
        if (!stack_top->in_else && !stack_top->require_given) {
 
1364
                if (policydbp->policy_type == POLICY_BASE
 
1365
                    && stack_top->parent != NULL) {
1188
1366
                        /* if this is base no require should be in the global block */
1189
1367
                        return 0;
1190
1368
                } else {
1191
 
                        /* non-ELSE branches must have at least one thing required */
1192
 
                        yyerror("This block has no require section.");
1193
 
                        return -1;
 
1369
                        /* non-ELSE branches must have at least one thing required */
 
1370
                        yyerror("This block has no require section.");
 
1371
                        return -1;
1194
1372
                }
1195
 
        }
1196
 
        return 0;
 
1373
        }
 
1374
        return 0;
1197
1375
}
1198
1376
 
1199
1377
/* Push a new scope on to the stack and update the 'last' pointer.
1200
1378
 * Return 0 on success, -1 if out * of memory. */
1201
 
static int push_stack(int stack_type, ...) {
1202
 
        scope_stack_t *s = calloc(1, sizeof(*s));
1203
 
        va_list ap;
1204
 
        if (s == NULL) {
1205
 
                return -1;
1206
 
        }
1207
 
        va_start(ap, stack_type);
1208
 
        switch (s->type = stack_type) {
1209
 
        case 1: {
1210
 
                s->u.avrule = va_arg(ap, avrule_block_t *);
1211
 
                s->decl = va_arg(ap, avrule_decl_t *);
1212
 
                break;
1213
 
        }
1214
 
        case 2: {
1215
 
                s->u.cond_list = va_arg(ap, cond_list_t *);
1216
 
                break;
1217
 
        }
1218
 
        default:
1219
 
                /* invalid stack type given */
1220
 
                assert(0);
1221
 
        }
1222
 
        va_end(ap);
1223
 
        s->parent = stack_top;
1224
 
        s->child = NULL;
1225
 
        stack_top = s;
1226
 
        return 0;
 
1379
static int push_stack(int stack_type, ...)
 
1380
{
 
1381
        scope_stack_t *s = calloc(1, sizeof(*s));
 
1382
        va_list ap;
 
1383
        if (s == NULL) {
 
1384
                return -1;
 
1385
        }
 
1386
        va_start(ap, stack_type);
 
1387
        switch (s->type = stack_type) {
 
1388
        case 1:{
 
1389
                        s->u.avrule = va_arg(ap, avrule_block_t *);
 
1390
                        s->decl = va_arg(ap, avrule_decl_t *);
 
1391
                        break;
 
1392
                }
 
1393
        case 2:{
 
1394
                        s->u.cond_list = va_arg(ap, cond_list_t *);
 
1395
                        break;
 
1396
                }
 
1397
        default:
 
1398
                /* invalid stack type given */
 
1399
                assert(0);
 
1400
        }
 
1401
        va_end(ap);
 
1402
        s->parent = stack_top;
 
1403
        s->child = NULL;
 
1404
        stack_top = s;
 
1405
        return 0;
1227
1406
}
1228
1407
 
1229
1408
/* Pop off the most recently added from the stack.  Update the 'last'
1230
1409
 * pointer. */
1231
 
static void pop_stack(void) {
1232
 
        scope_stack_t *parent;
1233
 
        assert(stack_top != NULL);
1234
 
        parent = stack_top->parent;
1235
 
        if (parent != NULL) {
1236
 
                parent->child = NULL;
1237
 
        }
1238
 
        free(stack_top);
1239
 
        stack_top = parent;
 
1410
static void pop_stack(void)
 
1411
{
 
1412
        scope_stack_t *parent;
 
1413
        assert(stack_top != NULL);
 
1414
        parent = stack_top->parent;
 
1415
        if (parent != NULL) {
 
1416
                parent->child = NULL;
 
1417
        }
 
1418
        free(stack_top);
 
1419
        stack_top = parent;
1240
1420
}