From patchwork Thu Jun 16 13:14:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 12883849 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4AC0C43334 for ; Thu, 16 Jun 2022 13:14:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232987AbiFPNOS (ORCPT ); Thu, 16 Jun 2022 09:14:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48568 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376992AbiFPNOP (ORCPT ); Thu, 16 Jun 2022 09:14:15 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 66BBB37AB0 for ; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id n10so2726006ejk.5 for ; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=9dcZ2AtcqOsdWps0nDzaRZDUGLstrpKouR5oIz5maUQ=; b=l6pVBhVrTrlIfunUk0tpMoIofpudLLmp502/K8S6BEMDa84WSv9qgFhWv5Vy1aec5b JnvL24HV2w4Yhl5BgRMXOAfEmjbJh6eLqOW/TQGHAP4EL3YRBRNwadXP91u/2sYngKWh ElzMZoSP+nrHeOgferYeU/QUfNaqT2xcXHBTOla/mmjgWrRy9HrTNNF+BP2yep/6eRhz rtHQyHkrUo7hIB+xRCC1pohnl1ZsAkaGp6RPwxCTODQLznbuEXesCg1wTwvCfI8Na9u/ qY8vZEjwWQdQg/cbyeFKTXYNvuoQT9xvxdiPgYnr3Z36YSZgu9qlWUGp/aSyPaZO1vz6 4c7w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=9dcZ2AtcqOsdWps0nDzaRZDUGLstrpKouR5oIz5maUQ=; b=I83vlMTQjahTSBzw+9qDOu2NP0xoUIJaPCoQ/eDobmcvXirKxQqoGNOoytBnMJI69J voo5nLgbBsDLaf32kkEjFp8qvvSis4/JLBSJfNjnvCEbomYt/2Ubsl7Ja0QVkzuN7642 V51yP555zpOejPDuXgTfzMrb0xGm7REJHulq4mT7U/fx/W+OPRf6rl/vzLmVwuuP2tbN ZvrUHS7W1mBcju3UqYeizeqRNu9jPPyKuNYkpEQ/hH76uTwuIIw5G4ELDUlRKa3BuVy3 Ayu+NKBfkPH9QITletrL+kxUSaTUGBw/72yooZ9dsvPbGSl50ngpguXGjuyOitaHoaxF Da/Q== X-Gm-Message-State: AJIora9W3v15FVCIXiAGO7TW4ir5KzX9aUzPMgSRduRy2xOntPD7LccM IDk7KQ5ejMtLkDwmI1MI3pO6RR0t7qYp7Q== X-Google-Smtp-Source: AGRyM1s7xrHy2EiuDUCk/jo5awawYfwc3x70AH742BVZw2qa2k+RXIf7CppysAztB1Rsa2c1wfC+Fg== X-Received: by 2002:a17:906:e104:b0:711:d510:54ca with SMTP id gj4-20020a170906e10400b00711d51054camr4363913ejb.342.1655385252852; Thu, 16 Jun 2022 06:14:12 -0700 (PDT) Received: from debianHome.localdomain (dynamic-077-008-158-068.77.8.pool.telefonica.de. [77.8.158.68]) by smtp.gmail.com with ESMTPSA id y11-20020a056402270b00b0042e1cbc4471sm1831530edd.3.2022.06.16.06.14.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jun 2022 06:14:11 -0700 (PDT) From: =?utf-8?q?Christian_G=C3=B6ttsche?= To: selinux@vger.kernel.org Subject: [RFC PATCH 1/4] libsepol: refactor ebitmap conversion in link.c Date: Thu, 16 Jun 2022 15:14:06 +0200 Message-Id: <20220616131409.23271-1-cgzones@googlemail.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Refactor the ebitmap conversions in link.c into its own function. Do not log an OOM message twice on type_set_or_convert() failure. Drop the now unused state parameter from type_set_or_convert() and type_set_convert(). Signed-off-by: Christian Göttsche --- libsepol/src/link.c | 140 +++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 93 deletions(-) diff --git a/libsepol/src/link.c b/libsepol/src/link.c index 7e8313cb..cbe4cea4 100644 --- a/libsepol/src/link.c +++ b/libsepol/src/link.c @@ -958,26 +958,28 @@ static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, /*********** callbacks that fix bitmaps ***********/ -static int type_set_convert(type_set_t * types, type_set_t * dst, - policy_module_t * mod, link_state_t * state - __attribute__ ((unused))) +static int ebitmap_convert(const ebitmap_t *src, ebitmap_t *dst, const uint32_t *map) { - unsigned int i; - ebitmap_node_t *tnode; - ebitmap_for_each_positive_bit(&types->types, tnode, i) { - assert(mod->map[SYM_TYPES][i]); - if (ebitmap_set_bit - (&dst->types, mod->map[SYM_TYPES][i] - 1, 1)) { - goto cleanup; - } - } - ebitmap_for_each_positive_bit(&types->negset, tnode, i) { - assert(mod->map[SYM_TYPES][i]); - if (ebitmap_set_bit - (&dst->negset, mod->map[SYM_TYPES][i] - 1, 1)) { - goto cleanup; - } + unsigned int bit; + ebitmap_node_t *node; + ebitmap_for_each_positive_bit(src, node, bit) { + assert(map[bit]); + if (ebitmap_set_bit(dst, map[bit] - 1, 1)) + return -1; } + + return 0; +} + +static int type_set_convert(const type_set_t * types, type_set_t * dst, + const policy_module_t * mod) +{ + if (ebitmap_convert(&types->types, &dst->types, mod->map[SYM_TYPES])) + goto cleanup; + + if (ebitmap_convert(&types->negset, &dst->negset, mod->map[SYM_TYPES])) + goto cleanup; + dst->flags = types->flags; return 0; @@ -988,13 +990,13 @@ static int type_set_convert(type_set_t * types, type_set_t * dst, /* OR 2 typemaps together and at the same time map the src types to * the correct values in the dst typeset. */ -static int type_set_or_convert(type_set_t * types, type_set_t * dst, - policy_module_t * mod, link_state_t * state) +static int type_set_or_convert(const type_set_t * types, type_set_t * dst, + const policy_module_t * mod) { type_set_t ts_tmp; type_set_init(&ts_tmp); - if (type_set_convert(types, &ts_tmp, mod, state) == -1) { + if (type_set_convert(types, &ts_tmp, mod) == -1) { goto cleanup; } if (type_set_or_eq(dst, &ts_tmp)) { @@ -1004,7 +1006,6 @@ static int type_set_or_convert(type_set_t * types, type_set_t * dst, return 0; cleanup: - ERR(state->handle, "Out of memory!"); type_set_destroy(&ts_tmp); return -1; } @@ -1012,18 +1013,11 @@ static int type_set_or_convert(type_set_t * types, type_set_t * dst, static int role_set_or_convert(role_set_t * roles, role_set_t * dst, policy_module_t * mod, link_state_t * state) { - unsigned int i; ebitmap_t tmp; - ebitmap_node_t *rnode; ebitmap_init(&tmp); - ebitmap_for_each_positive_bit(&roles->roles, rnode, i) { - assert(mod->map[SYM_ROLES][i]); - if (ebitmap_set_bit - (&tmp, mod->map[SYM_ROLES][i] - 1, 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&roles->roles, &tmp, mod->map[SYM_ROLES])) + goto cleanup; if (ebitmap_union(&dst->roles, &tmp)) { goto cleanup; } @@ -1088,13 +1082,11 @@ static int mls_range_convert(mls_semantic_range_t * src, mls_semantic_range_t * static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { - unsigned int i; char *id = key; role_datum_t *role, *dest_role = NULL; link_state_t *state = (link_state_t *) data; ebitmap_t e_tmp; policy_module_t *mod = state->cur; - ebitmap_node_t *rnode; hashtab_t role_tab; role = (role_datum_t *) datum; @@ -1111,30 +1103,20 @@ static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, } ebitmap_init(&e_tmp); - ebitmap_for_each_positive_bit(&role->dominates, rnode, i) { - assert(mod->map[SYM_ROLES][i]); - if (ebitmap_set_bit - (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&role->dominates, &e_tmp, mod->map[SYM_ROLES])) + goto cleanup; if (ebitmap_union(&dest_role->dominates, &e_tmp)) { goto cleanup; } - if (type_set_or_convert(&role->types, &dest_role->types, mod, state)) { + if (type_set_or_convert(&role->types, &dest_role->types, mod)) { goto cleanup; } ebitmap_destroy(&e_tmp); if (role->flavor == ROLE_ATTRIB) { ebitmap_init(&e_tmp); - ebitmap_for_each_positive_bit(&role->roles, rnode, i) { - assert(mod->map[SYM_ROLES][i]); - if (ebitmap_set_bit - (&e_tmp, mod->map[SYM_ROLES][i] - 1, 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&role->roles, &e_tmp, mod->map[SYM_ROLES])) + goto cleanup; if (ebitmap_union(&dest_role->roles, &e_tmp)) { goto cleanup; } @@ -1152,13 +1134,11 @@ static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, static int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum, void *data) { - unsigned int i; char *id = key; type_datum_t *type, *new_type = NULL; link_state_t *state = (link_state_t *) data; ebitmap_t e_tmp; policy_module_t *mod = state->cur; - ebitmap_node_t *tnode; symtab_t *typetab; type = (type_datum_t *) datum; @@ -1181,13 +1161,8 @@ static int type_fix_callback(hashtab_key_t key, hashtab_datum_t datum, } ebitmap_init(&e_tmp); - ebitmap_for_each_positive_bit(&type->types, tnode, i) { - assert(mod->map[SYM_TYPES][i]); - if (ebitmap_set_bit - (&e_tmp, mod->map[SYM_TYPES][i] - 1, 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&type->types, &e_tmp, mod->map[SYM_TYPES])) + goto cleanup; if (ebitmap_union(&new_type->types, &e_tmp)) { goto cleanup; } @@ -1269,9 +1244,8 @@ static int copy_avrule_list(avrule_t * list, avrule_t ** dst, new_rule->specified = cur->specified; new_rule->flags = cur->flags; if (type_set_convert - (&cur->stypes, &new_rule->stypes, module, state) == -1 - || type_set_convert(&cur->ttypes, &new_rule->ttypes, module, - state) == -1) { + (&cur->stypes, &new_rule->stypes, module) == -1 + || type_set_convert(&cur->ttypes, &new_rule->ttypes, module) == -1) { goto cleanup; } @@ -1355,8 +1329,6 @@ static int copy_role_trans_list(role_trans_rule_t * list, policy_module_t * module, link_state_t * state) { role_trans_rule_t *cur, *new_rule = NULL, *tail; - unsigned int i; - ebitmap_node_t *cnode; cur = list; tail = *dst; @@ -1374,19 +1346,12 @@ static int copy_role_trans_list(role_trans_rule_t * list, if (role_set_or_convert (&cur->roles, &new_rule->roles, module, state) || type_set_or_convert(&cur->types, &new_rule->types, - module, state)) { + module)) { goto cleanup; } - ebitmap_for_each_positive_bit(&cur->classes, cnode, i) { - assert(module->map[SYM_CLASSES][i]); - if (ebitmap_set_bit(&new_rule->classes, - module-> - map[SYM_CLASSES][i] - 1, - 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&cur->classes, &new_rule->classes, module->map[SYM_CLASSES])) + goto cleanup; new_rule->new_role = module->map[SYM_ROLES][cur->new_role - 1]; @@ -1476,8 +1441,8 @@ static int copy_filename_trans_list(filename_trans_rule_t * list, if (!new_rule->name) goto err; - if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module, state) || - type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module, state)) + if (type_set_or_convert(&cur->stypes, &new_rule->stypes, module) || + type_set_or_convert(&cur->ttypes, &new_rule->ttypes, module)) goto err; new_rule->tclass = module->map[SYM_CLASSES][cur->tclass - 1]; @@ -1497,8 +1462,6 @@ static int copy_range_trans_list(range_trans_rule_t * rules, policy_module_t * mod, link_state_t * state) { range_trans_rule_t *rule, *new_rule = NULL; - unsigned int i; - ebitmap_node_t *cnode; for (rule = rules; rule; rule = rule->next) { new_rule = @@ -1512,21 +1475,15 @@ static int copy_range_trans_list(range_trans_rule_t * rules, *dst = new_rule; if (type_set_convert(&rule->stypes, &new_rule->stypes, - mod, state)) + mod)) goto cleanup; if (type_set_convert(&rule->ttypes, &new_rule->ttypes, - mod, state)) + mod)) goto cleanup; - ebitmap_for_each_positive_bit(&rule->tclasses, cnode, i) { - assert(mod->map[SYM_CLASSES][i]); - if (ebitmap_set_bit - (&new_rule->tclasses, - mod->map[SYM_CLASSES][i] - 1, 1)) { - goto cleanup; - } - } + if (ebitmap_convert(&rule->tclasses, &new_rule->tclasses, mod->map[SYM_CLASSES])) + goto cleanup; if (mls_range_convert(&rule->trange, &new_rule->trange, mod, state)) goto cleanup; @@ -1688,15 +1645,12 @@ static int copy_scope_index(scope_index_t * src, scope_index_t * dest, } dest->class_perms_len = largest_mapped_class_value; for (i = 0; i < src->class_perms_len; i++) { - ebitmap_t *srcmap = src->class_perms_map + i; + const ebitmap_t *srcmap = src->class_perms_map + i; ebitmap_t *destmap = dest->class_perms_map + module->map[SYM_CLASSES][i] - 1; - ebitmap_for_each_positive_bit(srcmap, node, j) { - if (ebitmap_set_bit(destmap, module->perm_map[i][j] - 1, - 1)) { - goto cleanup; - } - } + + if (ebitmap_convert(srcmap, destmap, module->perm_map[i])) + goto cleanup; } return 0; From patchwork Thu Jun 16 13:14:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 12883850 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 688F0CCA47A for ; Thu, 16 Jun 2022 13:14:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376387AbiFPNOT (ORCPT ); Thu, 16 Jun 2022 09:14:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376998AbiFPNOP (ORCPT ); Thu, 16 Jun 2022 09:14:15 -0400 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0124E3981B for ; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id b8so2121553edj.11 for ; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=UTWtabnJa7Xg8h74E8kl3qJqlm+q/2RlSTvMbZVkOyg=; b=aaeywK2+88GJN0Xj8XfnhMAxu40IqADOWr68wIMClivgZgjB0tynt5iINdM1uo5ttp mWcp1xiVu6hpm2y3rgFizgKHd07zRrVB5/M1WUyxGLRIuU28ADtVcSzsjUE98395Mtx6 VHhLrT5H80xAbBFcNQSt0nVONn6zkcGg6sAQuzoVNBVfzI0v+Mie/oBKbM7IbBYhQkTt vkidfAbWm8hM1IoBY3mcK8gMX9lTil4YePghqpYg6W2KlkilxEuVYYV0IelQS66Usr35 FLc+R6zwOc2wCeHn/qVKa84I8LsXakn/SzuI67zp9UU7UBFOQAZhFIjtjyQDfmXnr2H6 KTHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UTWtabnJa7Xg8h74E8kl3qJqlm+q/2RlSTvMbZVkOyg=; b=vPY70XkSt/c3iuDLVidPJHTgLptMLQPiivSxwJDUdreIxqo9z8a+Pf4JPTnnHsEMuS IUVCTrqgdK9DIALLgveMGfb2VsMfHv7I6D2LSLVTC8czOYk6yuMJGahRm6x9R9tIBYNq HnLhnikOhm+ULrNC63XoE7PU2MPsHAYJG640IOeWO2+uT4RssF5MtD7ee0Vgv0p0W+xr xIQLMuSod978CVE86KTdrlCZhYTjZD/KfvIOY7auruOVtNeZRI8sfjUXWoNu8YGvr5eV wXzfWBvD9XHorkdc16XRQgjT0692eB/jJH+E310IWkj7LaM3jVMZ8Ft6RUYEiBSEa+lF feyQ== X-Gm-Message-State: AJIora8xooT0Xot2Ickfx2B2oiD30YYe9jGG7pNuypaKk/ESgD9oBWsS Xxm40XiY0tCnqlvnHn+QizipSKrfJeMlXA== X-Google-Smtp-Source: AGRyM1s88q2p1rXmq2ugx+QkGrpRIwQHZToBPvpDNgFV/25HCPdOsuaEzgxXurZhAteIGVBYPcLRLg== X-Received: by 2002:aa7:d895:0:b0:42e:985:40f7 with SMTP id u21-20020aa7d895000000b0042e098540f7mr6384607edq.351.1655385253491; Thu, 16 Jun 2022 06:14:13 -0700 (PDT) Received: from debianHome.localdomain (dynamic-077-008-158-068.77.8.pool.telefonica.de. [77.8.158.68]) by smtp.gmail.com with ESMTPSA id y11-20020a056402270b00b0042e1cbc4471sm1831530edd.3.2022.06.16.06.14.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jun 2022 06:14:13 -0700 (PDT) From: =?utf-8?q?Christian_G=C3=B6ttsche?= To: selinux@vger.kernel.org Subject: [RFC PATCH 2/4] libsepol: add ebitmap iterator wrapper with startnode Date: Thu, 16 Jun 2022 15:14:07 +0200 Message-Id: <20220616131409.23271-2-cgzones@googlemail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220616131409.23271-1-cgzones@googlemail.com> References: <20220616131409.23271-1-cgzones@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Similar like ebitmap_for_each_bit() iterates over all bits of an ebitmap add ebitmap_for_each_bit_starting() iterating over all bits starting from a specific node and bit, which can be from an outer iteration. Signed-off-by: Christian Göttsche --- libsepol/include/sepol/policydb/ebitmap.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h index 81d0c7a6..83ff54c2 100644 --- a/libsepol/include/sepol/policydb/ebitmap.h +++ b/libsepol/include/sepol/policydb/ebitmap.h @@ -80,6 +80,13 @@ static inline int ebitmap_node_get_bit(const ebitmap_node_t * n, unsigned int bi #define ebitmap_for_each_positive_bit(e, n, bit) \ ebitmap_for_each_bit(e, n, bit) if (ebitmap_node_get_bit(n, bit)) \ +#define ebitmap_for_each_bit_starting(e, startnode, startbit, n, bit) \ + n = startnode; \ + for (bit = ebitmap_next(&n, startbit); bit < ebitmap_length(e); bit = ebitmap_next(&n, bit)) \ + +#define ebitmap_for_each_positive_bit_starting(e, startnode, startbit, n, bit) \ + ebitmap_for_each_bit_starting(e, startnode, startbit, n, bit) if (ebitmap_node_get_bit(n, bit)) \ + extern int ebitmap_cmp(const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_or(ebitmap_t * dst, const ebitmap_t * e1, const ebitmap_t * e2); extern int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1); From patchwork Thu Jun 16 13:14:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 12883851 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7AC7CCA480 for ; Thu, 16 Jun 2022 13:14:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376631AbiFPNOT (ORCPT ); Thu, 16 Jun 2022 09:14:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376977AbiFPNOR (ORCPT ); Thu, 16 Jun 2022 09:14:17 -0400 Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 006A33A18A for ; Thu, 16 Jun 2022 06:14:15 -0700 (PDT) Received: by mail-ed1-x529.google.com with SMTP id x62so2123048ede.10 for ; Thu, 16 Jun 2022 06:14:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=1VQk7uSarjgterSt9hTn1PKGN1dHxFTjyiiltAudmPE=; b=ObIJfOuwuGyRDIdeMy1af4dyjGC2iNyFQ8jpa++I6xatYr40+zEO/EHk4pO3Om7oxz wUtvawwjlR44ga5aBnKEfUrpXtPlHetWhLJhJqpZ0NwbCRJZxvmyCAEAx32rsmzJbr+I bdqVGE0WlI20OfjsqBCs1vMUvCHn1iPeYyjgQFWQB8pxAYDIwwedED2jx2YrjCu0Y0tu FqQPTXMNMMiHomz4aSyWtjVYlZVYH//bchDvTh41C7bh03OksY5LE7B9vb5lTebdmhP+ wa+7675sxlacnJz0/YSmmQXkjcOBa8b3NfVSzEvMt6ZnDxiPSCBsGdCKtCnTbsnONbTW FaRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1VQk7uSarjgterSt9hTn1PKGN1dHxFTjyiiltAudmPE=; b=FdhHoyqHTaaBeP8/ZYe4iRclQEeYTVZruyIy5ZYTaZF+2MQ9ASUiiEfcKKBcf7wJRd WhU6XTPyiOA/rwX+4cZgKDPjg4hr71pk9Ji2ZejVixCA99+Z403i1Hua3uW9Nc+h5KT7 XyZ1Ljq3VwMhsOhdowrPaVNPqDj7UuaYMwlemVSBAbicWYrG5mf+Urw0F3YSw1o0777Q xJalD5NsLzRzq4xNHXPSi/EsCVYvF/jdfz0ZZ65Iw1fjHEeK1ATU3hfMiPgZcqF0Cm3r YqphOsjrBPZiGwych4Pk0D7zLJkTZt77yqr4HdjV/DwHGokScIf3l3fPcZiKPzE1z5Ux T6KQ== X-Gm-Message-State: AJIora/irUnLDa8vKaF8bl4r69GA11urw3OYHv/pUjYgO4WCrpjzqDOM 55RmPGUKar5M5eQRD0Hjn7BTrp2b2IyK/A== X-Google-Smtp-Source: AGRyM1uKYarBzrGR+ICh4aGUjxgzW5G8M7sTz9P7AOz+teGJIHTBXzWsPvSdIHH6GVsj1vrQaetLCw== X-Received: by 2002:a05:6402:27cf:b0:431:54d9:28ed with SMTP id c15-20020a05640227cf00b0043154d928edmr6378472ede.81.1655385254190; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) Received: from debianHome.localdomain (dynamic-077-008-158-068.77.8.pool.telefonica.de. [77.8.158.68]) by smtp.gmail.com with ESMTPSA id y11-20020a056402270b00b0042e1cbc4471sm1831530edd.3.2022.06.16.06.14.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jun 2022 06:14:13 -0700 (PDT) From: =?utf-8?q?Christian_G=C3=B6ttsche?= To: selinux@vger.kernel.org Subject: [RFC PATCH 3/4] libsepol: add compile-time constraint for mutual exclusive attributes Date: Thu, 16 Jun 2022 15:14:08 +0200 Message-Id: <20220616131409.23271-3-cgzones@googlemail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220616131409.23271-1-cgzones@googlemail.com> References: <20220616131409.23271-1-cgzones@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Add a new compile-time constraint, similar to neverallow, which enables to specify two or more type attributes to be mutual exclusive. This means no type can be associated with more than one of them. The constraints are stored as a linked-list in the policy for modular policies, by a new modular policy version, and are discarded in kernel policies, not needing any kernel support. Some Reference Policy examples: unpriv_userdomain, admindomain: client_packet_type, server_packet_type: auth_file_type, non_auth_file_type: pseudofs, xattrfs, noxattrfs: reserved_port_type, unreserved_port_type: security_file_type, non_security_file_type: libsepol.check_segregate_attributes: segregate_attributes violated by type dnssec_t associated with attributes security_file_type and non_security_file_type ibendport_type, packet_type, sysctl_type, device_node, ibpkey_type, sysfs_types, domain, boolean_type, netif_type, file_type, node_type, proc_type, port_type: libsepol.check_segregate_attributes: segregate_attributes violated by type virt_content_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type sysctl_fs_t associated with attributes sysctl_type and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type initrc_devpts_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type qemu_image_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type user_devpts_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type dockerc_t associated with attributes domain and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type cpu_online_t associated with attributes sysfs_types and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type cardmgr_dev_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type sysctl_t associated with attributes sysctl_type and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type bootloader_tmp_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type xen_image_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type svirt_prot_exec_image_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type xen_devpts_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type proc_t associated with attributes file_type and proc_type libsepol.check_segregate_attributes: segregate_attributes violated by type sysfs_t associated with attributes sysfs_types and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type proc_xen_t associated with attributes file_type and proc_type libsepol.check_segregate_attributes: segregate_attributes violated by type svirt_image_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type virt_image_t associated with attributes device_node and file_type libsepol.check_segregate_attributes: segregate_attributes violated by type container_file_t associated with attributes device_node and file_type libsepol.check_assertions: 20 segregate attribute failures occurred Closes: https://github.com/SELinuxProject/selinux/issues/42 Signed-off-by: Christian Göttsche --- libsepol/include/sepol/policydb/policydb.h | 18 +++++- libsepol/src/assertion.c | 59 ++++++++++++++++- libsepol/src/expand.c | 56 +++++++++++++++- libsepol/src/link.c | 57 ++++++++++++++++ libsepol/src/policydb.c | 75 ++++++++++++++++++++++ libsepol/src/policydb_validate.c | 29 +++++++++ libsepol/src/write.c | 34 +++++++++- 7 files changed, 323 insertions(+), 5 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index de0068a6..b4a78e2f 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -192,6 +192,16 @@ typedef struct type_datum { uint32_t bounds; /* bounds type, if exist */ } type_datum_t; +/* Mutual exclusive attributes */ +typedef struct segregate_attribute { + ebitmap_t attrs; /* mutual exclusive attributes */ + unsigned long line; /* line number from policy.conf where this rule originated */ + /* source file name and line number (e.g. .te file) */ + char *source_filename; + unsigned long source_line; + struct segregate_attribute *next; +} segregate_attribute_t; + /* * Properties of type_datum * available on the policy version >= (MOD_)POLICYDB_VERSION_BOUNDARY @@ -605,6 +615,9 @@ typedef struct policydb { bitmaps. Someday the 0 bit may be used for global permissive */ ebitmap_t permissive_map; + /* mutual exclusive attributes (not preserved in kernel policy) */ + segregate_attribute_t *segregate_attributes; + unsigned policyvers; unsigned handle_unknown; @@ -696,6 +709,8 @@ extern void level_datum_init(level_datum_t * x); extern void level_datum_destroy(level_datum_t * x); extern void cat_datum_init(cat_datum_t * x); extern void cat_datum_destroy(cat_datum_t * x); +extern void segregate_attribute_init(segregate_attribute_t * x); +extern void segregate_attribute_destroy(segregate_attribute_t * x); extern int check_assertion(policydb_t *p, avrule_t *avrule); extern int check_assertions(sepol_handle_t * handle, policydb_t * p, avrule_t * avrules); @@ -783,9 +798,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define MOD_POLICYDB_VERSION_INFINIBAND 19 #define MOD_POLICYDB_VERSION_GLBLUB 20 #define MOD_POLICYDB_VERSION_SELF_TYPETRANS 21 +#define MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE 22 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SELF_TYPETRANS +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE #define POLICYDB_CONFIG_MLS 1 diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index 161874c3..28a9c55f 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -36,7 +36,7 @@ struct avtab_match_args { unsigned long errors; }; -static const char* policy_name(policydb_t *p) { +static const char* policy_name(const policydb_t *p) { const char *policy_file = "policy.conf"; if (p->name) { policy_file = p->name; @@ -535,6 +535,53 @@ int check_assertion(policydb_t *p, avrule_t *avrule) return rc; } +static int check_segregate_attributes(sepol_handle_t *handle, const policydb_t *p) +{ + int errors = 0; + const segregate_attribute_t *sattr; + + for (sattr = p->segregate_attributes; sattr; sattr = sattr->next) { + ebitmap_node_t *first_node; + unsigned int first_bit; + + ebitmap_for_each_positive_bit(&sattr->attrs, first_node, first_bit) { + ebitmap_node_t *second_node; + unsigned int second_bit; + + ebitmap_for_each_positive_bit_starting(&sattr->attrs, first_node, first_bit, second_node, second_bit) { + ebitmap_t attr_union; + ebitmap_node_t *type_node; + unsigned int type_bit; + + if (ebitmap_and(&attr_union, &p->attr_type_map[first_bit], &p->attr_type_map[second_bit])) + return -1; + + ebitmap_for_each_positive_bit(&attr_union, type_node, type_bit) { + if (sattr->source_filename) + ERR(handle, "segregate_attributes on line %lu of %s (or line %lu of %s) violated by " + "type %s associated with attributes %s and %s", + sattr->source_line, sattr->source_filename, sattr->line, policy_name(p), + p->p_type_val_to_name[type_bit], p->p_type_val_to_name[first_bit], p->p_type_val_to_name[second_bit]); + else if (sattr->line) + ERR(handle, "segregate_attributes on line %lu of %s violated by " + "type %s associated with attributes %s and %s", + sattr->line, policy_name(p), + p->p_type_val_to_name[type_bit], p->p_type_val_to_name[first_bit], p->p_type_val_to_name[second_bit]); + else + ERR(handle, "segregate_attributes violated by " + "type %s associated with attributes %s and %s", + p->p_type_val_to_name[type_bit], p->p_type_val_to_name[first_bit], p->p_type_val_to_name[second_bit]); + errors++; + } + + ebitmap_destroy(&attr_union); + } + } + } + + return errors; +} + int check_assertions(sepol_handle_t * handle, policydb_t * p, avrule_t * avrules) { @@ -570,5 +617,15 @@ int check_assertions(sepol_handle_t * handle, policydb_t * p, if (errors) ERR(handle, "%lu neverallow failures occurred", errors); + rc = check_segregate_attributes(handle, p); + if (rc < 0) { + ERR(handle, "Error occurred while checking segregate attributes"); + return -1; + } + if (rc) { + ERR(handle, "%d segregate attribute failures occurred", rc); + errors += rc; + } + return errors ? -1 : 0; } diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 8d19850e..483f6905 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -56,7 +56,7 @@ static void expand_state_init(expand_state_t * state) memset(state, 0, sizeof(expand_state_t)); } -static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) +static int map_ebitmap(const ebitmap_t * src, ebitmap_t * dst, const uint32_t * map) { unsigned int i; ebitmap_node_t *tnode; @@ -2341,6 +2341,56 @@ static int genfs_copy(expand_state_t * state) return 0; } +static int segregate_attribute_copy(expand_state_t *state) +{ + const segregate_attribute_t *old; + segregate_attribute_t *list = NULL; + + for (old = state->base->segregate_attributes; old; old = old->next) { + segregate_attribute_t *new; + + new = calloc(1, sizeof(segregate_attribute_t)); + if (!new) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + new->next = NULL; + new->line = old->line; + new->source_line = old->source_line; + if (old->source_filename) { + new->source_filename = strdup(old->source_filename); + if (!new->source_filename) { + ERR(state->handle, "Out of memory!"); + free(new); + return -1; + } + } + + if (map_ebitmap(&old->attrs, &new->attrs, state->typemap)) { + ERR(state->handle, "out of memory"); + ebitmap_destroy(&new->attrs); + free(new->source_filename); + free(new); + return -1; + } + + if (list) + list->next = new; + else { + if (state->out->segregate_attributes) { + segregate_attribute_t *s; + for (s = state->out->segregate_attributes; s->next; s = s->next) {} + s->next = new; + } else + state->out->segregate_attributes = new; + } + list = new; + } + + return 0; +} + static int type_attr_map(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *ptr) @@ -3173,6 +3223,10 @@ int expand_module(sepol_handle_t * handle, if (genfs_copy(&state)) goto cleanup; + /* copy segregate attributes */ + if (segregate_attribute_copy(&state)) + goto cleanup; + /* Build the type<->attribute maps and remove attributes. */ state.out->attr_type_map = calloc(state.out->p_types.nprim, sizeof(ebitmap_t)); diff --git a/libsepol/src/link.c b/libsepol/src/link.c index cbe4cea4..04f8b2cf 100644 --- a/libsepol/src/link.c +++ b/libsepol/src/link.c @@ -1857,6 +1857,58 @@ static int scope_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return -1; } +static int copy_segregate_attributes(link_state_t * state, const policy_module_t *module) +{ + const segregate_attribute_t *src_sattr; + segregate_attribute_t *list = NULL; + + for (src_sattr = module->policy->segregate_attributes; src_sattr; src_sattr = src_sattr->next) { + segregate_attribute_t *new_sattr; + + new_sattr = calloc(1, sizeof(segregate_attribute_t)); + if (!new_sattr) { + ERR(state->handle, "Out of memory!"); + return -1; + } + + ebitmap_init(&new_sattr->attrs); + if (ebitmap_convert(&src_sattr->attrs, &new_sattr->attrs, module->map[SYM_TYPES])) { + ebitmap_destroy(&new_sattr->attrs); + free(new_sattr); + ERR(state->handle, "Out of memory!"); + return -1; + } + + new_sattr->line = src_sattr->line; + + if (src_sattr->source_filename) { + new_sattr->source_filename = strdup(src_sattr->source_filename); + if (!new_sattr->source_filename) { + ebitmap_destroy(&new_sattr->attrs); + free(new_sattr); + ERR(state->handle, "Out of memory!"); + return -1; + } + } + + new_sattr->source_line = src_sattr->source_line; + + if (list) + list->next = new_sattr; + else { + if (state->base->segregate_attributes) { + segregate_attribute_t *s; + for (s = state->base->segregate_attributes; s->next; s = s->next) {} + s->next = new_sattr; + } else + state->base->segregate_attributes = new_sattr; + } + list = new_sattr; + } + + return 0; +} + /* Copy a module over to a base, remapping all values within. After * all identifiers and rules are done, copy the scoping information. * This is when it checks for duplicate declarations. */ @@ -1891,6 +1943,11 @@ static int copy_module(link_state_t * state, policy_module_t * module) } } + ret = copy_segregate_attributes(state, module); + if (ret) { + return ret; + } + return 0; } diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index fc260eb6..356e8268 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -334,6 +334,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, @@ -460,6 +467,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = 0, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, }; #if 0 @@ -760,6 +774,21 @@ void avrule_list_destroy(avrule_t * x) } } +void segregate_attribute_init(segregate_attribute_t * x) +{ + memset(x, 0, sizeof(segregate_attribute_t)); + ebitmap_init(&x->attrs); +} + + +void segregate_attribute_destroy(segregate_attribute_t * x) +{ + if (!x) + return; + ebitmap_destroy(&x->attrs); + free(x->source_filename); +} + /* * Initialize the role table by implicitly adding role 'object_r'. If * the policy is a module, set object_r's scope to be SCOPE_REQ, @@ -1492,6 +1521,7 @@ void policydb_destroy(policydb_t * p) unsigned int i; role_allow_t *ra, *lra = NULL; role_trans_t *tr, *ltr = NULL; + segregate_attribute_t *sattr, *sattr_next; if (!p) return; @@ -1585,6 +1615,12 @@ void policydb_destroy(policydb_t * p) free(p->attr_type_map); } + for (sattr = p->segregate_attributes; sattr; sattr = sattr_next) { + sattr_next = sattr->next; + segregate_attribute_destroy(sattr); + free(sattr); + } + return; } @@ -4174,6 +4210,39 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) return -1; } +static int segregate_attributes_read(policydb_t * p, struct policy_file *fp) +{ + segregate_attribute_t *list = NULL; + uint32_t buf, nel, i; + int rc; + + rc = next_entry(&buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + nel = le32_to_cpu(buf); + for (i = 0; i < nel; i++) { + segregate_attribute_t *sattr; + + sattr = calloc(1, sizeof(segregate_attribute_t)); + if (!sattr) + return -1; + + if (ebitmap_read(&sattr->attrs, fp) < 0) { + ebitmap_destroy(&sattr->attrs); + free(sattr); + return -1; + } + + if (list) + list->next = sattr; + else + p->segregate_attributes = sattr; + list = sattr; + } + + return 0; +} + static sepol_security_class_t policydb_string_to_security_class( struct policydb *policydb, const char *class_name) @@ -4570,6 +4639,12 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) } } + if (p->policyvers >= MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE && + p->policy_type != POLICY_KERN) { + if (segregate_attributes_read(p, fp)) + return POLICYDB_ERROR; + } + if (validate_policydb(fp->handle, p)) goto bad; diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index 99d4eb7f..be969036 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -1270,6 +1270,32 @@ bad: return -1; } +static int validate_segregate_attributes(sepol_handle_t *handle, policydb_t *p, validate_t flavors[]) +{ + segregate_attribute_t *sattr; + ebitmap_node_t *node; + unsigned int i; + + for (sattr = p->segregate_attributes; sattr; sattr = sattr->next) { + if (ebitmap_cardinality(&sattr->attrs) < 2) + goto bad; + + if (validate_ebitmap(&sattr->attrs, &flavors[SYM_TYPES])) + goto bad; + + ebitmap_for_each_positive_bit(&sattr->attrs, node, i) { + if (p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) + goto bad; + } + } + + return 0; + +bad: + ERR(handle, "Invalid segregate attribute definition"); + return -1; +} + static int validate_properties(sepol_handle_t *handle, policydb_t *p) { switch (p->policy_type) { @@ -1376,6 +1402,9 @@ int validate_policydb(sepol_handle_t *handle, policydb_t *p) if (validate_permissives(handle, p, flavors)) goto bad; + if (validate_segregate_attributes(handle, p, flavors)) + goto bad; + validate_array_destroy(flavors); return 0; diff --git a/libsepol/src/write.c b/libsepol/src/write.c index 48ed21ea..d5c6df16 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -58,9 +58,9 @@ struct policy_data { static int avrule_write_list(policydb_t *p, avrule_t * avrules, struct policy_file *fp); -static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) +static int ebitmap_write(const ebitmap_t * e, struct policy_file *fp) { - ebitmap_node_t *n; + const ebitmap_node_t *n; uint32_t buf[32], bit, count; uint64_t map; size_t items; @@ -2189,6 +2189,30 @@ static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)), return 0; } +static int segregate_attributes_write(const policydb_t *p, struct policy_file *fp) +{ + const segregate_attribute_t *sattr; + size_t items; + uint32_t buf, count = 0; + + for (sattr = p->segregate_attributes; sattr; sattr = sattr->next) { + if (__builtin_add_overflow(count, 1, &count)) + return POLICYDB_ERROR; + } + + buf = cpu_to_le32(count); + items = put_entry(&buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + + for (sattr = p->segregate_attributes; sattr; sattr = sattr->next) { + if (ebitmap_write(&sattr->attrs, fp)) + return POLICYDB_ERROR; + } + + return POLICYDB_SUCCESS; +} + /* * Write the configuration data in a policy database * structure to a policy database binary representation @@ -2411,5 +2435,11 @@ int policydb_write(policydb_t * p, struct policy_file *fp) } } + if (p->policyvers >= MOD_POLICYDB_VERSION_SEGREGATEATTRIBUTE && + p->policy_type != POLICY_KERN) { + if (segregate_attributes_write(p, fp)) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; } From patchwork Thu Jun 16 13:14:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 12883852 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DA36CC433EF for ; Thu, 16 Jun 2022 13:14:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234971AbiFPNOU (ORCPT ); Thu, 16 Jun 2022 09:14:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376938AbiFPNOR (ORCPT ); Thu, 16 Jun 2022 09:14:17 -0400 Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B6E926AEA for ; Thu, 16 Jun 2022 06:14:16 -0700 (PDT) Received: by mail-ed1-x52a.google.com with SMTP id cn20so2145645edb.6 for ; Thu, 16 Jun 2022 06:14:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=gLONVdGYOb35y+62hTaYz+Ej29o7Qj4Q6LBLaJU8b/E=; b=dufuDBwNNuUkrfyNKq6T+culdR6eoJ0Eu9K4Uw0Ke0PWAqCaGXZ/MY3zB2nHw4FrtH ujaWvZ03sq7hnk68NexM2gWRt8zdnMNZbWYU50ph8Tn2NoMFfv2WBYM1pXAirt4g/qcF THggL1DVpW7rWFfNn9Hui9np1AS3BzYwh3VJmkXbSdaxs+uWogV4alhWUD72/L0c2X1N UnxornkIMj+C73GWhk4h41kVbCZ/JIZzT/886AtWf+kOaVWYZOH9aYNhhMkV+OFNl3B7 ZiGVPBGAIS54T/yXnhx9qbK1RSK00iEsXLHsIu4P/whEUlUF6UvzDGuBm/XGXnQEn1tU ipUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gLONVdGYOb35y+62hTaYz+Ej29o7Qj4Q6LBLaJU8b/E=; b=MlX+uGTxmqU2DTeQvHAFgFw8W0f+n1Y78i+x9ZeKy83PPxYIlU11yHVwQ59vRUA+QB hCJZpA+mCbIbwRTFJMEtitwvzbrQk3EIxOJ6otXD/GBISP/kpl2gvCtmEU2wTEq5pLeR OAJzT2ewZXFjd7Xbnsh0REkJR3ZmJhQsAwCXFQpHOBJTpAu4vVcjwK8nqRgQ43m+r26I tr+DDMxbDKlJn/y1gMTtYx4d6bMsZjUDhjqVeGgsD1S4PqQ/gi7K9ji7LDCvplUqkDR4 voykcKuJ3XjEZS3e0VUp5g7xmvCWrjGIelDJLV287XkVEX6En/LFMLHpbVGeR4wh53re x/1Q== X-Gm-Message-State: AJIora9UQ1xxv60BB02Z/zDUVtHhxF26+buk5bcPFbu79/NS3wq+T2fm YAJeucK1eJHBRrfiwyqi9PaXhWjVNLDokg== X-Google-Smtp-Source: AGRyM1sffoe4XYoZRFHZnA2hW6HxPp81x8QZv09Woc9Z9WTXNghPWyd7MVj0xeygqJGA0rqX4DHcgA== X-Received: by 2002:a05:6402:f:b0:42e:561:a1c0 with SMTP id d15-20020a056402000f00b0042e0561a1c0mr6485181edu.309.1655385254801; Thu, 16 Jun 2022 06:14:14 -0700 (PDT) Received: from debianHome.localdomain (dynamic-077-008-158-068.77.8.pool.telefonica.de. [77.8.158.68]) by smtp.gmail.com with ESMTPSA id y11-20020a056402270b00b0042e1cbc4471sm1831530edd.3.2022.06.16.06.14.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jun 2022 06:14:14 -0700 (PDT) From: =?utf-8?q?Christian_G=C3=B6ttsche?= To: selinux@vger.kernel.org Subject: [RFC PATCH 4/4] checkpolicy: add front-end support for segregate attributes Date: Thu, 16 Jun 2022 15:14:09 +0200 Message-Id: <20220616131409.23271-4-cgzones@googlemail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220616131409.23271-1-cgzones@googlemail.com> References: <20220616131409.23271-1-cgzones@googlemail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Support specifying segregate attributes. The following two blocks are equivalent: segregate_attributes attr1, attr2, attr3; segregate_attributes attr1, attr2; segregate_attributes attr1, attr3; segregate_attributes attr2, attr3; Signed-off-by: Christian Göttsche --- checkpolicy/policy_define.c | 74 +++++++++++++++++++++++++++++++++++++ checkpolicy/policy_define.h | 1 + checkpolicy/policy_parse.y | 5 +++ checkpolicy/policy_scan.l | 2 + 4 files changed, 82 insertions(+) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 8bf36859..faa8c00f 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -1220,6 +1220,80 @@ exit: return rc; } +int define_segregate_attributes(void) +{ + char *id = NULL; + segregate_attribute_t *sattr = NULL; + int rc = -1; + + if (pass == 1) { + while ((id = queue_remove(id_queue))) + free(id); + return 0; + } + + sattr = malloc(sizeof(segregate_attribute_t)); + if (!sattr) { + yyerror("Out of memory!"); + goto exit; + } + + ebitmap_init(&sattr->attrs); + sattr->line = policydb_lineno; + sattr->source_line = source_lineno; + sattr->source_filename = strdup(source_file); + if (!sattr->source_filename) { + yyerror("Out of memory!"); + goto exit; + } + + while ((id = queue_remove(id_queue))) { + const type_datum_t *attr; + + if (!is_id_in_scope(SYM_TYPES, id)) { + yyerror2("attribute %s is not within scope", id); + goto exit; + } + + attr = hashtab_search(policydbp->p_types.table, id); + if (!attr) { + yyerror2("attribute %s is not declared", id); + goto exit; + } + + if (attr->flavor != TYPE_ATTRIB) { + yyerror2("%s is a type, not an attribute", id); + goto exit; + } + + if (ebitmap_get_bit(&sattr->attrs, attr->s.value - 1)) { + yyerror2("attribute %s used multiple times", id); + goto exit; + } + + if (ebitmap_set_bit(&sattr->attrs, attr->s.value - 1, TRUE)) { + yyerror("Out of memory!"); + goto exit; + } + + free(id); + } + + sattr->next = policydbp->segregate_attributes; + policydbp->segregate_attributes = sattr; + + sattr = NULL; + rc = 0; +exit: + if (sattr) { + free(sattr->source_filename); + ebitmap_destroy(&sattr->attrs); + free(sattr); + } + free(id); + return rc; +} + static int add_aliases_to_type(type_datum_t * type) { char *id; diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h index 50a7ba78..f55d0b17 100644 --- a/checkpolicy/policy_define.h +++ b/checkpolicy/policy_define.h @@ -68,6 +68,7 @@ int define_type(int alias); int define_user(void); int define_validatetrans(constraint_expr_t *expr); int expand_attrib(void); +int define_segregate_attributes(void); int insert_id(const char *id,int push); int insert_separator(int push); role_datum_t *define_role_dom(role_datum_t *r); diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index 45f973ff..acd6096d 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -104,6 +104,7 @@ typedef int (* require_func_t)(int pass); %token ALIAS %token ATTRIBUTE %token EXPANDATTRIBUTE +%token SEGREGATEATTRIBUTES %token BOOL %token TUNABLE %token IF @@ -320,6 +321,7 @@ rbac_decl : attribute_role_def ; te_decl : attribute_def | expandattribute_def + | segregateattributes_def | type_def | typealias_def | typeattribute_def @@ -337,6 +339,9 @@ attribute_def : ATTRIBUTE identifier ';' expandattribute_def : EXPANDATTRIBUTE names bool_val ';' { if (expand_attrib()) return -1;} ; +segregateattributes_def : SEGREGATEATTRIBUTES identifier ',' id_comma_list ';' + { if (define_segregate_attributes()) return -1;} + ; type_def : TYPE identifier alias_def opt_attr_list ';' {if (define_type(1)) return -1;} | TYPE identifier opt_attr_list ';' diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l index 9fefea7b..d865dcb6 100644 --- a/checkpolicy/policy_scan.l +++ b/checkpolicy/policy_scan.l @@ -123,6 +123,8 @@ ATTRIBUTE | attribute { return(ATTRIBUTE); } EXPANDATTRIBUTE | expandattribute { return(EXPANDATTRIBUTE); } +SEGREGATE_ATTRIBUTES | +segregate_attributes { return(SEGREGATEATTRIBUTES); } TYPE_TRANSITION | type_transition { return(TYPE_TRANSITION); } TYPE_MEMBER |