Coverage Report

Created: 2024-07-27 06:22

/src/selinux/libsepol/src/avrule_block.c
Line
Count
Source (jump to first uncovered line)
1
/* Authors: Jason Tang <jtang@tresys.com>
2
 *
3
 * Functions that manipulate a logical block (conditional, optional,
4
 * or global scope) for a policy module.
5
 *
6
 * Copyright (C) 2005 Tresys Technology, LLC
7
 *
8
 *  This library is free software; you can redistribute it and/or
9
 *  modify it under the terms of the GNU Lesser General Public
10
 *  License as published by the Free Software Foundation; either
11
 *  version 2.1 of the License, or (at your option) any later version.
12
 *
13
 *  This library is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 *  Lesser General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU Lesser General Public
19
 *  License along with this library; if not, write to the Free Software
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
 */
22
23
#include <sepol/policydb/policydb.h>
24
#include <sepol/policydb/conditional.h>
25
#include <sepol/policydb/avrule_block.h>
26
27
#include <assert.h>
28
#include <stdlib.h>
29
30
/* It is anticipated that there be less declarations within an avrule
31
 * block than the global policy.  Thus the symbol table sizes are
32
 * smaller than those listed in policydb.c */
33
static const unsigned int symtab_sizes[SYM_NUM] = {
34
  2,
35
  4,
36
  8,
37
  32,
38
  16,
39
  4,
40
  2,
41
  2,
42
};
43
44
avrule_block_t *avrule_block_create(void)
45
2.77k
{
46
2.77k
  avrule_block_t *block;
47
2.77k
  if ((block = calloc(1, sizeof(*block))) == NULL) {
48
0
    return NULL;
49
0
  }
50
2.77k
  return block;
51
2.77k
}
52
53
avrule_decl_t *avrule_decl_create(uint32_t decl_id)
54
2.77k
{
55
2.77k
  avrule_decl_t *decl;
56
2.77k
  int i;
57
2.77k
  if ((decl = calloc(1, sizeof(*decl))) == NULL) {
58
0
    return NULL;
59
0
  }
60
2.77k
  decl->decl_id = decl_id;
61
24.9k
  for (i = 0; i < SYM_NUM; i++) {
62
22.1k
    if (symtab_init(&decl->symtab[i], symtab_sizes[i])) {
63
0
      avrule_decl_destroy(decl);
64
0
      return NULL;
65
0
    }
66
22.1k
  }
67
68
24.9k
  for (i = 0; i < SYM_NUM; i++) {
69
22.1k
    ebitmap_init(&decl->required.scope[i]);
70
22.1k
    ebitmap_init(&decl->declared.scope[i]);
71
22.1k
  }
72
2.77k
  return decl;
73
2.77k
}
74
75
/* note that unlike the other destroy functions, this one does /NOT/
76
 * destroy the pointer itself */
77
static void scope_index_destroy(scope_index_t * scope)
78
5.54k
{
79
5.54k
  unsigned int i;
80
5.54k
  if (scope == NULL) {
81
0
    return;
82
0
  }
83
49.9k
  for (i = 0; i < SYM_NUM; i++) {
84
44.3k
    ebitmap_destroy(scope->scope + i);
85
44.3k
  }
86
5.54k
  if (scope->class_perms_map) {
87
0
    for (i = 0; i < scope->class_perms_len; i++) {
88
0
      ebitmap_destroy(scope->class_perms_map + i);
89
0
    }
90
0
  }
91
5.54k
  free(scope->class_perms_map);
92
5.54k
}
93
94
void avrule_decl_destroy(avrule_decl_t * x)
95
2.77k
{
96
2.77k
  if (x == NULL) {
97
0
    return;
98
0
  }
99
2.77k
  cond_list_destroy(x->cond_list);
100
2.77k
  avrule_list_destroy(x->avrules);
101
2.77k
  role_trans_rule_list_destroy(x->role_tr_rules);
102
2.77k
  filename_trans_rule_list_destroy(x->filename_trans_rules);
103
2.77k
  role_allow_rule_list_destroy(x->role_allow_rules);
104
2.77k
  range_trans_rule_list_destroy(x->range_tr_rules);
105
2.77k
  scope_index_destroy(&x->required);
106
2.77k
  scope_index_destroy(&x->declared);
107
2.77k
  symtabs_destroy(x->symtab);
108
2.77k
  free(x->module_name);
109
2.77k
  free(x);
110
2.77k
}
111
112
void avrule_block_destroy(avrule_block_t * x)
113
2.77k
{
114
2.77k
  avrule_decl_t *decl;
115
2.77k
  if (x == NULL) {
116
0
    return;
117
0
  }
118
2.77k
  decl = x->branch_list;
119
5.54k
  while (decl != NULL) {
120
2.77k
    avrule_decl_t *next_decl = decl->next;
121
2.77k
    avrule_decl_destroy(decl);
122
2.77k
    decl = next_decl;
123
2.77k
  }
124
2.77k
  free(x);
125
2.77k
}
126
127
void avrule_block_list_destroy(avrule_block_t * x)
128
2.77k
{
129
5.54k
  while (x != NULL) {
130
2.77k
    avrule_block_t *next = x->next;
131
2.77k
    avrule_block_destroy(x);
132
2.77k
    x = next;
133
2.77k
  }
134
2.77k
}
135
136
/* Get a conditional node from a avrule_decl with the same expression.
137
 * If that expression does not exist then create one. */
