Compare commits
145 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7a48f3506f | ||
|
f7d3e92ab4 | ||
|
ed61d9f2c1 | ||
|
09d2e8094c | ||
|
459a123b94 | ||
|
13eae1c266 | ||
|
838d335395 | ||
|
32434c9af6 | ||
|
39b828ba84 | ||
|
cdfab80e4f | ||
|
8f242926e6 | ||
|
9252e3a610 | ||
|
c58a1c7ba8 | ||
|
fd4d970e8a | ||
|
3579f74695 | ||
|
7a84df0229 | ||
|
50ae97404c | ||
|
5c73d48883 | ||
|
01964798fa | ||
|
d300c9886e | ||
|
ce5eeffdaa | ||
|
ba37cef257 | ||
|
ddd17ca307 | ||
|
6b4592388f | ||
|
20bb12ceb9 | ||
|
bbccbf93a7 | ||
|
32c4c0d503 | ||
|
fa475c1e36 | ||
|
70ceab4461 | ||
|
0ce45d72d2 | ||
|
8bb335b66c | ||
|
4526ce3233 | ||
|
3a48e0a688 | ||
|
fc3f64a7e0 | ||
|
eb32e87623 | ||
|
89aa58d422 | ||
|
0de70f05fe | ||
|
26d393d9cb | ||
|
94d6cb61f3 | ||
|
c7d36f14a7 | ||
|
355996f836 | ||
|
02871fc83d | ||
|
3a71508af5 | ||
|
640cc38286 | ||
|
41f64ace3a | ||
|
e02987b8e3 | ||
|
259de5ea3b | ||
|
175b09a804 | ||
|
99653f4b76 | ||
|
6f37e10a79 | ||
|
d162105aae | ||
|
aac9abeb50 | ||
|
5ec2ad1fb2 | ||
|
44e2d26a69 | ||
|
0a1d1e58aa | ||
|
d88ffa19a4 | ||
|
29e9ab01e1 | ||
|
71b1a80d94 | ||
|
6bf5b06538 | ||
|
a7ec325b44 | ||
|
154778f82c | ||
|
0861542f57 | ||
|
96ba36d4a0 | ||
|
3febb8cf9a | ||
|
a554107a85 | ||
|
8b5abd72f1 | ||
|
cb8eded90a | ||
|
cc880287e2 | ||
|
5e480567c8 | ||
|
e4eba91d66 | ||
|
658aaff9c8 | ||
|
35b7bcbd4e | ||
|
f4c39a3999 | ||
|
44f2d57366 | ||
|
0d1fcdd0f7 | ||
|
b84a7e51c3 | ||
|
2ec04ef185 | ||
|
be60b4fdd2 | ||
|
87d9d9b744 | ||
|
4704b23dcb | ||
|
ee7b363d01 | ||
|
5c767f8d24 | ||
|
e7d43c0ef0 | ||
|
8f8f3fb514 | ||
|
1a48e42dcf | ||
|
d002148307 | ||
|
6e6c78000d | ||
|
5a38f90989 | ||
|
7a2ea3adf4 | ||
|
0df3b08ca9 | ||
|
a3698bbb34 | ||
|
0557b38137 | ||
|
eb4908df1b | ||
|
7a85deddcf | ||
|
99ee75724c | ||
|
f204e024f1 | ||
|
feedd04d81 | ||
|
4b02553992 | ||
|
fa3013007e | ||
|
03f17d27e6 | ||
|
5f329cea08 | ||
|
96e6f72927 | ||
|
9d04e817bf | ||
|
a195d32913 | ||
|
46942f6c6f | ||
|
ee95801ed9 | ||
|
f39b887832 | ||
|
f15ff0d1b0 | ||
|
b413b6e9e9 | ||
|
58df885532 | ||
|
39e091adf3 | ||
|
878dae3299 | ||
|
07e78442e3 | ||
|
ed26f06a29 | ||
|
3c75a3b3ff | ||
|
6eec04097e | ||
|
a98ce44d26 | ||
|
b7b88e49b7 | ||
|
1a403b0896 | ||
|
6e97542597 | ||
|
54f27dc276 | ||
|
554824b9da | ||
|
53af5b6865 | ||
|
a3a7288b5c | ||
|
92502fe369 | ||
|
65043ab531 | ||
|
60894b281e | ||
|
9788767c5c | ||
|
957300d4ea | ||
|
a7387c80ed | ||
|
83e7a5b3fa | ||
|
90faed0461 | ||
|
c07084d5f6 | ||
|
aca479dae3 | ||
|
a5bd29455e | ||
|
7f9cab778e | ||
|
31a56530a4 | ||
|
ad2013ee23 | ||
|
be396c6d8c | ||
|
cd4e504b6b | ||
|
4ce335c44c | ||
|
a2f29b67b1 | ||
|
47d254b60b | ||
|
848ca5cad6 | ||
|
d13ce1e89d |
37
.gitignore
vendored
37
.gitignore
vendored
@ -140,3 +140,40 @@ libsepol-2.0.30.tgz
|
|||||||
libsepol-2.0.31.tgz
|
libsepol-2.0.31.tgz
|
||||||
libsepol-2.0.32.tgz
|
libsepol-2.0.32.tgz
|
||||||
libsepol-2.0.33.tgz
|
libsepol-2.0.33.tgz
|
||||||
|
libsepol-2.0.34.tgz
|
||||||
|
libsepol-2.0.35.tgz
|
||||||
|
libsepol-2.0.36.tgz
|
||||||
|
libsepol-2.0.37.tgz
|
||||||
|
libsepol-2.0.38.tgz
|
||||||
|
libsepol-2.0.39.tgz
|
||||||
|
libsepol-2.0.40.tgz
|
||||||
|
libsepol-2.0.41.tgz
|
||||||
|
/libsepol-2.0.42.tgz
|
||||||
|
/libsepol-2.0.43.tgz
|
||||||
|
/libsepol-2.0.44.tgz
|
||||||
|
/libsepol-2.0.45.tgz
|
||||||
|
/libsepol-2.1.0.tgz
|
||||||
|
/libsepol-2.1.1.tgz
|
||||||
|
/libsepol-2.1.2.tgz
|
||||||
|
/libsepol-2.1.3.tgz
|
||||||
|
/libsepol-2.1.4.tgz
|
||||||
|
/libsepol-2.1.5.tgz
|
||||||
|
/libsepol-2.1.7.tgz
|
||||||
|
/libsepol-2.1.8.tgz
|
||||||
|
/libsepol-2.1.9.tgz
|
||||||
|
/libsepol-2.2.tgz
|
||||||
|
/libsepol-2.3.tgz
|
||||||
|
/libsepol-2.4.tar.gz
|
||||||
|
/libsepol-2.5-rc1.tar.gz
|
||||||
|
/libsepol-2.5.tar.gz
|
||||||
|
/libsepol-2.6.tar.gz
|
||||||
|
/libsepol-2.7.tar.gz
|
||||||
|
/libsepol-2.8-rc1.tar.gz
|
||||||
|
/libsepol-2.8-rc3.tar.gz
|
||||||
|
/libsepol-2.8.tar.gz
|
||||||
|
/libsepol-2.9-rc1.tar.gz
|
||||||
|
/libsepol-2.9-rc2.tar.gz
|
||||||
|
/libsepol-2.9.tar.gz
|
||||||
|
/libsepol-3.0-rc1.tar.gz
|
||||||
|
/libsepol-3.0.tar.gz
|
||||||
|
/libsepol-3.1.tar.gz
|
||||||
|
592
0001-libsepol-checkpolicy-optimize-storage-of-filename-tr.patch
Normal file
592
0001-libsepol-checkpolicy-optimize-storage-of-filename-tr.patch
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
From 42ae834a7428c57f7b2a9f448adf4cf991fa3487 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
Date: Fri, 31 Jul 2020 13:10:34 +0200
|
||||||
|
Subject: [PATCH] libsepol,checkpolicy: optimize storage of filename
|
||||||
|
transitions
|
||||||
|
|
||||||
|
In preparation to support a new policy format with a more optimal
|
||||||
|
representation of filename transition rules, this patch applies an
|
||||||
|
equivalent change from kernel commit c3a276111ea2 ("selinux: optimize
|
||||||
|
storage of filename transitions").
|
||||||
|
|
||||||
|
See the kernel commit's description [1] for the rationale behind this
|
||||||
|
representation. This change doesn't bring any measurable difference of
|
||||||
|
policy build performance (semodule -B) on Fedora.
|
||||||
|
|
||||||
|
[1] https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git/commit/?id=c3a276111ea2572399281988b3129683e2a6b60b
|
||||||
|
|
||||||
|
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_binary.c | 26 ++---
|
||||||
|
libsepol/include/sepol/policydb/policydb.h | 15 ++-
|
||||||
|
libsepol/src/expand.c | 56 ++-------
|
||||||
|
libsepol/src/kernel_to_cil.c | 24 +++-
|
||||||
|
libsepol/src/kernel_to_conf.c | 24 +++-
|
||||||
|
libsepol/src/policydb.c | 125 +++++++++++++++------
|
||||||
|
libsepol/src/write.c | 46 ++++----
|
||||||
|
7 files changed, 183 insertions(+), 133 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||||
|
index 62178d998468..7726685809af 100644
|
||||||
|
--- a/libsepol/cil/src/cil_binary.c
|
||||||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||||||
|
@@ -1131,11 +1131,10 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru
|
||||||
|
class_datum_t *sepol_obj = NULL;
|
||||||
|
struct cil_list *class_list;
|
||||||
|
type_datum_t *sepol_result = NULL;
|
||||||
|
- filename_trans_t *newkey = NULL;
|
||||||
|
- filename_trans_datum_t *newdatum = NULL, *otype = NULL;
|
||||||
|
ebitmap_t src_bitmap, tgt_bitmap;
|
||||||
|
ebitmap_node_t *node1, *node2;
|
||||||
|
unsigned int i, j;
|
||||||
|
+ uint32_t otype;
|
||||||
|
struct cil_list_item *c;
|
||||||
|
char *name = DATUM(typetrans->name)->name;
|
||||||
|
|
||||||
|
@@ -1176,22 +1175,14 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru
|
||||||
|
rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
|
||||||
|
if (rc != SEPOL_OK) goto exit;
|
||||||
|
|
||||||
|
- newkey = cil_calloc(1, sizeof(*newkey));
|
||||||
|
- newdatum = cil_calloc(1, sizeof(*newdatum));
|
||||||
|
- newkey->stype = sepol_src->s.value;
|
||||||
|
- newkey->ttype = sepol_tgt->s.value;
|
||||||
|
- newkey->tclass = sepol_obj->s.value;
|
||||||
|
- newkey->name = cil_strdup(name);
|
||||||
|
- newdatum->otype = sepol_result->s.value;
|
||||||
|
-
|
||||||
|
- rc = hashtab_insert(pdb->filename_trans,
|
||||||
|
- (hashtab_key_t)newkey,
|
||||||
|
- newdatum);
|
||||||
|
+ rc = policydb_filetrans_insert(
|
||||||
|
+ pdb, sepol_src->s.value, sepol_tgt->s.value,
|
||||||
|
+ sepol_obj->s.value, name, NULL,
|
||||||
|
+ sepol_result->s.value, &otype
|
||||||
|
+ );
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
if (rc == SEPOL_EEXIST) {
|
||||||
|
- otype = hashtab_search(pdb->filename_trans,
|
||||||
|
- (hashtab_key_t)newkey);
|
||||||
|
- if (newdatum->otype != otype->otype) {
|
||||||
|
+ if (sepol_result->s.value!= otype) {
|
||||||
|
cil_log(CIL_ERR, "Conflicting name type transition rules\n");
|
||||||
|
} else {
|
||||||
|
rc = SEPOL_OK;
|
||||||
|
@@ -1199,9 +1190,6 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru
|
||||||
|
} else {
|
||||||
|
cil_log(CIL_ERR, "Out of memory\n");
|
||||||
|
}
|
||||||
|
- free(newkey->name);
|
||||||
|
- free(newkey);
|
||||||
|
- free(newdatum);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
index 81b63fefbb20..c3180c611c64 100644
|
||||||
|
--- a/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
+++ b/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
@@ -162,15 +162,16 @@ typedef struct role_allow {
|
||||||
|
} role_allow_t;
|
||||||
|
|
||||||
|
/* filename_trans rules */
|
||||||
|
-typedef struct filename_trans {
|
||||||
|
- uint32_t stype;
|
||||||
|
+typedef struct filename_trans_key {
|
||||||
|
uint32_t ttype;
|
||||||
|
uint32_t tclass;
|
||||||
|
char *name;
|
||||||
|
-} filename_trans_t;
|
||||||
|
+} filename_trans_key_t;
|
||||||
|
|
||||||
|
typedef struct filename_trans_datum {
|
||||||
|
- uint32_t otype; /* expected of new object */
|
||||||
|
+ ebitmap_t stypes;
|
||||||
|
+ uint32_t otype;
|
||||||
|
+ struct filename_trans_datum *next;
|
||||||
|
} filename_trans_datum_t;
|
||||||
|
|
||||||
|
/* Type attributes */
|
||||||
|
@@ -591,6 +592,7 @@ typedef struct policydb {
|
||||||
|
|
||||||
|
/* file transitions with the last path component */
|
||||||
|
hashtab_t filename_trans;
|
||||||
|
+ uint32_t filename_trans_count;
|
||||||
|
|
||||||
|
ebitmap_t *type_attr_map;
|
||||||
|
|
||||||
|
@@ -650,6 +652,11 @@ extern int policydb_load_isids(policydb_t * p, sidtab_t * s);
|
||||||
|
|
||||||
|
extern int policydb_sort_ocontexts(policydb_t *p);
|
||||||
|
|
||||||
|
+extern int policydb_filetrans_insert(policydb_t *p, uint32_t stype,
|
||||||
|
+ uint32_t ttype, uint32_t tclass,
|
||||||
|
+ const char *name, char **name_alloc,
|
||||||
|
+ uint32_t otype, uint32_t *present_otype);
|
||||||
|
+
|
||||||
|
/* Deprecated */
|
||||||
|
extern int policydb_context_isvalid(const policydb_t * p,
|
||||||
|
const context_struct_t * c);
|
||||||
|
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||||
|
index 529e1d356a89..19e48c507236 100644
|
||||||
|
--- a/libsepol/src/expand.c
|
||||||
|
+++ b/libsepol/src/expand.c
|
||||||
|
@@ -1371,8 +1371,6 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)
|
||||||
|
static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules)
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
- filename_trans_t key, *new_trans;
|
||||||
|
- filename_trans_datum_t *otype;
|
||||||
|
filename_trans_rule_t *cur_rule;
|
||||||
|
ebitmap_t stypes, ttypes;
|
||||||
|
ebitmap_node_t *snode, *tnode;
|
||||||
|
@@ -1380,7 +1378,7 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r
|
||||||
|
|
||||||
|
cur_rule = rules;
|
||||||
|
while (cur_rule) {
|
||||||
|
- uint32_t mapped_otype;
|
||||||
|
+ uint32_t mapped_otype, present_otype;
|
||||||
|
|
||||||
|
ebitmap_init(&stypes);
|
||||||
|
ebitmap_init(&ttypes);
|
||||||
|
@@ -1401,15 +1399,14 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r
|
||||||
|
|
||||||
|
ebitmap_for_each_positive_bit(&stypes, snode, i) {
|
||||||
|
ebitmap_for_each_positive_bit(&ttypes, tnode, j) {
|
||||||
|
- key.stype = i + 1;
|
||||||
|
- key.ttype = j + 1;
|
||||||
|
- key.tclass = cur_rule->tclass;
|
||||||
|
- key.name = cur_rule->name;
|
||||||
|
- otype = hashtab_search(state->out->filename_trans,
|
||||||
|
- (hashtab_key_t) &key);
|
||||||
|
- if (otype) {
|
||||||
|
+ rc = policydb_filetrans_insert(
|
||||||
|
+ state->out, i + 1, j + 1,
|
||||||
|
+ cur_rule->tclass, cur_rule->name,
|
||||||
|
+ NULL, mapped_otype, &present_otype
|
||||||
|
+ );
|
||||||
|
+ if (rc == SEPOL_EEXIST) {
|
||||||
|
/* duplicate rule, ignore */
|
||||||
|
- if (otype->otype == mapped_otype)
|
||||||
|
+ if (present_otype == mapped_otype)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\": %s vs %s",
|
||||||
|
@@ -1417,44 +1414,11 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r
|
||||||
|
state->out->p_type_val_to_name[j],
|
||||||
|
state->out->p_class_val_to_name[cur_rule->tclass - 1],
|
||||||
|
cur_rule->name,
|
||||||
|
- state->out->p_type_val_to_name[otype->otype - 1],
|
||||||
|
+ state->out->p_type_val_to_name[present_otype - 1],
|
||||||
|
state->out->p_type_val_to_name[mapped_otype - 1]);
|
||||||
|
return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- new_trans = calloc(1, sizeof(*new_trans));
|
||||||
|
- if (!new_trans) {
|
||||||
|
- ERR(state->handle, "Out of memory!");
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- new_trans->name = strdup(cur_rule->name);
|
||||||
|
- if (!new_trans->name) {
|
||||||
|
- ERR(state->handle, "Out of memory!");
|
||||||
|
- free(new_trans);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- new_trans->stype = i + 1;
|
||||||
|
- new_trans->ttype = j + 1;
|
||||||
|
- new_trans->tclass = cur_rule->tclass;
|
||||||
|
-
|
||||||
|
- otype = calloc(1, sizeof(*otype));
|
||||||
|
- if (!otype) {
|
||||||
|
- ERR(state->handle, "Out of memory!");
|
||||||
|
- free(new_trans->name);
|
||||||
|
- free(new_trans);
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- otype->otype = mapped_otype;
|
||||||
|
-
|
||||||
|
- rc = hashtab_insert(state->out->filename_trans,
|
||||||
|
- (hashtab_key_t)new_trans,
|
||||||
|
- otype);
|
||||||
|
- if (rc) {
|
||||||
|
+ } else if (rc < 0) {
|
||||||
|
ERR(state->handle, "Out of memory!");
|
||||||
|
- free(otype);
|
||||||
|
- free(new_trans->name);
|
||||||
|
- free(new_trans);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
|
||||||
|
index 958adc4cfc0a..c247b32f9e75 100644
|
||||||
|
--- a/libsepol/src/kernel_to_cil.c
|
||||||
|
+++ b/libsepol/src/kernel_to_cil.c
|
||||||
|
@@ -1841,21 +1841,35 @@ struct map_filename_trans_args {
|
||||||
|
|
||||||
|
static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg)
|
||||||
|
{
|
||||||
|
- filename_trans_t *ft = (filename_trans_t *)key;
|
||||||
|
+ filename_trans_key_t *ft = (filename_trans_key_t *)key;
|
||||||
|
filename_trans_datum_t *datum = data;
|
||||||
|
struct map_filename_trans_args *map_args = arg;
|
||||||
|
struct policydb *pdb = map_args->pdb;
|
||||||
|
struct strs *strs = map_args->strs;
|
||||||
|
char *src, *tgt, *class, *filename, *new;
|
||||||
|
+ struct ebitmap_node *node;
|
||||||
|
+ uint32_t bit;
|
||||||
|
+ int rc;
|
||||||
|
|
||||||
|
- src = pdb->p_type_val_to_name[ft->stype - 1];
|
||||||
|
tgt = pdb->p_type_val_to_name[ft->ttype - 1];
|
||||||
|
class = pdb->p_class_val_to_name[ft->tclass - 1];
|
||||||
|
filename = ft->name;
|
||||||
|
- new = pdb->p_type_val_to_name[datum->otype - 1];
|
||||||
|
+ do {
|
||||||
|
+ new = pdb->p_type_val_to_name[datum->otype - 1];
|
||||||
|
+
|
||||||
|
+ ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {
|
||||||
|
+ src = pdb->p_type_val_to_name[bit];
|
||||||
|
+ rc = strs_create_and_add(strs,
|
||||||
|
+ "(typetransition %s %s %s %s %s)",
|
||||||
|
+ 5, src, tgt, class, filename, new);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ } while (datum);
|
||||||
|
|
||||||
|
- return strs_create_and_add(strs, "(typetransition %s %s %s %s %s)", 5,
|
||||||
|
- src, tgt, class, filename, new);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_filename_trans_rules_to_cil(FILE *out, struct policydb *pdb)
|
||||||
|
diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c
|
||||||
|
index 7cc91eb3d129..62bf706c1aa0 100644
|
||||||
|
--- a/libsepol/src/kernel_to_conf.c
|
||||||
|
+++ b/libsepol/src/kernel_to_conf.c
|
||||||
|
@@ -1822,21 +1822,35 @@ struct map_filename_trans_args {
|
||||||
|
|
||||||
|
static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg)
|
||||||
|
{
|
||||||
|
- filename_trans_t *ft = (filename_trans_t *)key;
|
||||||
|
+ filename_trans_key_t *ft = (filename_trans_key_t *)key;
|
||||||
|
filename_trans_datum_t *datum = data;
|
||||||
|
struct map_filename_trans_args *map_args = arg;
|
||||||
|
struct policydb *pdb = map_args->pdb;
|
||||||
|
struct strs *strs = map_args->strs;
|
||||||
|
char *src, *tgt, *class, *filename, *new;
|
||||||
|
+ struct ebitmap_node *node;
|
||||||
|
+ uint32_t bit;
|
||||||
|
+ int rc;
|
||||||
|
|
||||||
|
- src = pdb->p_type_val_to_name[ft->stype - 1];
|
||||||
|
tgt = pdb->p_type_val_to_name[ft->ttype - 1];
|
||||||
|
class = pdb->p_class_val_to_name[ft->tclass - 1];
|
||||||
|
filename = ft->name;
|
||||||
|
- new = pdb->p_type_val_to_name[datum->otype - 1];
|
||||||
|
+ do {
|
||||||
|
+ new = pdb->p_type_val_to_name[datum->otype - 1];
|
||||||
|
+
|
||||||
|
+ ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {
|
||||||
|
+ src = pdb->p_type_val_to_name[bit];
|
||||||
|
+ rc = strs_create_and_add(strs,
|
||||||
|
+ "type_transition %s %s:%s %s \"%s\";",
|
||||||
|
+ 5, src, tgt, class, new, filename);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ } while (datum);
|
||||||
|
|
||||||
|
- return strs_create_and_add(strs, "type_transition %s %s:%s %s \"%s\";", 5,
|
||||||
|
- src, tgt, class, new, filename);
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_filename_trans_rules_to_conf(FILE *out, struct policydb *pdb)
|
||||||
|
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||||
|
index 3992ea56f092..0b98d50b8096 100644
|
||||||
|
--- a/libsepol/src/policydb.c
|
||||||
|
+++ b/libsepol/src/policydb.c
|
||||||
|
@@ -789,12 +789,12 @@ partial_name_hash(unsigned long c, unsigned long prevhash)
|
||||||
|
|
||||||
|
static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)
|
||||||
|
{
|
||||||
|
- const struct filename_trans *ft = (const struct filename_trans *)k;
|
||||||
|
+ const filename_trans_key_t *ft = (const filename_trans_key_t *)k;
|
||||||
|
unsigned long hash;
|
||||||
|
unsigned int byte_num;
|
||||||
|
unsigned char focus;
|
||||||
|
|
||||||
|
- hash = ft->stype ^ ft->ttype ^ ft->tclass;
|
||||||
|
+ hash = ft->ttype ^ ft->tclass;
|
||||||
|
|
||||||
|
byte_num = 0;
|
||||||
|
while ((focus = ft->name[byte_num++]))
|
||||||
|
@@ -805,14 +805,10 @@ static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)
|
||||||
|
static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
|
||||||
|
const_hashtab_key_t k1, const_hashtab_key_t k2)
|
||||||
|
{
|
||||||
|
- const struct filename_trans *ft1 = (const struct filename_trans *)k1;
|
||||||
|
- const struct filename_trans *ft2 = (const struct filename_trans *)k2;
|
||||||
|
+ const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1;
|
||||||
|
+ const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
- v = ft1->stype - ft2->stype;
|
||||||
|
- if (v)
|
||||||
|
- return v;
|
||||||
|
-
|
||||||
|
v = ft1->ttype - ft2->ttype;
|
||||||
|
if (v)
|
||||||
|
return v;
|
||||||
|
@@ -1409,9 +1405,12 @@ common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
|
||||||
|
static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum,
|
||||||
|
void *p __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
- struct filename_trans *ft = (struct filename_trans *)key;
|
||||||
|
+ filename_trans_key_t *ft = (filename_trans_key_t *)key;
|
||||||
|
+ filename_trans_datum_t *fd = datum;
|
||||||
|
+
|
||||||
|
free(ft->name);
|
||||||
|
free(key);
|
||||||
|
+ ebitmap_destroy(&fd->stypes);
|
||||||
|
free(datum);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -2595,12 +2594,85 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,
|
||||||
|
+ uint32_t tclass, const char *name,
|
||||||
|
+ char **name_alloc, uint32_t otype,
|
||||||
|
+ uint32_t *present_otype)
|
||||||
|
+{
|
||||||
|
+ filename_trans_key_t *ft, key;
|
||||||
|
+ filename_trans_datum_t *datum, *last;
|
||||||
|
+
|
||||||
|
+ key.ttype = ttype;
|
||||||
|
+ key.tclass = tclass;
|
||||||
|
+ key.name = (char *)name;
|
||||||
|
+
|
||||||
|
+ last = NULL;
|
||||||
|
+ datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key);
|
||||||
|
+ while (datum) {
|
||||||
|
+ if (ebitmap_get_bit(&datum->stypes, stype - 1)) {
|
||||||
|
+ if (present_otype)
|
||||||
|
+ *present_otype = datum->otype;
|
||||||
|
+ return SEPOL_EEXIST;
|
||||||
|
+ }
|
||||||
|
+ if (datum->otype == otype)
|
||||||
|
+ break;
|
||||||
|
+ last = datum;
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ }
|
||||||
|
+ if (!datum) {
|
||||||
|
+ datum = malloc(sizeof(*datum));
|
||||||
|
+ if (!datum)
|
||||||
|
+ return SEPOL_ENOMEM;
|
||||||
|
+
|
||||||
|
+ ebitmap_init(&datum->stypes);
|
||||||
|
+ datum->otype = otype;
|
||||||
|
+ datum->next = NULL;
|
||||||
|
+
|
||||||
|
+ if (last) {
|
||||||
|
+ last->next = datum;
|
||||||
|
+ } else {
|
||||||
|
+ char *name_dup;
|
||||||
|
+
|
||||||
|
+ if (name_alloc) {
|
||||||
|
+ name_dup = *name_alloc;
|
||||||
|
+ *name_alloc = NULL;
|
||||||
|
+ } else {
|
||||||
|
+ name_dup = strdup(name);
|
||||||
|
+ if (!name_dup) {
|
||||||
|
+ free(datum);
|
||||||
|
+ return SEPOL_ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ft = malloc(sizeof(*ft));
|
||||||
|
+ if (!ft) {
|
||||||
|
+ free(name_dup);
|
||||||
|
+ free(datum);
|
||||||
|
+ return SEPOL_ENOMEM;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ft->ttype = ttype;
|
||||||
|
+ ft->tclass = tclass;
|
||||||
|
+ ft->name = name_dup;
|
||||||
|
+
|
||||||
|
+ if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
|
||||||
|
+ (hashtab_datum_t)datum)) {
|
||||||
|
+ free(name_dup);
|
||||||
|
+ free(datum);
|
||||||
|
+ free(ft);
|
||||||
|
+ return SEPOL_ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ p->filename_trans_count++;
|
||||||
|
+ return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
- uint32_t buf[4], nel, len;
|
||||||
|
- filename_trans_t *ft;
|
||||||
|
- filename_trans_datum_t *otype;
|
||||||
|
+ uint32_t buf[4], nel, len, stype, ttype, tclass, otype;
|
||||||
|
int rc;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
@@ -2610,16 +2682,8 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
nel = le32_to_cpu(buf[0]);
|
||||||
|
|
||||||
|
for (i = 0; i < nel; i++) {
|
||||||
|
- ft = NULL;
|
||||||
|
- otype = NULL;
|
||||||
|
name = NULL;
|
||||||
|
|
||||||
|
- ft = calloc(1, sizeof(*ft));
|
||||||
|
- if (!ft)
|
||||||
|
- goto err;
|
||||||
|
- otype = calloc(1, sizeof(*otype));
|
||||||
|
- if (!otype)
|
||||||
|
- goto err;
|
||||||
|
rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
if (rc < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -2631,8 +2695,6 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
if (!name)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- ft->name = name;
|
||||||
|
-
|
||||||
|
rc = next_entry(name, fp, len);
|
||||||
|
if (rc < 0)
|
||||||
|
goto err;
|
||||||
|
@@ -2641,13 +2703,13 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
if (rc < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- ft->stype = le32_to_cpu(buf[0]);
|
||||||
|
- ft->ttype = le32_to_cpu(buf[1]);
|
||||||
|
- ft->tclass = le32_to_cpu(buf[2]);
|
||||||
|
- otype->otype = le32_to_cpu(buf[3]);
|
||||||
|
+ stype = le32_to_cpu(buf[0]);
|
||||||
|
+ ttype = le32_to_cpu(buf[1]);
|
||||||
|
+ tclass = le32_to_cpu(buf[2]);
|
||||||
|
+ otype = le32_to_cpu(buf[3]);
|
||||||
|
|
||||||
|
- rc = hashtab_insert(p->filename_trans, (hashtab_key_t) ft,
|
||||||
|
- otype);
|
||||||
|
+ rc = policydb_filetrans_insert(p, stype, ttype, tclass, name,
|
||||||
|
+ &name, otype, NULL);
|
||||||
|
if (rc) {
|
||||||
|
if (rc != SEPOL_EEXIST)
|
||||||
|
goto err;
|
||||||
|
@@ -2657,16 +2719,11 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
* compatibility, do not reject such policies, just
|
||||||
|
* ignore the duplicate.
|
||||||
|
*/
|
||||||
|
- free(ft);
|
||||||
|
- free(name);
|
||||||
|
- free(otype);
|
||||||
|
- /* continue, ignoring this one */
|
||||||
|
}
|
||||||
|
+ free(name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
- free(ft);
|
||||||
|
- free(otype);
|
||||||
|
free(name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
|
||||||
|
index 1fd6a16a248b..d3aee8d5bf22 100644
|
||||||
|
--- a/libsepol/src/write.c
|
||||||
|
+++ b/libsepol/src/write.c
|
||||||
|
@@ -571,44 +571,50 @@ static int role_allow_write(role_allow_t * r, struct policy_file *fp)
|
||||||
|
|
||||||
|
static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)
|
||||||
|
{
|
||||||
|
- uint32_t buf[4];
|
||||||
|
+ uint32_t bit, buf[4];
|
||||||
|
size_t items, len;
|
||||||
|
- struct filename_trans *ft = (struct filename_trans *)key;
|
||||||
|
- struct filename_trans_datum *otype = data;
|
||||||
|
+ filename_trans_key_t *ft = (filename_trans_key_t *)key;
|
||||||
|
+ filename_trans_datum_t *datum = data;
|
||||||
|
+ ebitmap_node_t *node;
|
||||||
|
void *fp = ptr;
|
||||||
|
|
||||||
|
len = strlen(ft->name);
|
||||||
|
- buf[0] = cpu_to_le32(len);
|
||||||
|
- items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
- if (items != 1)
|
||||||
|
- return POLICYDB_ERROR;
|
||||||
|
+ do {
|
||||||
|
+ ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {
|
||||||
|
+ buf[0] = cpu_to_le32(len);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
+ if (items != 1)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
|
||||||
|
- items = put_entry(ft->name, sizeof(char), len, fp);
|
||||||
|
- if (items != len)
|
||||||
|
- return POLICYDB_ERROR;
|
||||||
|
+ items = put_entry(ft->name, sizeof(char), len, fp);
|
||||||
|
+ if (items != len)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
|
||||||
|
- buf[0] = cpu_to_le32(ft->stype);
|
||||||
|
- buf[1] = cpu_to_le32(ft->ttype);
|
||||||
|
- buf[2] = cpu_to_le32(ft->tclass);
|
||||||
|
- buf[3] = cpu_to_le32(otype->otype);
|
||||||
|
- items = put_entry(buf, sizeof(uint32_t), 4, fp);
|
||||||
|
- if (items != 4)
|
||||||
|
- return POLICYDB_ERROR;
|
||||||
|
+ buf[0] = cpu_to_le32(bit + 1);
|
||||||
|
+ buf[1] = cpu_to_le32(ft->ttype);
|
||||||
|
+ buf[2] = cpu_to_le32(ft->tclass);
|
||||||
|
+ buf[3] = cpu_to_le32(datum->otype);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 4, fp);
|
||||||
|
+ if (items != 4)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ } while (datum);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int filename_trans_write(struct policydb *p, void *fp)
|
||||||
|
{
|
||||||
|
- size_t nel, items;
|
||||||
|
+ size_t items;
|
||||||
|
uint32_t buf[1];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- nel = p->filename_trans->nel;
|
||||||
|
- buf[0] = cpu_to_le32(nel);
|
||||||
|
+ buf[0] = cpu_to_le32(p->filename_trans_count);
|
||||||
|
items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
if (items != 1)
|
||||||
|
return POLICYDB_ERROR;
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
394
0002-libsepol-implement-POLICYDB_VERSION_COMP_FTRANS.patch
Normal file
394
0002-libsepol-implement-POLICYDB_VERSION_COMP_FTRANS.patch
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
From 8206b8cb00392aab358f4eeae38f98850438085c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
Date: Fri, 31 Jul 2020 13:10:35 +0200
|
||||||
|
Subject: [PATCH] libsepol: implement POLICYDB_VERSION_COMP_FTRANS
|
||||||
|
|
||||||
|
Implement a new, more space-efficient form of storing filename
|
||||||
|
transitions in the binary policy. The internal structures have already
|
||||||
|
been converted to this new representation; this patch just implements
|
||||||
|
reading/writing an equivalent representation from/to the binary policy.
|
||||||
|
|
||||||
|
This new format reduces the size of Fedora policy from 7.6 MB to only
|
||||||
|
3.3 MB (with policy optimization enabled in both cases). With the
|
||||||
|
unconfined module disabled, the size is reduced from 3.3 MB to 2.4 MB.
|
||||||
|
|
||||||
|
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/include/sepol/policydb/policydb.h | 3 +-
|
||||||
|
libsepol/src/policydb.c | 209 +++++++++++++++++----
|
||||||
|
libsepol/src/write.c | 73 ++++++-
|
||||||
|
3 files changed, 242 insertions(+), 43 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
index c3180c611c64..9ef43abc2f12 100644
|
||||||
|
--- a/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
+++ b/libsepol/include/sepol/policydb/policydb.h
|
||||||
|
@@ -755,10 +755,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);
|
||||||
|
#define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */
|
||||||
|
#define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */
|
||||||
|
#define POLICYDB_VERSION_GLBLUB 32
|
||||||
|
+#define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */
|
||||||
|
|
||||||
|
/* Range of policy versions we understand*/
|
||||||
|
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
|
||||||
|
-#define POLICYDB_VERSION_MAX POLICYDB_VERSION_GLBLUB
|
||||||
|
+#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS
|
||||||
|
|
||||||
|
/* Module versions and specific changes*/
|
||||||
|
#define MOD_POLICYDB_VERSION_BASE 4
|
||||||
|
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
|
||||||
|
index 0b98d50b8096..ce8f3ad77005 100644
|
||||||
|
--- a/libsepol/src/policydb.c
|
||||||
|
+++ b/libsepol/src/policydb.c
|
||||||
|
@@ -200,6 +200,13 @@ static struct policydb_compat_info policydb_compat[] = {
|
||||||
|
.ocon_num = OCON_IBENDPORT + 1,
|
||||||
|
.target_platform = SEPOL_TARGET_SELINUX,
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .type = POLICY_KERN,
|
||||||
|
+ .version = POLICYDB_VERSION_COMP_FTRANS,
|
||||||
|
+ .sym_num = SYM_NUM,
|
||||||
|
+ .ocon_num = OCON_IBENDPORT + 1,
|
||||||
|
+ .target_platform = SEPOL_TARGET_SELINUX,
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
.type = POLICY_BASE,
|
||||||
|
.version = MOD_POLICYDB_VERSION_BASE,
|
||||||
|
@@ -2669,65 +2676,201 @@ int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,
|
||||||
|
return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
+static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp)
|
||||||
|
{
|
||||||
|
- unsigned int i;
|
||||||
|
- uint32_t buf[4], nel, len, stype, ttype, tclass, otype;
|
||||||
|
+ uint32_t buf[4], len, stype, ttype, tclass, otype;
|
||||||
|
+ char *name = NULL;
|
||||||
|
int rc;
|
||||||
|
- char *name;
|
||||||
|
|
||||||
|
rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
- nel = le32_to_cpu(buf[0]);
|
||||||
|
+ len = le32_to_cpu(buf[0]);
|
||||||
|
+ if (zero_or_saturated(len))
|
||||||
|
+ return -1;
|
||||||
|
|
||||||
|
- for (i = 0; i < nel; i++) {
|
||||||
|
- name = NULL;
|
||||||
|
+ name = calloc(len + 1, sizeof(*name));
|
||||||
|
+ if (!name)
|
||||||
|
+ return -1;
|
||||||
|
|
||||||
|
- rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
- if (rc < 0)
|
||||||
|
- goto err;
|
||||||
|
- len = le32_to_cpu(buf[0]);
|
||||||
|
- if (zero_or_saturated(len))
|
||||||
|
+ rc = next_entry(name, fp, len);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ stype = le32_to_cpu(buf[0]);
|
||||||
|
+ ttype = le32_to_cpu(buf[1]);
|
||||||
|
+ tclass = le32_to_cpu(buf[2]);
|
||||||
|
+ otype = le32_to_cpu(buf[3]);
|
||||||
|
+
|
||||||
|
+ rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name,
|
||||||
|
+ otype, NULL);
|
||||||
|
+ if (rc) {
|
||||||
|
+ if (rc != SEPOL_EEXIST)
|
||||||
|
goto err;
|
||||||
|
+ /*
|
||||||
|
+ * Some old policies were wrongly generated with
|
||||||
|
+ * duplicate filename transition rules. For backward
|
||||||
|
+ * compatibility, do not reject such policies, just
|
||||||
|
+ * ignore the duplicate.
|
||||||
|
+ */
|
||||||
|
+ }
|
||||||
|
+ free(name);
|
||||||
|
+ return 0;
|
||||||
|
+err:
|
||||||
|
+ free(name);
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int filename_trans_check_datum(filename_trans_datum_t *datum)
|
||||||
|
+{
|
||||||
|
+ ebitmap_t stypes, otypes;
|
||||||
|
+ int rc = -1;
|
||||||
|
+
|
||||||
|
+ ebitmap_init(&stypes);
|
||||||
|
+ ebitmap_init(&otypes);
|
||||||
|
+
|
||||||
|
+ while (datum) {
|
||||||
|
+ if (ebitmap_get_bit(&otypes, datum->otype))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (ebitmap_set_bit(&otypes, datum->otype, 1))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ if (ebitmap_match_any(&stypes, &datum->stypes))
|
||||||
|
+ goto out;
|
||||||
|
|
||||||
|
- name = calloc(len + 1, sizeof(*name));
|
||||||
|
- if (!name)
|
||||||
|
+ if (ebitmap_union(&stypes, &datum->stypes))
|
||||||
|
+ goto out;
|
||||||
|
+
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ }
|
||||||
|
+ rc = 0;
|
||||||
|
+out:
|
||||||
|
+ ebitmap_destroy(&stypes);
|
||||||
|
+ ebitmap_destroy(&otypes);
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int filename_trans_read_one(policydb_t *p, struct policy_file *fp)
|
||||||
|
+{
|
||||||
|
+ filename_trans_key_t *ft = NULL;
|
||||||
|
+ filename_trans_datum_t **dst, *datum, *first = NULL;
|
||||||
|
+ unsigned int i;
|
||||||
|
+ uint32_t buf[3], len, ttype, tclass, ndatum;
|
||||||
|
+ char *name = NULL;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ len = le32_to_cpu(buf[0]);
|
||||||
|
+ if (zero_or_saturated(len))
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ name = calloc(len + 1, sizeof(*name));
|
||||||
|
+ if (!name)
|
||||||
|
+ return -1;
|
||||||
|
+
|
||||||
|
+ rc = next_entry(name, fp, len);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ ttype = le32_to_cpu(buf[0]);
|
||||||
|
+ tclass = le32_to_cpu(buf[1]);
|
||||||
|
+ ndatum = le32_to_cpu(buf[2]);
|
||||||
|
+ if (ndatum == 0)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ dst = &first;
|
||||||
|
+ for (i = 0; i < ndatum; i++) {
|
||||||
|
+ datum = malloc(sizeof(*datum));
|
||||||
|
+ if (!datum)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- rc = next_entry(name, fp, len);
|
||||||
|
+ *dst = datum;
|
||||||
|
+
|
||||||
|
+ /* ebitmap_read() will at least init the bitmap */
|
||||||
|
+ rc = ebitmap_read(&datum->stypes, fp);
|
||||||
|
if (rc < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
|
||||||
|
+ rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
if (rc < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
- stype = le32_to_cpu(buf[0]);
|
||||||
|
- ttype = le32_to_cpu(buf[1]);
|
||||||
|
- tclass = le32_to_cpu(buf[2]);
|
||||||
|
- otype = le32_to_cpu(buf[3]);
|
||||||
|
+ datum->otype = le32_to_cpu(buf[0]);
|
||||||
|
|
||||||
|
- rc = policydb_filetrans_insert(p, stype, ttype, tclass, name,
|
||||||
|
- &name, otype, NULL);
|
||||||
|
- if (rc) {
|
||||||
|
- if (rc != SEPOL_EEXIST)
|
||||||
|
- goto err;
|
||||||
|
- /*
|
||||||
|
- * Some old policies were wrongly generated with
|
||||||
|
- * duplicate filename transition rules. For backward
|
||||||
|
- * compatibility, do not reject such policies, just
|
||||||
|
- * ignore the duplicate.
|
||||||
|
- */
|
||||||
|
- }
|
||||||
|
- free(name);
|
||||||
|
+ p->filename_trans_count += ebitmap_cardinality(&datum->stypes);
|
||||||
|
+
|
||||||
|
+ dst = &datum->next;
|
||||||
|
}
|
||||||
|
+ *dst = NULL;
|
||||||
|
+
|
||||||
|
+ if (ndatum > 1 && filename_trans_check_datum(first))
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ ft = malloc(sizeof(*ft));
|
||||||
|
+ if (!ft)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
+ ft->ttype = ttype;
|
||||||
|
+ ft->tclass = tclass;
|
||||||
|
+ ft->name = name;
|
||||||
|
+
|
||||||
|
+ rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
|
||||||
|
+ (hashtab_datum_t)first);
|
||||||
|
+ if (rc)
|
||||||
|
+ goto err;
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
+ free(ft);
|
||||||
|
free(name);
|
||||||
|
+ while (first) {
|
||||||
|
+ datum = first;
|
||||||
|
+ first = first->next;
|
||||||
|
+
|
||||||
|
+ ebitmap_destroy(&datum->stypes);
|
||||||
|
+ free(datum);
|
||||||
|
+ }
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int filename_trans_read(policydb_t *p, struct policy_file *fp)
|
||||||
|
+{
|
||||||
|
+ unsigned int i;
|
||||||
|
+ uint32_t buf[1], nel;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ rc = next_entry(buf, fp, sizeof(uint32_t));
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ nel = le32_to_cpu(buf[0]);
|
||||||
|
+
|
||||||
|
+ if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
|
||||||
|
+ for (i = 0; i < nel; i++) {
|
||||||
|
+ rc = filename_trans_read_one_compat(p, fp);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ for (i = 0; i < nel; i++) {
|
||||||
|
+ rc = filename_trans_read_one(p, fp);
|
||||||
|
+ if (rc < 0)
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int ocontext_read_xen(struct policydb_compat_info *info,
|
||||||
|
policydb_t *p, struct policy_file *fp)
|
||||||
|
{
|
||||||
|
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
|
||||||
|
index d3aee8d5bf22..84bcaf3f57ca 100644
|
||||||
|
--- a/libsepol/src/write.c
|
||||||
|
+++ b/libsepol/src/write.c
|
||||||
|
@@ -569,7 +569,7 @@ static int role_allow_write(role_allow_t * r, struct policy_file *fp)
|
||||||
|
return POLICYDB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)
|
||||||
|
+static int filename_write_one_compat(hashtab_key_t key, void *data, void *ptr)
|
||||||
|
{
|
||||||
|
uint32_t bit, buf[4];
|
||||||
|
size_t items, len;
|
||||||
|
@@ -605,6 +605,54 @@ static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int filename_write_one(hashtab_key_t key, void *data, void *ptr)
|
||||||
|
+{
|
||||||
|
+ uint32_t buf[3];
|
||||||
|
+ size_t items, len, ndatum;
|
||||||
|
+ filename_trans_key_t *ft = (filename_trans_key_t *)key;
|
||||||
|
+ filename_trans_datum_t *datum;
|
||||||
|
+ void *fp = ptr;
|
||||||
|
+
|
||||||
|
+ len = strlen(ft->name);
|
||||||
|
+ buf[0] = cpu_to_le32(len);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
+ if (items != 1)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+
|
||||||
|
+ items = put_entry(ft->name, sizeof(char), len, fp);
|
||||||
|
+ if (items != len)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+
|
||||||
|
+ ndatum = 0;
|
||||||
|
+ datum = data;
|
||||||
|
+ do {
|
||||||
|
+ ndatum++;
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ } while (datum);
|
||||||
|
+
|
||||||
|
+ buf[0] = cpu_to_le32(ft->ttype);
|
||||||
|
+ buf[1] = cpu_to_le32(ft->tclass);
|
||||||
|
+ buf[2] = cpu_to_le32(ndatum);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 3, fp);
|
||||||
|
+ if (items != 3)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+
|
||||||
|
+ datum = data;
|
||||||
|
+ do {
|
||||||
|
+ if (ebitmap_write(&datum->stypes, fp))
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+
|
||||||
|
+ buf[0] = cpu_to_le32(datum->otype);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
+ if (items != 1)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
+
|
||||||
|
+ datum = datum->next;
|
||||||
|
+ } while (datum);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int filename_trans_write(struct policydb *p, void *fp)
|
||||||
|
{
|
||||||
|
size_t items;
|
||||||
|
@@ -614,16 +662,23 @@ static int filename_trans_write(struct policydb *p, void *fp)
|
||||||
|
if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- buf[0] = cpu_to_le32(p->filename_trans_count);
|
||||||
|
- items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
- if (items != 1)
|
||||||
|
- return POLICYDB_ERROR;
|
||||||
|
+ if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
|
||||||
|
+ buf[0] = cpu_to_le32(p->filename_trans_count);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
+ if (items != 1)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
|
||||||
|
- rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
|
||||||
|
- if (rc)
|
||||||
|
- return rc;
|
||||||
|
+ rc = hashtab_map(p->filename_trans, filename_write_one_compat,
|
||||||
|
+ fp);
|
||||||
|
+ } else {
|
||||||
|
+ buf[0] = cpu_to_le32(p->filename_trans->nel);
|
||||||
|
+ items = put_entry(buf, sizeof(uint32_t), 1, fp);
|
||||||
|
+ if (items != 1)
|
||||||
|
+ return POLICYDB_ERROR;
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+ rc = hashtab_map(p->filename_trans, filename_write_one, fp);
|
||||||
|
+ }
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int role_set_write(role_set_t * x, struct policy_file *fp)
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
172
0003-libsepol-cil-Validate-constraint-expressions-before-.patch
Normal file
172
0003-libsepol-cil-Validate-constraint-expressions-before-.patch
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
From 685f577aa01ed378374cde9c0105b19c18ca7c07 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
Date: Wed, 9 Sep 2020 16:57:12 -0400
|
||||||
|
Subject: [PATCH] libsepol/cil: Validate constraint expressions before adding
|
||||||
|
to binary policy
|
||||||
|
|
||||||
|
CIL was not correctly determining the depth of constraint expressions
|
||||||
|
which prevented it from giving an error when the max depth was exceeded.
|
||||||
|
This allowed invalid policy binaries with constraint expressions exceeding
|
||||||
|
the max depth to be created.
|
||||||
|
|
||||||
|
Validate the constraint expression using the same logic that is used
|
||||||
|
when reading the binary policy. This includes checking the depth of the
|
||||||
|
the expression.
|
||||||
|
|
||||||
|
Reported-by: Jonathan Hettwer <j2468h@gmail.com>
|
||||||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||||
|
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_binary.c | 48 ++++++++++++++++++++++++++++++++
|
||||||
|
libsepol/cil/src/cil_build_ast.c | 20 ++++---------
|
||||||
|
2 files changed, 53 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||||
|
index 7726685809af..c8e41f09e53f 100644
|
||||||
|
--- a/libsepol/cil/src/cil_binary.c
|
||||||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||||||
|
@@ -2713,6 +2713,49 @@ int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db,
|
||||||
|
return SEPOL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int __cil_validate_constrain_expr(constraint_expr_t *sepol_expr)
|
||||||
|
+{
|
||||||
|
+ constraint_expr_t *e;
|
||||||
|
+ int depth = -1;
|
||||||
|
+
|
||||||
|
+ for (e = sepol_expr; e != NULL; e = e->next) {
|
||||||
|
+ switch (e->expr_type) {
|
||||||
|
+ case CEXPR_NOT:
|
||||||
|
+ if (depth < 0) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid constraint expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case CEXPR_AND:
|
||||||
|
+ case CEXPR_OR:
|
||||||
|
+ if (depth < 1) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid constraint expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ depth--;
|
||||||
|
+ break;
|
||||||
|
+ case CEXPR_ATTR:
|
||||||
|
+ case CEXPR_NAMES:
|
||||||
|
+ if (depth == (CEXPR_MAXDEPTH - 1)) {
|
||||||
|
+ cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ depth++;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ cil_log(CIL_ERR,"Invalid constraint expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (depth != 0) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid constraint expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SEPOL_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
@@ -2736,6 +2779,11 @@ int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, s
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rc = __cil_validate_constrain_expr(sepol_expr);
|
||||||
|
+ if (rc != SEPOL_OK) {
|
||||||
|
+ goto exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
sepol_constrain->expr = sepol_expr;
|
||||||
|
sepol_constrain->next = sepol_class->constraints;
|
||||||
|
sepol_class->constraints = sepol_constrain;
|
||||||
|
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
index 60ecaaff3060..870c6923b4de 100644
|
||||||
|
--- a/libsepol/cil/src/cil_build_ast.c
|
||||||
|
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
@@ -2738,7 +2738,7 @@ exit:
|
||||||
|
return SEPOL_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int *depth)
|
||||||
|
+static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
enum cil_flavor op;
|
||||||
|
@@ -2750,12 +2750,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (*depth > CEXPR_MAXDEPTH) {
|
||||||
|
- cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH);
|
||||||
|
- rc = SEPOL_ERR;
|
||||||
|
- goto exit;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
op = __cil_get_constraint_operator_flavor(current->data);
|
||||||
|
|
||||||
|
rc = cil_verify_constraint_expr_syntax(current, op);
|
||||||
|
@@ -2769,14 +2763,13 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl
|
||||||
|
case CIL_CONS_DOM:
|
||||||
|
case CIL_CONS_DOMBY:
|
||||||
|
case CIL_CONS_INCOMP:
|
||||||
|
- (*depth)++;
|
||||||
|
rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CIL_NOT:
|
||||||
|
- rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth);
|
||||||
|
+ rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
@@ -2785,11 +2778,11 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl
|
||||||
|
cil_list_append(*expr, CIL_LIST, lexpr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
- rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth);
|
||||||
|
+ rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
- rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth);
|
||||||
|
+ rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
cil_list_destroy(&lexpr, CIL_TRUE);
|
||||||
|
goto exit;
|
||||||
|
@@ -2801,8 +2794,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (*depth)--;
|
||||||
|
-
|
||||||
|
return SEPOL_OK;
|
||||||
|
exit:
|
||||||
|
|
||||||
|
@@ -2812,13 +2803,12 @@ exit:
|
||||||
|
int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
- int depth = 0;
|
||||||
|
|
||||||
|
if (current->cl_head == NULL) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth);
|
||||||
|
+ rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
172
0004-libsepol-cil-Validate-conditional-expressions-before.patch
Normal file
172
0004-libsepol-cil-Validate-conditional-expressions-before.patch
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
From 734e4beb55cb53d3370201838caa4850b2a6d276 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
Date: Wed, 9 Sep 2020 16:57:02 -0400
|
||||||
|
Subject: [PATCH] libsepol/cil: Validate conditional expressions before adding
|
||||||
|
to binary policy
|
||||||
|
|
||||||
|
CIL was not correctly determining the depth of conditional expressions
|
||||||
|
which prevented it from giving an error when the max depth was exceeded.
|
||||||
|
This allowed invalid policy binaries to be created.
|
||||||
|
|
||||||
|
Validate the conditional expression using the same logic that is used
|
||||||
|
when evaluating a conditional expression. This includes checking the
|
||||||
|
depth of the expression.
|
||||||
|
|
||||||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||||
|
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_binary.c | 50 ++++++++++++++++++++++++++++++++
|
||||||
|
libsepol/cil/src/cil_build_ast.c | 26 +++++------------
|
||||||
|
2 files changed, 57 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||||
|
index c8e41f09e53f..50cc7f757c62 100644
|
||||||
|
--- a/libsepol/cil/src/cil_binary.c
|
||||||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||||||
|
@@ -2176,6 +2176,51 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e
|
||||||
|
return SEPOL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int __cil_validate_cond_expr(cond_expr_t *cond_expr)
|
||||||
|
+{
|
||||||
|
+ cond_expr_t *e;
|
||||||
|
+ int depth = -1;
|
||||||
|
+
|
||||||
|
+ for (e = cond_expr; e != NULL; e = e->next) {
|
||||||
|
+ switch (e->expr_type) {
|
||||||
|
+ case COND_BOOL:
|
||||||
|
+ if (depth == (COND_EXPR_MAXDEPTH - 1)) {
|
||||||
|
+ cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ depth++;
|
||||||
|
+ break;
|
||||||
|
+ case COND_NOT:
|
||||||
|
+ if (depth < 0) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ case COND_OR:
|
||||||
|
+ case COND_AND:
|
||||||
|
+ case COND_XOR:
|
||||||
|
+ case COND_EQ:
|
||||||
|
+ case COND_NEQ:
|
||||||
|
+ if (depth < 1) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ depth--;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (depth != 0) {
|
||||||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SEPOL_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
@@ -2204,6 +2249,11 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ rc = __cil_validate_cond_expr(tmp_cond->expr);
|
||||||
|
+ if (rc != SEPOL_OK) {
|
||||||
|
+ goto exit;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
tmp_cond->true_list = &tmp_cl;
|
||||||
|
|
||||||
|
rc = cond_normalize_expr(pdb, tmp_cond);
|
||||||
|
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
index 870c6923b4de..3aabb05ec534 100644
|
||||||
|
--- a/libsepol/cil/src/cil_build_ast.c
|
||||||
|
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
@@ -2548,18 +2548,13 @@ static enum cil_flavor __cil_get_expr_operator_flavor(const char *op)
|
||||||
|
else return CIL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth);
|
||||||
|
+static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr);
|
||||||
|
|
||||||
|
-static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)
|
||||||
|
+static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
enum cil_flavor op;
|
||||||
|
|
||||||
|
- if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) {
|
||||||
|
- cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH);
|
||||||
|
- goto exit;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
op = __cil_get_expr_operator_flavor(current->data);
|
||||||
|
|
||||||
|
rc = cil_verify_expr_syntax(current, op, flavor);
|
||||||
|
@@ -2572,26 +2567,20 @@ static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (op == CIL_NONE || op == CIL_ALL) {
|
||||||
|
- (*depth)++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
for (;current != NULL; current = current->next) {
|
||||||
|
- rc = __cil_fill_expr(current, flavor, expr, depth);
|
||||||
|
+ rc = __cil_fill_expr(current, flavor, expr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (*depth)--;
|
||||||
|
-
|
||||||
|
return SEPOL_OK;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)
|
||||||
|
+static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
|
||||||
|
@@ -2605,7 +2594,7 @@ static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor
|
||||||
|
} else {
|
||||||
|
struct cil_list *sub_expr;
|
||||||
|
cil_list_init(&sub_expr, flavor);
|
||||||
|
- rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr, depth);
|
||||||
|
+ rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
cil_list_destroy(&sub_expr, CIL_TRUE);
|
||||||
|
goto exit;
|
||||||
|
@@ -2623,14 +2612,13 @@ exit:
|
||||||
|
int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
- int depth = 0;
|
||||||
|
|
||||||
|
cil_list_init(expr, flavor);
|
||||||
|
|
||||||
|
if (current->cl_head == NULL) {
|
||||||
|
- rc = __cil_fill_expr(current, flavor, *expr, &depth);
|
||||||
|
+ rc = __cil_fill_expr(current, flavor, *expr);
|
||||||
|
} else {
|
||||||
|
- rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth);
|
||||||
|
+ rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From a152653b9a43fe2c776d239efc2d46d336555bc8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
Date: Tue, 15 Sep 2020 14:48:06 -0400
|
||||||
|
Subject: [PATCH] libsepol/cil: Fix neverallow checking involving classmaps
|
||||||
|
|
||||||
|
When classmaps used in a neverallow were being expanded during CIL
|
||||||
|
neverallow checking, an empty classmapping in the list of
|
||||||
|
classmappings for a classmap would cause the classmap expansion to
|
||||||
|
stop and the rest of the classmapping of the classmap to be ignored.
|
||||||
|
This would mean that not all of the classes and permissions associated
|
||||||
|
with the classmap would be used to check for a neverallow violation.
|
||||||
|
|
||||||
|
Do not end the expansion of a classmap when one classmapping is empty.
|
||||||
|
|
||||||
|
Reported-by: Jonathan Hettwer <j2468h@gmail.com>
|
||||||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||||
|
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_binary.c | 14 ++++++--------
|
||||||
|
1 file changed, 6 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||||
|
index 50cc7f757c62..36720eda4549 100644
|
||||||
|
--- a/libsepol/cil/src/cil_binary.c
|
||||||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||||||
|
@@ -4363,15 +4363,13 @@ static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *cla
|
||||||
|
|
||||||
|
rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
|
||||||
|
if (rc != SEPOL_OK) goto exit;
|
||||||
|
- if (data == 0) {
|
||||||
|
- /* No permissions */
|
||||||
|
- return SEPOL_OK;
|
||||||
|
+ if (data != 0) { /* Only add if there are permissions */
|
||||||
|
+ cpn = cil_malloc(sizeof(class_perm_node_t));
|
||||||
|
+ cpn->tclass = sepol_class->s.value;
|
||||||
|
+ cpn->data = data;
|
||||||
|
+ cpn->next = *sepol_class_perms;
|
||||||
|
+ *sepol_class_perms = cpn;
|
||||||
|
}
|
||||||
|
- cpn = cil_malloc(sizeof(class_perm_node_t));
|
||||||
|
- cpn->tclass = sepol_class->s.value;
|
||||||
|
- cpn->data = data;
|
||||||
|
- cpn->next = *sepol_class_perms;
|
||||||
|
- *sepol_class_perms = cpn;
|
||||||
|
} else { /* MAP */
|
||||||
|
struct cil_list_item *j = NULL;
|
||||||
|
cil_list_for_each(j, cp->perms) {
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
@ -0,0 +1,90 @@
|
|||||||
|
From 521e6a2f478a4c7a7c198c017d4d12e8667d89e7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
Date: Sat, 3 Oct 2020 15:19:08 +0200
|
||||||
|
Subject: [PATCH] libsepol/cil: fix signed overflow caused by using (1 << 31) -
|
||||||
|
1
|
||||||
|
|
||||||
|
When compiling SELinux userspace tools with -ftrapv (this option
|
||||||
|
generates traps for signed overflow on addition, subtraction,
|
||||||
|
multiplication operations, instead of silently wrapping around),
|
||||||
|
semodule crashes when running the tests from
|
||||||
|
scripts/ci/fedora-test-runner.sh in a Fedora 32 virtual machine:
|
||||||
|
|
||||||
|
[root@localhost selinux-testsuite]# make test
|
||||||
|
make -C policy load
|
||||||
|
make[1]: Entering directory '/root/selinux-testsuite/policy'
|
||||||
|
# Test for "expand-check = 0" in /etc/selinux/semanage.conf
|
||||||
|
# General policy build
|
||||||
|
make[2]: Entering directory '/root/selinux-testsuite/policy/test_policy'
|
||||||
|
Compiling targeted test_policy module
|
||||||
|
Creating targeted test_policy.pp policy package
|
||||||
|
rm tmp/test_policy.mod.fc
|
||||||
|
make[2]: Leaving directory '/root/selinux-testsuite/policy/test_policy'
|
||||||
|
# General policy load
|
||||||
|
domain_fd_use --> off
|
||||||
|
/usr/sbin/semodule -i test_policy/test_policy.pp test_mlsconstrain.cil test_overlay_defaultrange.cil test_add_levels.cil test_glblub.cil
|
||||||
|
make[1]: *** [Makefile:174: load] Aborted (core dumped)
|
||||||
|
|
||||||
|
Using "coredumpctl gdb" leads to the following strack trace:
|
||||||
|
|
||||||
|
(gdb) bt
|
||||||
|
#0 0x00007f608fe4fa25 in raise () from /lib64/libc.so.6
|
||||||
|
#1 0x00007f608fe38895 in abort () from /lib64/libc.so.6
|
||||||
|
#2 0x00007f6090028aca in __addvsi3.cold () from /lib64/libsepol.so.1
|
||||||
|
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
|
||||||
|
at ../cil/src/cil_binary.c:1551
|
||||||
|
#4 0x00007f60900970dd in __cil_permx_bitmap_to_sepol_xperms_list (xperms=0xb650a30, xperms_list=0x7ffce2653b18)
|
||||||
|
at ../cil/src/cil_binary.c:1596
|
||||||
|
#5 0x00007f6090097286 in __cil_avrulex_ioctl_to_policydb (k=0xb8ec200 "@\023\214\022\006", datum=0xb650a30,
|
||||||
|
args=0x239a640) at ../cil/src/cil_binary.c:1649
|
||||||
|
#6 0x00007f609003f1e5 in hashtab_map (h=0x41f8710, apply=0x7f60900971da <__cil_avrulex_ioctl_to_policydb>,
|
||||||
|
args=0x239a640) at hashtab.c:234
|
||||||
|
#7 0x00007f609009ea19 in cil_binary_create_allocated_pdb (db=0x2394f10, policydb=0x239a640)
|
||||||
|
at ../cil/src/cil_binary.c:4969
|
||||||
|
#8 0x00007f609009d19d in cil_binary_create (db=0x2394f10, policydb=0x7ffce2653d30) at ../cil/src/cil_binary.c:4329
|
||||||
|
#9 0x00007f609008ec23 in cil_build_policydb_create_pdb (db=0x2394f10, sepol_db=0x7ffce2653d30)
|
||||||
|
at ../cil/src/cil.c:631
|
||||||
|
#10 0x00007f608fff4bf3 in semanage_direct_commit () from /lib64/libsemanage.so.1
|
||||||
|
#11 0x00007f608fff9fae in semanage_commit () from /lib64/libsemanage.so.1
|
||||||
|
#12 0x0000000000403e2b in main (argc=7, argv=0x7ffce2655058) at semodule.c:753
|
||||||
|
|
||||||
|
(gdb) f 3
|
||||||
|
#3 0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)
|
||||||
|
at ../cil/src/cil_binary.c:1551
|
||||||
|
1551 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
|
||||||
|
|
||||||
|
A signed integer overflow therefore occurs in XPERM_SETBITS(h):
|
||||||
|
|
||||||
|
#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
|
||||||
|
|
||||||
|
This macro is expanded with h=31, so "(1 << 31) - 1" is computed:
|
||||||
|
|
||||||
|
* (1 << 31) = -0x80000000 is the lowest signed 32-bit integer value
|
||||||
|
* (1 << 31) - 1 overflows the capacity of a signed 32-bit integer and
|
||||||
|
results in 0x7fffffff (which is unsigned)
|
||||||
|
|
||||||
|
Using unsigned integers (with "1U") fixes the crash, as
|
||||||
|
(1U << 31) = 0x80000000U has no overflowing issues.
|
||||||
|
|
||||||
|
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
Acked-by: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_binary.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||||||
|
index 36720eda4549..e417c5c28b8b 100644
|
||||||
|
--- a/libsepol/cil/src/cil_binary.c
|
||||||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||||||
|
@@ -1526,7 +1526,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_
|
||||||
|
/* index of the u32 containing the permission */
|
||||||
|
#define XPERM_IDX(x) (x >> 5)
|
||||||
|
/* set bits 0 through x-1 within the u32 */
|
||||||
|
-#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
|
||||||
|
+#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)
|
||||||
|
/* low value for this u32 */
|
||||||
|
#define XPERM_LOW(x) (x << 5)
|
||||||
|
/* high value for this u32 */
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
77
0007-libsepol-drop-confusing-BUG_ON-macro.patch
Normal file
77
0007-libsepol-drop-confusing-BUG_ON-macro.patch
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
From 64387cb37379fc8f135eeecd2bd9fdf3c591c763 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
Date: Sat, 3 Oct 2020 15:34:19 +0200
|
||||||
|
Subject: [PATCH] libsepol: drop confusing BUG_ON macro
|
||||||
|
|
||||||
|
Contrary to Linux kernel, BUG_ON() does not halt the execution, in
|
||||||
|
libsepol/src/services.c. Instead it displays an error message and
|
||||||
|
continues the execution.
|
||||||
|
|
||||||
|
This means that this code does not prevent an out-of-bound write from
|
||||||
|
happening:
|
||||||
|
|
||||||
|
case CEXPR_AND:
|
||||||
|
BUG_ON(sp < 1);
|
||||||
|
sp--;
|
||||||
|
s[sp] &= s[sp + 1];
|
||||||
|
|
||||||
|
Use if(...){BUG();rc=-EINVAL;goto out;} constructions instead, to make
|
||||||
|
sure that the array access is always in-bound.
|
||||||
|
|
||||||
|
This issue has been found using clang's static analyzer:
|
||||||
|
https://558-118970575-gh.circle-artifacts.com/0/output-scan-build/2020-10-02-065849-6375-1/report-50a861.html#EndPath
|
||||||
|
|
||||||
|
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
---
|
||||||
|
libsepol/src/services.c | 19 +++++++++++++++----
|
||||||
|
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||||
|
index 90da1f4efef3..beb0711f6680 100644
|
||||||
|
--- a/libsepol/src/services.c
|
||||||
|
+++ b/libsepol/src/services.c
|
||||||
|
@@ -67,7 +67,6 @@
|
||||||
|
#include "flask.h"
|
||||||
|
|
||||||
|
#define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)
|
||||||
|
-#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)
|
||||||
|
|
||||||
|
static int selinux_enforcing = 1;
|
||||||
|
|
||||||
|
@@ -469,18 +468,30 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,
|
||||||
|
/* Now process each expression of the constraint */
|
||||||
|
switch (e->expr_type) {
|
||||||
|
case CEXPR_NOT:
|
||||||
|
- BUG_ON(sp < 0);
|
||||||
|
+ if (sp < 0) {
|
||||||
|
+ BUG();
|
||||||
|
+ rc = -EINVAL;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
s[sp] = !s[sp];
|
||||||
|
cat_expr_buf(expr_list[expr_counter], "not");
|
||||||
|
break;
|
||||||
|
case CEXPR_AND:
|
||||||
|
- BUG_ON(sp < 1);
|
||||||
|
+ if (sp < 1) {
|
||||||
|
+ BUG();
|
||||||
|
+ rc = -EINVAL;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
sp--;
|
||||||
|
s[sp] &= s[sp + 1];
|
||||||
|
cat_expr_buf(expr_list[expr_counter], "and");
|
||||||
|
break;
|
||||||
|
case CEXPR_OR:
|
||||||
|
- BUG_ON(sp < 1);
|
||||||
|
+ if (sp < 1) {
|
||||||
|
+ BUG();
|
||||||
|
+ rc = -EINVAL;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
sp--;
|
||||||
|
s[sp] |= s[sp + 1];
|
||||||
|
cat_expr_buf(expr_list[expr_counter], "or");
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
From c97d63c6b40c71c693d3b5bb25628869a95dff24 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
Date: Sat, 3 Oct 2020 15:56:58 +0200
|
||||||
|
Subject: [PATCH] libsepol: silence potential NULL pointer dereference warning
|
||||||
|
|
||||||
|
When find_avtab_node() is called with key->specified & AVTAB_XPERMS and
|
||||||
|
xperms=NULL, xperms is being dereferenced. This is detected as a
|
||||||
|
"NULL pointer dereference issue" by static analyzers.
|
||||||
|
|
||||||
|
Even though it does not make much sense to call find_avtab_node() in a
|
||||||
|
way which triggers the NULL pointer dereference issue, static analyzers
|
||||||
|
have a hard time with calls such as:
|
||||||
|
|
||||||
|
node = find_avtab_node(handle, avtab, &avkey, cond, NULL);
|
||||||
|
|
||||||
|
... where xperms=NULL.
|
||||||
|
|
||||||
|
So, make the function report an error instead of crashing.
|
||||||
|
|
||||||
|
Here is an example of report from clang's static analyzer:
|
||||||
|
https://558-118970575-gh.circle-artifacts.com/0/output-scan-build/2020-10-02-065849-6375-1/report-d86a57.html#EndPath
|
||||||
|
|
||||||
|
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
---
|
||||||
|
libsepol/src/expand.c | 23 ++++++++++++++---------
|
||||||
|
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
|
||||||
|
index 19e48c507236..eac7e4507d02 100644
|
||||||
|
--- a/libsepol/src/expand.c
|
||||||
|
+++ b/libsepol/src/expand.c
|
||||||
|
@@ -1570,17 +1570,22 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
|
||||||
|
|
||||||
|
/* AVTAB_XPERMS entries are not necessarily unique */
|
||||||
|
if (key->specified & AVTAB_XPERMS) {
|
||||||
|
- node = avtab_search_node(avtab, key);
|
||||||
|
- while (node) {
|
||||||
|
- if ((node->datum.xperms->specified == xperms->specified) &&
|
||||||
|
- (node->datum.xperms->driver == xperms->driver)) {
|
||||||
|
- match = 1;
|
||||||
|
- break;
|
||||||
|
+ if (xperms == NULL) {
|
||||||
|
+ ERR(handle, "searching xperms NULL");
|
||||||
|
+ node = NULL;
|
||||||
|
+ } else {
|
||||||
|
+ node = avtab_search_node(avtab, key);
|
||||||
|
+ while (node) {
|
||||||
|
+ if ((node->datum.xperms->specified == xperms->specified) &&
|
||||||
|
+ (node->datum.xperms->driver == xperms->driver)) {
|
||||||
|
+ match = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ node = avtab_search_node_next(node, key->specified);
|
||||||
|
}
|
||||||
|
- node = avtab_search_node_next(node, key->specified);
|
||||||
|
+ if (!match)
|
||||||
|
+ node = NULL;
|
||||||
|
}
|
||||||
|
- if (!match)
|
||||||
|
- node = NULL;
|
||||||
|
} else {
|
||||||
|
node = avtab_search_node(avtab, key);
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
193
0009-libsepol-Get-rid-of-the-old-and-duplicated-symbols.patch
Normal file
193
0009-libsepol-Get-rid-of-the-old-and-duplicated-symbols.patch
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
From ae58e84b4fd825b6cd2c67f3856ac35557c45e9c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
Date: Fri, 9 Oct 2020 15:00:47 +0200
|
||||||
|
Subject: [PATCH] libsepol: Get rid of the old and duplicated symbols
|
||||||
|
|
||||||
|
Versioned duplicate symbols cause problems for LTO. These symbols were
|
||||||
|
introduced during the CIL integration several releases ago and were only
|
||||||
|
consumed by other SELinux userspace components.
|
||||||
|
|
||||||
|
Fixes: https://github.com/SELinuxProject/selinux/issues/245
|
||||||
|
|
||||||
|
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil.c | 84 ------------------------------------
|
||||||
|
libsepol/src/libsepol.map.in | 5 ---
|
||||||
|
2 files changed, 89 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
|
||||||
|
index a3c6a2934c72..95bdb5e5854c 100644
|
||||||
|
--- a/libsepol/cil/src/cil.c
|
||||||
|
+++ b/libsepol/cil/src/cil.c
|
||||||
|
@@ -51,27 +51,6 @@
|
||||||
|
#include "cil_policy.h"
|
||||||
|
#include "cil_strpool.h"
|
||||||
|
|
||||||
|
-#if !defined(SHARED) || defined(ANDROID) || defined(__APPLE__)
|
||||||
|
- #define DISABLE_SYMVER 1
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#ifndef DISABLE_SYMVER
|
||||||
|
-asm(".symver cil_build_policydb_pdb, cil_build_policydb@LIBSEPOL_1.0");
|
||||||
|
-asm(".symver cil_build_policydb_create_pdb, cil_build_policydb@@LIBSEPOL_1.1");
|
||||||
|
-
|
||||||
|
-asm(".symver cil_compile_pdb, cil_compile@LIBSEPOL_1.0");
|
||||||
|
-asm(".symver cil_compile_nopdb, cil_compile@@LIBSEPOL_1.1");
|
||||||
|
-
|
||||||
|
-asm(".symver cil_userprefixes_to_string_pdb, cil_userprefixes_to_string@LIBSEPOL_1.0");
|
||||||
|
-asm(".symver cil_userprefixes_to_string_nopdb, cil_userprefixes_to_string@@LIBSEPOL_1.1");
|
||||||
|
-
|
||||||
|
-asm(".symver cil_selinuxusers_to_string_pdb, cil_selinuxusers_to_string@LIBSEPOL_1.0");
|
||||||
|
-asm(".symver cil_selinuxusers_to_string_nopdb, cil_selinuxusers_to_string@@LIBSEPOL_1.1");
|
||||||
|
-
|
||||||
|
-asm(".symver cil_filecons_to_string_pdb, cil_filecons_to_string@LIBSEPOL_1.0");
|
||||||
|
-asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1");
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {
|
||||||
|
{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||||
|
{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
|
||||||
|
@@ -549,11 +528,7 @@ exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef DISABLE_SYMVER
|
||||||
|
int cil_compile(struct cil_db *db)
|
||||||
|
-#else
|
||||||
|
-int cil_compile_nopdb(struct cil_db *db)
|
||||||
|
-#endif
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
|
||||||
|
@@ -597,33 +572,7 @@ exit:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifndef DISABLE_SYMVER
|
||||||
|
-int cil_compile_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db)
|
||||||
|
-{
|
||||||
|
- return cil_compile_nopdb(db);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int cil_build_policydb_pdb(cil_db_t *db, sepol_policydb_t *sepol_db)
|
||||||
|
-{
|
||||||
|
- int rc;
|
||||||
|
-
|
||||||
|
- cil_log(CIL_INFO, "Building policy binary\n");
|
||||||
|
- rc = cil_binary_create_allocated_pdb(db, sepol_db);
|
||||||
|
- if (rc != SEPOL_OK) {
|
||||||
|
- cil_log(CIL_ERR, "Failed to generate binary\n");
|
||||||
|
- goto exit;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-exit:
|
||||||
|
- return rc;
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#ifdef DISABLE_SYMVER
|
||||||
|
int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db)
|
||||||
|
-#else
|
||||||
|
-int cil_build_policydb_create_pdb(cil_db_t *db, sepol_policydb_t **sepol_db)
|
||||||
|
-#endif
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
@@ -1371,11 +1320,7 @@ const char * cil_node_to_string(struct cil_tree_node *node)
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef DISABLE_SYMVER
|
||||||
|
int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#else
|
||||||
|
-int cil_userprefixes_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#endif
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
size_t str_len = 0;
|
||||||
|
@@ -1420,13 +1365,6 @@ exit:
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifndef DISABLE_SYMVER
|
||||||
|
-int cil_userprefixes_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
|
||||||
|
-{
|
||||||
|
- return cil_userprefixes_to_string_nopdb(db, out, size);
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitmap)
|
||||||
|
{
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
@@ -1614,11 +1552,7 @@ static int __cil_level_to_string(struct cil_level *lvl, char *out)
|
||||||
|
return str_tmp - out;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef DISABLE_SYMVER
|
||||||
|
int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#else
|
||||||
|
-int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#endif
|
||||||
|
{
|
||||||
|
size_t str_len = 0;
|
||||||
|
int buf_pos = 0;
|
||||||
|
@@ -1675,18 +1609,7 @@ int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size
|
||||||
|
return SEPOL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifndef DISABLE_SYMVER
|
||||||
|
-int cil_selinuxusers_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
|
||||||
|
-{
|
||||||
|
- return cil_selinuxusers_to_string_nopdb(db, out, size);
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
-#ifdef DISABLE_SYMVER
|
||||||
|
int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#else
|
||||||
|
-int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
|
||||||
|
-#endif
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
int buf_pos = 0;
|
||||||
|
@@ -1804,13 +1727,6 @@ int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size)
|
||||||
|
return SEPOL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifndef DISABLE_SYMVER
|
||||||
|
-int cil_filecons_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)
|
||||||
|
-{
|
||||||
|
- return cil_filecons_to_string_nopdb(db, out, size);
|
||||||
|
-}
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
void cil_set_disable_dontaudit(struct cil_db *db, int disable_dontaudit)
|
||||||
|
{
|
||||||
|
db->disable_dontaudit = disable_dontaudit;
|
||||||
|
diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
|
||||||
|
index f08c2a861693..98da9789b71b 100644
|
||||||
|
--- a/libsepol/src/libsepol.map.in
|
||||||
|
+++ b/libsepol/src/libsepol.map.in
|
||||||
|
@@ -1,19 +1,14 @@
|
||||||
|
LIBSEPOL_1.0 {
|
||||||
|
global:
|
||||||
|
cil_add_file;
|
||||||
|
- cil_build_policydb;
|
||||||
|
- cil_compile;
|
||||||
|
cil_db_destroy;
|
||||||
|
cil_db_init;
|
||||||
|
- cil_filecons_to_string;
|
||||||
|
- cil_selinuxusers_to_string;
|
||||||
|
cil_set_disable_dontaudit;
|
||||||
|
cil_set_disable_neverallow;
|
||||||
|
cil_set_handle_unknown;
|
||||||
|
cil_set_log_handler;
|
||||||
|
cil_set_log_level;
|
||||||
|
cil_set_preserve_tunables;
|
||||||
|
- cil_userprefixes_to_string;
|
||||||
|
expand_module_avrules;
|
||||||
|
sepol_bool_clone;
|
||||||
|
sepol_bool_compare;
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
134
0010-libsepol-Drop-deprecated-functions.patch
Normal file
134
0010-libsepol-Drop-deprecated-functions.patch
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
From 506c7b95b802ab157fe9ae1dae22fab12c515306 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
Date: Fri, 9 Oct 2020 15:00:48 +0200
|
||||||
|
Subject: [PATCH] libsepol: Drop deprecated functions
|
||||||
|
|
||||||
|
These functions were converted to no-op by commit
|
||||||
|
c3f9492d7ff0 ("selinux: Remove legacy local boolean and user code") and
|
||||||
|
left in libsepol/src/deprecated_functions.c to preserve API/ABI. As we
|
||||||
|
change libsepol ABI dropping duplicate symbols it's time to drop these
|
||||||
|
functions too.
|
||||||
|
|
||||||
|
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/include/sepol/booleans.h | 5 ----
|
||||||
|
libsepol/include/sepol/users.h | 6 ----
|
||||||
|
libsepol/src/deprecated_funcs.c | 50 -------------------------------
|
||||||
|
libsepol/src/libsepol.map.in | 4 ---
|
||||||
|
4 files changed, 65 deletions(-)
|
||||||
|
delete mode 100644 libsepol/src/deprecated_funcs.c
|
||||||
|
|
||||||
|
diff --git a/libsepol/include/sepol/booleans.h b/libsepol/include/sepol/booleans.h
|
||||||
|
index 06d2230c395d..25229057dbd7 100644
|
||||||
|
--- a/libsepol/include/sepol/booleans.h
|
||||||
|
+++ b/libsepol/include/sepol/booleans.h
|
||||||
|
@@ -10,11 +10,6 @@
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-/* These two functions are deprecated. See src/deprecated_funcs.c */
|
||||||
|
-extern int sepol_genbools(void *data, size_t len, const char *boolpath);
|
||||||
|
-extern int sepol_genbools_array(void *data, size_t len,
|
||||||
|
- char **names, int *values, int nel);
|
||||||
|
-
|
||||||
|
/* Set the specified boolean */
|
||||||
|
extern int sepol_bool_set(sepol_handle_t * handle,
|
||||||
|
sepol_policydb_t * policydb,
|
||||||
|
diff --git a/libsepol/include/sepol/users.h b/libsepol/include/sepol/users.h
|
||||||
|
index 70158ac41e40..156d1adb2d60 100644
|
||||||
|
--- a/libsepol/include/sepol/users.h
|
||||||
|
+++ b/libsepol/include/sepol/users.h
|
||||||
|
@@ -10,12 +10,6 @@
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-/* These two functions are deprecated. See src/deprecated_funcs.c */
|
||||||
|
-extern int sepol_genusers(void *data, size_t len,
|
||||||
|
- const char *usersdir,
|
||||||
|
- void **newdata, size_t * newlen);
|
||||||
|
-extern void sepol_set_delusers(int on);
|
||||||
|
-
|
||||||
|
/* Modify the user, or add it, if the key is not found */
|
||||||
|
extern int sepol_user_modify(sepol_handle_t * handle,
|
||||||
|
sepol_policydb_t * policydb,
|
||||||
|
diff --git a/libsepol/src/deprecated_funcs.c b/libsepol/src/deprecated_funcs.c
|
||||||
|
deleted file mode 100644
|
||||||
|
index d0dab7dfcb4a..000000000000
|
||||||
|
--- a/libsepol/src/deprecated_funcs.c
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,50 +0,0 @@
|
||||||
|
-#include <stdio.h>
|
||||||
|
-#include "debug.h"
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * Need to keep these stubs for the libsepol interfaces exported in
|
||||||
|
- * libsepol.map.in, as they are part of the shared library ABI.
|
||||||
|
- */
|
||||||
|
-
|
||||||
|
-static const char *msg = "Deprecated interface";
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * These two functions are deprecated and referenced in:
|
||||||
|
- * include/libsepol/users.h
|
||||||
|
- */
|
||||||
|
-int sepol_genusers(void *data __attribute((unused)),
|
||||||
|
- size_t len __attribute((unused)),
|
||||||
|
- const char *usersdir __attribute((unused)),
|
||||||
|
- void **newdata __attribute((unused)),
|
||||||
|
- size_t *newlen __attribute((unused)))
|
||||||
|
-{
|
||||||
|
- WARN(NULL, "%s", msg);
|
||||||
|
- return -1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-void sepol_set_delusers(int on __attribute((unused)))
|
||||||
|
-{
|
||||||
|
- WARN(NULL, "%s", msg);
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-/*
|
||||||
|
- * These two functions are deprecated and referenced in:
|
||||||
|
- * include/libsepol/booleans.h
|
||||||
|
- */
|
||||||
|
-int sepol_genbools(void *data __attribute((unused)),
|
||||||
|
- size_t len __attribute((unused)),
|
||||||
|
- const char *booleans __attribute((unused)))
|
||||||
|
-{
|
||||||
|
- WARN(NULL, "%s", msg);
|
||||||
|
- return -1;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-int sepol_genbools_array(void *data __attribute((unused)),
|
||||||
|
- size_t len __attribute((unused)),
|
||||||
|
- char **names __attribute((unused)),
|
||||||
|
- int *values __attribute((unused)),
|
||||||
|
- int nel __attribute((unused)))
|
||||||
|
-{
|
||||||
|
- WARN(NULL, "%s", msg);
|
||||||
|
- return -1;
|
||||||
|
-}
|
||||||
|
diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
|
||||||
|
index 98da9789b71b..eb5721257638 100644
|
||||||
|
--- a/libsepol/src/libsepol.map.in
|
||||||
|
+++ b/libsepol/src/libsepol.map.in
|
||||||
|
@@ -45,9 +45,6 @@ LIBSEPOL_1.0 {
|
||||||
|
sepol_context_to_string;
|
||||||
|
sepol_debug;
|
||||||
|
sepol_expand_module;
|
||||||
|
- sepol_genbools;
|
||||||
|
- sepol_genbools_array;
|
||||||
|
- sepol_genusers;
|
||||||
|
sepol_get_disable_dontaudit;
|
||||||
|
sepol_get_preserve_tunables;
|
||||||
|
sepol_handle_create;
|
||||||
|
@@ -213,7 +210,6 @@ LIBSEPOL_1.0 {
|
||||||
|
sepol_port_set_port;
|
||||||
|
sepol_port_set_proto;
|
||||||
|
sepol_port_set_range;
|
||||||
|
- sepol_set_delusers;
|
||||||
|
sepol_set_disable_dontaudit;
|
||||||
|
sepol_set_expand_consume_base;
|
||||||
|
sepol_set_policydb_from_file;
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
45
0011-libsepol-Bump-libsepol.so-version.patch
Normal file
45
0011-libsepol-Bump-libsepol.so-version.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
From 4a142ac46a116feb9f978eaec68a30efef979c73 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
Date: Fri, 9 Oct 2020 15:00:49 +0200
|
||||||
|
Subject: [PATCH] libsepol: Bump libsepol.so version
|
||||||
|
|
||||||
|
Previous commits removed some symbols and broke ABI, therefore we need to change
|
||||||
|
SONAME.
|
||||||
|
|
||||||
|
See the following quotes from distribution guidelines:
|
||||||
|
|
||||||
|
https://www.debian.org/doc/debian-policy/ch-sharedlibs.html#run-time-shared-libraries
|
||||||
|
|
||||||
|
Every time the shared library ABI changes in a way that may break
|
||||||
|
binaries linked against older versions of the shared library, the SONAME
|
||||||
|
of the library and the corresponding name for the binary package
|
||||||
|
containing the runtime shared library should change.
|
||||||
|
|
||||||
|
https://docs.fedoraproject.org/en-US/packaging-guidelines/#_downstream_so_name_versioning
|
||||||
|
|
||||||
|
When new versions of the library are released, you should use an ABI
|
||||||
|
comparison tool to check for ABI differences in the built shared
|
||||||
|
libraries. If it detects any incompatibilities, bump the n number by
|
||||||
|
one.
|
||||||
|
|
||||||
|
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/src/Makefile | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/src/Makefile b/libsepol/src/Makefile
|
||||||
|
index 8d466f56ed0e..dc8b1773d974 100644
|
||||||
|
--- a/libsepol/src/Makefile
|
||||||
|
+++ b/libsepol/src/Makefile
|
||||||
|
@@ -7,7 +7,7 @@ RANLIB ?= ranlib
|
||||||
|
CILDIR ?= ../cil
|
||||||
|
|
||||||
|
VERSION = $(shell cat ../VERSION)
|
||||||
|
-LIBVERSION = 1
|
||||||
|
+LIBVERSION = 2
|
||||||
|
|
||||||
|
LEX = flex
|
||||||
|
CIL_GENERATED = $(CILDIR)/src/cil_lexer.c
|
||||||
|
--
|
||||||
|
2.29.0.rc2
|
||||||
|
|
170
0012-libsepol-cil-Give-error-for-more-than-one-true-or-fa.patch
Normal file
170
0012-libsepol-cil-Give-error-for-more-than-one-true-or-fa.patch
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
From 3b26f0566698926ba38cbf3fa702f3ff78862c5e Mon Sep 17 00:00:00 2001
|
||||||
|
From: James Carter <jwcart2@gmail.com>
|
||||||
|
Date: Tue, 20 Oct 2020 09:28:56 -0400
|
||||||
|
Subject: [PATCH] libsepol/cil: Give error for more than one true or false
|
||||||
|
block
|
||||||
|
|
||||||
|
Both tunableif and booleanif use conditional blocks (either true or
|
||||||
|
false). No ordering is imposed, so a false block can be first (or even
|
||||||
|
the only) block. Checks are made to ensure that the first and second
|
||||||
|
(if it exists) blocks are either true or false, but no checks are made
|
||||||
|
to ensure that there is only one true and/or one false block. If there
|
||||||
|
are more than one true or false block, only the first will be used and
|
||||||
|
the other will be ignored.
|
||||||
|
|
||||||
|
Create a function, cil_verify_conditional_blocks(), that gives an error
|
||||||
|
along with a message if more than one true or false block is specified
|
||||||
|
and call that function when building tunableif and booleanif blocks in
|
||||||
|
the AST.
|
||||||
|
|
||||||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||||||
|
Acked-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||||
|
---
|
||||||
|
libsepol/cil/src/cil_build_ast.c | 44 +++++---------------------------
|
||||||
|
libsepol/cil/src/cil_verify.c | 35 +++++++++++++++++++++++++
|
||||||
|
libsepol/cil/src/cil_verify.h | 1 +
|
||||||
|
3 files changed, 42 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
index 3aabb05ec534..a895583404a7 100644
|
||||||
|
--- a/libsepol/cil/src/cil_build_ast.c
|
||||||
|
+++ b/libsepol/cil/src/cil_build_ast.c
|
||||||
|
@@ -2821,7 +2821,6 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
|
||||||
|
int syntax_len = sizeof(syntax)/sizeof(*syntax);
|
||||||
|
struct cil_booleanif *bif = NULL;
|
||||||
|
struct cil_tree_node *next = NULL;
|
||||||
|
- struct cil_tree_node *cond = NULL;
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
|
||||||
|
if (db == NULL || parse_current == NULL || ast_node == NULL) {
|
||||||
|
@@ -2841,27 +2840,12 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- cond = parse_current->next->next;
|
||||||
|
-
|
||||||
|
- /* Destroying expr tree after stack is created*/
|
||||||
|
- if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
||||||
|
- cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
||||||
|
- rc = SEPOL_ERR;
|
||||||
|
- cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
||||||
|
+ rc = cil_verify_conditional_blocks(parse_current->next->next);
|
||||||
|
+ if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cond->next != NULL) {
|
||||||
|
- cond = cond->next;
|
||||||
|
- if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
||||||
|
- cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
||||||
|
- rc = SEPOL_ERR;
|
||||||
|
- cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
||||||
|
- goto exit;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
-
|
||||||
|
+ /* Destroying expr tree */
|
||||||
|
next = parse_current->next->next;
|
||||||
|
cil_tree_subtree_destroy(parse_current->next);
|
||||||
|
parse_current->next = next;
|
||||||
|
@@ -2905,7 +2889,6 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||||
|
int syntax_len = sizeof(syntax)/sizeof(*syntax);
|
||||||
|
struct cil_tunableif *tif = NULL;
|
||||||
|
struct cil_tree_node *next = NULL;
|
||||||
|
- struct cil_tree_node *cond = NULL;
|
||||||
|
int rc = SEPOL_ERR;
|
||||||
|
|
||||||
|
if (db == NULL || parse_current == NULL || ast_node == NULL) {
|
||||||
|
@@ -2924,27 +2907,12 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- cond = parse_current->next->next;
|
||||||
|
-
|
||||||
|
- if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
||||||
|
- cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
||||||
|
- rc = SEPOL_ERR;
|
||||||
|
- cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
||||||
|
+ rc = cil_verify_conditional_blocks(parse_current->next->next);
|
||||||
|
+ if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (cond->next != NULL) {
|
||||||
|
- cond = cond->next;
|
||||||
|
-
|
||||||
|
- if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
|
||||||
|
- cond->cl_head->data != CIL_KEY_CONDFALSE) {
|
||||||
|
- rc = SEPOL_ERR;
|
||||||
|
- cil_log(CIL_ERR, "Conditional neither true nor false\n");
|
||||||
|
- goto exit;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Destroying expr tree after stack is created*/
|
||||||
|
+ /* Destroying expr tree */
|
||||||
|
next = parse_current->next->next;
|
||||||
|
cil_tree_subtree_destroy(parse_current->next);
|
||||||
|
parse_current->next = next;
|
||||||
|
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
|
||||||
|
index c73bbeee371b..6706e21921fe 100644
|
||||||
|
--- a/libsepol/cil/src/cil_verify.c
|
||||||
|
+++ b/libsepol/cil/src/cil_verify.c
|
||||||
|
@@ -324,6 +324,41 @@ exit:
|
||||||
|
return SEPOL_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int cil_verify_conditional_blocks(struct cil_tree_node *current)
|
||||||
|
+{
|
||||||
|
+ int found_true = CIL_FALSE;
|
||||||
|
+ int found_false = CIL_FALSE;
|
||||||
|
+
|
||||||
|
+ if (current->cl_head->data == CIL_KEY_CONDTRUE) {
|
||||||
|
+ found_true = CIL_TRUE;
|
||||||
|
+ } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
|
||||||
|
+ found_false = CIL_TRUE;
|
||||||
|
+ } else {
|
||||||
|
+ cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ current = current->next;
|
||||||
|
+ if (current != NULL) {
|
||||||
|
+ if (current->cl_head->data == CIL_KEY_CONDTRUE) {
|
||||||
|
+ if (found_true) {
|
||||||
|
+ cil_tree_log(current, CIL_ERR, "More than one true block in conditional");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
|
||||||
|
+ if (found_false) {
|
||||||
|
+ cil_tree_log(current, CIL_ERR, "More than one false block in conditional");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
|
||||||
|
+ return SEPOL_ERR;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SEPOL_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list)
|
||||||
|
{
|
||||||
|
struct cil_list_item *i;
|
||||||
|
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
|
||||||
|
index bda1565fced5..905761b0a19c 100644
|
||||||
|
--- a/libsepol/cil/src/cil_verify.h
|
||||||
|
+++ b/libsepol/cil/src/cil_verify.h
|
||||||
|
@@ -61,6 +61,7 @@ int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[]
|
||||||
|
int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||||
|
int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor);
|
||||||
|
int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op);
|
||||||
|
+int cil_verify_conditional_blocks(struct cil_tree_node *current);
|
||||||
|
int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list);
|
||||||
|
int __cil_verify_ranges(struct cil_list *list);
|
||||||
|
int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args);
|
||||||
|
--
|
||||||
|
2.29.2
|
||||||
|
|
81
0013-libsepol-free-memory-when-realloc-fails.patch
Normal file
81
0013-libsepol-free-memory-when-realloc-fails.patch
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
From a2bd2a8ea5ef687e8b4dc2694f7d5e99a1ec2a06 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
Date: Thu, 12 Nov 2020 21:24:06 +0100
|
||||||
|
Subject: [PATCH] libsepol: free memory when realloc() fails
|
||||||
|
|
||||||
|
In get_class_info(), if realloc(class_buf, new_class_buf_len) fails to
|
||||||
|
grow the memory, the function returns NULL without freeing class_buf.
|
||||||
|
This leads to a memory leak which is reported by clang's static
|
||||||
|
analyzer:
|
||||||
|
https://580-118970575-gh.circle-artifacts.com/0/output-scan-build/2020-11-11-194150-6152-1/report-42a899.html#EndPath
|
||||||
|
|
||||||
|
Fix the memory leak by calling free(class_buf).
|
||||||
|
|
||||||
|
While at it, use size_t insted of int to store the size of the buffer
|
||||||
|
which is growing.
|
||||||
|
|
||||||
|
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
|
||||||
|
---
|
||||||
|
libsepol/src/services.c | 19 +++++++++++--------
|
||||||
|
1 file changed, 11 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libsepol/src/services.c b/libsepol/src/services.c
|
||||||
|
index beb0711f6680..72b39657cd2e 100644
|
||||||
|
--- a/libsepol/src/services.c
|
||||||
|
+++ b/libsepol/src/services.c
|
||||||
|
@@ -312,17 +312,20 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||||
|
else
|
||||||
|
state_num = mls + 2;
|
||||||
|
|
||||||
|
- int class_buf_len = 0;
|
||||||
|
- int new_class_buf_len;
|
||||||
|
- int len, buf_used;
|
||||||
|
+ size_t class_buf_len = 0;
|
||||||
|
+ size_t new_class_buf_len;
|
||||||
|
+ size_t buf_used;
|
||||||
|
+ int len;
|
||||||
|
char *class_buf = NULL, *p;
|
||||||
|
char *new_class_buf = NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
|
||||||
|
new_class_buf = realloc(class_buf, new_class_buf_len);
|
||||||
|
- if (!new_class_buf)
|
||||||
|
- return NULL;
|
||||||
|
+ if (!new_class_buf) {
|
||||||
|
+ free(class_buf);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
class_buf_len = new_class_buf_len;
|
||||||
|
class_buf = new_class_buf;
|
||||||
|
buf_used = 0;
|
||||||
|
@@ -330,7 +333,7 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||||
|
|
||||||
|
/* Add statement type */
|
||||||
|
len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]);
|
||||||
|
- if (len < 0 || len >= class_buf_len - buf_used)
|
||||||
|
+ if (len < 0 || (size_t)len >= class_buf_len - buf_used)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add class entry */
|
||||||
|
@@ -338,7 +341,7 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||||
|
buf_used += len;
|
||||||
|
len = snprintf(p, class_buf_len - buf_used, "%s ",
|
||||||
|
policydb->p_class_val_to_name[tclass - 1]);
|
||||||
|
- if (len < 0 || len >= class_buf_len - buf_used)
|
||||||
|
+ if (len < 0 || (size_t)len >= class_buf_len - buf_used)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Add permission entries (validatetrans does not have perms) */
|
||||||
|
@@ -351,7 +354,7 @@ static char *get_class_info(sepol_security_class_t tclass,
|
||||||
|
} else {
|
||||||
|
len = snprintf(p, class_buf_len - buf_used, "(");
|
||||||
|
}
|
||||||
|
- if (len < 0 || len >= class_buf_len - buf_used)
|
||||||
|
+ if (len < 0 || (size_t)len >= class_buf_len - buf_used)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.29.2
|
||||||
|
|
18
STAGE1-libsepol
Normal file
18
STAGE1-libsepol
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
srpm libsepol
|
||||||
|
mcd $BUILDDIR/t-libsepol
|
||||||
|
rsync -av $SRC/libsepol*/ ./
|
||||||
|
make $J \
|
||||||
|
CC=${TARGET}-gcc \
|
||||||
|
AS=${TARGET}-as \
|
||||||
|
AR=${TARGET}-ar \
|
||||||
|
STRIP=${TARGET}-strip \
|
||||||
|
RANLIB=${TARGET}-ranlib \
|
||||||
|
CFLAGS="" \
|
||||||
|
TLSFLAGS="" \
|
||||||
|
all
|
||||||
|
ARGS="DESTDIR=${ROOTFS}"
|
||||||
|
if [ "$SUFFIX" = "64" ]
|
||||||
|
then
|
||||||
|
ARGS="$ARGS LIBDIR=${ROOTFS}/usr/lib64 SHLIBDIR=${ROOTFS}/usr/lib64"
|
||||||
|
fi
|
||||||
|
make $J $ARGS install
|
16
gating.yaml
Normal file
16
gating.yaml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- fedora-*
|
||||||
|
decision_context: bodhi_update_push_testing
|
||||||
|
subject_type: koji_build
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
|
||||||
|
|
||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- fedora-*
|
||||||
|
decision_context: bodhi_update_push_stable
|
||||||
|
subject_type: koji_build
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
|
||||||
|
|
@ -1,237 +0,0 @@
|
|||||||
diff --exclude-from=exclude -N -u -r nsalibsepol/include/sepol/policydb/conditional.h libsepol-2.0.1/include/sepol/policydb/conditional.h
|
|
||||||
--- nsalibsepol/include/sepol/policydb/conditional.h 2006-11-16 17:14:15.000000000 -0500
|
|
||||||
+++ libsepol-2.0.1/include/sepol/policydb/conditional.h 2007-03-28 14:13:02.000000000 -0400
|
|
||||||
@@ -100,6 +100,8 @@
|
|
||||||
cond_node_t * needle, cond_node_t * haystack,
|
|
||||||
int *was_created);
|
|
||||||
|
|
||||||
+extern cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node);
|
|
||||||
+
|
|
||||||
extern cond_node_t *cond_node_search(policydb_t * p, cond_node_t * list,
|
|
||||||
cond_node_t * cn);
|
|
||||||
|
|
||||||
diff --exclude-from=exclude -N -u -r nsalibsepol/src/conditional.c libsepol-2.0.1/src/conditional.c
|
|
||||||
--- nsalibsepol/src/conditional.c 2006-11-16 17:14:24.000000000 -0500
|
|
||||||
+++ libsepol-2.0.1/src/conditional.c 2007-03-28 14:13:02.000000000 -0400
|
|
||||||
@@ -26,9 +26,6 @@
|
|
||||||
|
|
||||||
#include "private.h"
|
|
||||||
|
|
||||||
-#undef min
|
|
||||||
-#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
-
|
|
||||||
/* move all type rules to top of t/f lists to help kernel on evaluation */
|
|
||||||
static void cond_optimize(cond_av_list_t ** l)
|
|
||||||
{
|
|
||||||
@@ -136,6 +133,38 @@
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/* Create a new conditional node, optionally copying
|
|
||||||
+ * the conditional expression from an existing node.
|
|
||||||
+ * If node is NULL then a new node will be created
|
|
||||||
+ * with no conditional expression.
|
|
||||||
+ */
|
|
||||||
+cond_node_t *cond_node_create(policydb_t * p, cond_node_t * node)
|
|
||||||
+{
|
|
||||||
+ cond_node_t *new_node;
|
|
||||||
+ unsigned int i;
|
|
||||||
+
|
|
||||||
+ new_node = (cond_node_t *)malloc(sizeof(cond_node_t));
|
|
||||||
+ if (!new_node) {
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ memset(new_node, 0, sizeof(cond_node_t));
|
|
||||||
+
|
|
||||||
+ if (node) {
|
|
||||||
+ new_node->expr = cond_copy_expr(node->expr);
|
|
||||||
+ if (!new_node->expr) {
|
|
||||||
+ free(new_node);
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ new_node->cur_state = cond_evaluate_expr(p, new_node->expr);
|
|
||||||
+ new_node->nbools = node->nbools;
|
|
||||||
+ for (i = 0; i < min(node->nbools, COND_MAX_BOOLS); i++)
|
|
||||||
+ new_node->bool_ids[i] = node->bool_ids[i];
|
|
||||||
+ new_node->expr_pre_comp = node->expr_pre_comp;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return new_node;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Find a conditional (the needle) within a list of existing ones (the
|
|
||||||
* haystack) that has a matching expression. If found, return a
|
|
||||||
* pointer to the existing node, setting 'was_created' to 0.
|
|
||||||
@@ -145,9 +174,6 @@
|
|
||||||
cond_node_t * needle, cond_node_t * haystack,
|
|
||||||
int *was_created)
|
|
||||||
{
|
|
||||||
- cond_node_t *new_node;
|
|
||||||
- unsigned int i;
|
|
||||||
-
|
|
||||||
while (haystack) {
|
|
||||||
if (cond_expr_equal(needle, haystack)) {
|
|
||||||
*was_created = 0;
|
|
||||||
@@ -156,26 +182,8 @@
|
|
||||||
haystack = haystack->next;
|
|
||||||
}
|
|
||||||
*was_created = 1;
|
|
||||||
- new_node = (cond_node_t *) malloc(sizeof(cond_node_t));
|
|
||||||
- if (!new_node) {
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- memset(new_node, 0, sizeof(cond_node_t));
|
|
||||||
- new_node->expr = cond_copy_expr(needle->expr);
|
|
||||||
- if (!new_node->expr) {
|
|
||||||
- free(new_node);
|
|
||||||
- return NULL;
|
|
||||||
- }
|
|
||||||
- new_node->cur_state = cond_evaluate_expr(p, new_node->expr);
|
|
||||||
- new_node->nbools = needle->nbools;
|
|
||||||
- for (i = 0; i < min(needle->nbools, COND_MAX_BOOLS); i++)
|
|
||||||
- new_node->bool_ids[i] = needle->bool_ids[i];
|
|
||||||
- new_node->expr_pre_comp = needle->expr_pre_comp;
|
|
||||||
- new_node->true_list = NULL;
|
|
||||||
- new_node->false_list = NULL;
|
|
||||||
- new_node->avtrue_list = NULL;
|
|
||||||
- new_node->avfalse_list = NULL;
|
|
||||||
- return new_node;
|
|
||||||
+
|
|
||||||
+ return cond_node_create(p, needle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return either a pre-existing matching node or create a new node */
|
|
||||||
diff --exclude-from=exclude -N -u -r nsalibsepol/src/expand.c libsepol-2.0.1/src/expand.c
|
|
||||||
--- nsalibsepol/src/expand.c 2007-02-07 12:11:48.000000000 -0500
|
|
||||||
+++ libsepol-2.0.1/src/expand.c 2007-03-28 14:13:02.000000000 -0400
|
|
||||||
@@ -35,10 +35,12 @@
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
+#include "private.h"
|
|
||||||
|
|
||||||
typedef struct expand_state {
|
|
||||||
int verbose;
|
|
||||||
uint32_t *typemap;
|
|
||||||
+ uint32_t *boolmap;
|
|
||||||
policydb_t *base;
|
|
||||||
policydb_t *out;
|
|
||||||
sepol_handle_t *handle;
|
|
||||||
@@ -791,8 +793,8 @@
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- new_bool->s.value = bool->s.value;
|
|
||||||
state->out->p_bools.nprim++;
|
|
||||||
+ new_bool->s.value = state->out->p_bools.nprim;
|
|
||||||
|
|
||||||
ret = hashtab_insert(state->out->p_bools.table,
|
|
||||||
(hashtab_key_t) new_id,
|
|
||||||
@@ -804,6 +806,8 @@
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ state->boolmap[bool->s.value - 1] = new_bool->s.value;
|
|
||||||
+
|
|
||||||
new_bool->state = bool->state;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -1555,12 +1559,35 @@
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn)
|
|
||||||
+{
|
|
||||||
+ cond_expr_t *cur;
|
|
||||||
+ unsigned int i;
|
|
||||||
+
|
|
||||||
+ cur = cn->expr;
|
|
||||||
+ while (cur) {
|
|
||||||
+ if (cur->bool)
|
|
||||||
+ cur->bool = state->boolmap[cur->bool - 1];
|
|
||||||
+ cur = cur->next;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++)
|
|
||||||
+ cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1];
|
|
||||||
+
|
|
||||||
+ if (cond_normalize_expr(state->out, cn)) {
|
|
||||||
+ ERR(state->handle, "Error while normalizing conditional");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* copy the nodes in *reverse* order -- the result is that the last
|
|
||||||
* given conditional appears first in the policy, so as to match the
|
|
||||||
* behavior of the upstream compiler */
|
|
||||||
static int cond_node_copy(expand_state_t * state, cond_node_t * cn)
|
|
||||||
{
|
|
||||||
- cond_node_t *new_cond;
|
|
||||||
+ cond_node_t *new_cond, *tmp;
|
|
||||||
|
|
||||||
if (cn == NULL) {
|
|
||||||
return 0;
|
|
||||||
@@ -1573,11 +1600,26 @@
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
- new_cond = cond_node_search(state->out, state->out->cond_list, cn);
|
|
||||||
+ /* create a new temporary conditional node with the booleans
|
|
||||||
+ * mapped */
|
|
||||||
+ tmp = cond_node_create(state->base, cn);
|
|
||||||
+ if (!tmp) {
|
|
||||||
+ ERR(state->handle, "Out of memory");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (cond_node_map_bools(state, tmp)) {
|
|
||||||
+ ERR(state->handle, "Error mapping booleans");
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ new_cond = cond_node_search(state->out, state->out->cond_list, tmp);
|
|
||||||
if (!new_cond) {
|
|
||||||
+ cond_node_destroy(tmp);
|
|
||||||
ERR(state->handle, "Out of memory!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
+ cond_node_destroy(tmp);
|
|
||||||
|
|
||||||
if (cond_avrule_list_copy
|
|
||||||
(state->out, cn->avtrue_list, &state->out->te_cond_avtab,
|
|
||||||
@@ -2210,6 +2252,12 @@
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t));
|
|
||||||
+ if (!state.boolmap) {
|
|
||||||
+ ERR(handle, "Out of memory!");
|
|
||||||
+ goto cleanup;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* order is important - types must be first */
|
|
||||||
|
|
||||||
/* copy types */
|
|
||||||
@@ -2364,6 +2412,7 @@
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
free(state.typemap);
|
|
||||||
+ free(state.boolmap);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --exclude-from=exclude -N -u -r nsalibsepol/src/private.h libsepol-2.0.1/src/private.h
|
|
||||||
--- nsalibsepol/src/private.h 2007-02-07 12:11:48.000000000 -0500
|
|
||||||
+++ libsepol-2.0.1/src/private.h 2007-03-28 14:13:02.000000000 -0400
|
|
||||||
@@ -24,6 +24,9 @@
|
|
||||||
#define le64_to_cpu(x) bswap_64(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+#undef min
|
|
||||||
+#define min(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
+
|
|
||||||
/* Policy compatibility information. */
|
|
||||||
struct policydb_compat_info {
|
|
||||||
unsigned int type;
|
|
1140
libsepol.spec
1140
libsepol.spec
File diff suppressed because it is too large
Load Diff
2
sources
2
sources
@ -1 +1 @@
|
|||||||
0c8c322bc4e5c5b5af9a6be7dbbd7d43 libsepol-2.0.33.tgz
|
SHA512 (libsepol-3.1.tar.gz) = 4b5f4e82853ff3e9b4fac2dbdea5c2fc3bb7b508af912217ac4b75da6540fbcd77aa314ab95cd9dfa94fbc4a885000656a663c1a152f65b4cf6970ea0b6034ab
|
||||||
|
12
tests/tests.yml
Normal file
12
tests/tests.yml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
# Tests that run in all contexts
|
||||||
|
- hosts: localhost
|
||||||
|
roles:
|
||||||
|
- role: standard-test-beakerlib
|
||||||
|
tags:
|
||||||
|
- classic
|
||||||
|
- container
|
||||||
|
repositories:
|
||||||
|
- repo: "https://src.fedoraproject.org/tests/selinux.git"
|
||||||
|
dest: "selinux"
|
||||||
|
fmf_filter: "tier: 1 | component: libsepol"
|
Loading…
Reference in New Issue
Block a user