138
cond_list_t *get_decl_cond_list(policydb_t * p, avrule_decl_t * decl,
139
        cond_list_t * cond)
140
0
{
141
0
  cond_list_t *result;
142
0
  int was_created;
143
0
  result = cond_node_find(p, cond, decl->cond_list, &was_created);
144
0
  if (result != NULL && was_created) {
145
0
    result->next = decl->cond_list;
146
0
    decl->cond_list = result;
147
0
  }
148
0
  return result;
149
0
}
150
151
/* Look up an identifier in a policy's scoping table.  If it is there,
152
 * marked as SCOPE_DECL, and any of its declaring block has been enabled,
153
 * then return 1.  Otherwise return 0. Can only be called after the 
154
 * decl_val_to_struct index has been created */
155
int is_id_enabled(const char *id, const policydb_t * p, int symbol_table)
156
0
{
157
0
  const scope_datum_t *scope =
158
0
      (scope_datum_t *) hashtab_search(p->scope[symbol_table].table, id);
159
0
  const avrule_decl_t *decl;
160
0
  uint32_t len;
161
162
0
  if (scope == NULL) {
163
0
    return 0;
164
0
  }
165
0
  if (scope->scope != SCOPE_DECL) {
166
0
    return 0;
167
0
  }
168
169
0
  len = scope->decl_ids_len;
170
0
  if (len < 1) {
171
0
    return 0;
172
0
  }
173
174
0
  if (symbol_table == SYM_ROLES || symbol_table == SYM_USERS) {
175
0
    uint32_t i;
176
0
    for (i = 0; i < len; i++) {
177
0
      decl = p->decl_val_to_struct[scope->decl_ids[i] - 1];
178
0
      if (decl != NULL && decl->enabled) {
179
0
        return 1;
180
0
      }
181
0
    }
182
0
  } else {
183
0
    decl = p->decl_val_to_struct[scope->decl_ids[len-1] - 1];
184
0
    if (decl != NULL && decl->enabled) {
185
0
      return 1;
186
0
    }
187
0
  }
188
189
0
  return 0;
190
0
}
191
192
/* Check if a particular permission is present within the given class.
193
 * Whether the class is enabled is NOT checked.
194
 * Returns 1 if permission is present, 0 otherwise */
195
int is_perm_existent(const class_datum_t *cladatum, const char *perm_id)
196
0
{
197
0
  const perm_datum_t *perm;
198
199
0
  perm = hashtab_search(cladatum->permissions.table, perm_id);
200
0
  if (perm == NULL && cladatum->comdatum != 0) {
201
    /* permission was not in this class.  before giving
202
     * up, check the class's parent */
203
0
    perm =
204
0
        hashtab_search(cladatum->comdatum->permissions.table,
205
0
           perm_id);
206
0
  }
207
0
  if (perm == NULL) {
208
0
    return 0;
209
0
  }
210
0
  return 1;
211
0
}