diff mbox series

[5/8] libsepol: implement new module binary format of avrule

Message ID 20230531114914.2237609-6-juraj@jurajmarcin.com (mailing list archive)
State Superseded
Delegated to: Petr Lautrbach
Headers show
Series checkpolicy, libsepol: add prefix/suffix matching to filename type transitions | expand

Commit Message

Juraj Marcin May 31, 2023, 11:49 a.m. UTC
Implement a new module policy format that closely matches the new
internal representation of avrule introduced in the previous patch.

This patch bumps the maximum module policy version and implements
reading/writing functions such that the module binary policy structure
matches its internal representation, namely, the object name attribute
used for the filename transition rules.

These changes have no significant effect on the size of the module
policy file (tested with Fedora policy).

Reviewed-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Juraj Marcin <juraj@jurajmarcin.com>
---
 libsepol/include/sepol/policydb/policydb.h |  3 ++-
 libsepol/src/policydb.c                    | 28 ++++++++++++++++++++++
 libsepol/src/write.c                       | 24 ++++++++++++++++---
 3 files changed, 51 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 528c1cad..5efd0a47 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -749,9 +749,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_AVRULE_FTRANS	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_AVRULE_FTRANS
 
 #define POLICYDB_CONFIG_MLS    1
 
diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
index f2271524..3776292a 100644
--- a/libsepol/src/policydb.c
+++ b/libsepol/src/policydb.c
@@ -341,6 +341,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_AVRULE_FTRANS,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_IBENDPORT + 1,
+	 .target_platform = SEPOL_TARGET_SELINUX,
+	},
 	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BASE,
@@ -467,6 +474,13 @@  static const struct policydb_compat_info policydb_compat[] = {
 	 .ocon_num = 0,
 	 .target_platform = SEPOL_TARGET_SELINUX,
 	},
+	{
+	 .type = POLICY_MOD,
+	 .version = MOD_POLICYDB_VERSION_AVRULE_FTRANS,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = 0,
+	 .target_platform = SEPOL_TARGET_SELINUX,
+	},
 };
 
 #if 0
@@ -3202,6 +3216,19 @@  static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp)
 		tail = cur;
 	}
 
+	if (p->policyvers >= MOD_POLICYDB_VERSION_AVRULE_FTRANS &&
+	    avrule->specified & AVRULE_TRANSITION) {
+		rc = next_entry(buf, fp, sizeof(uint32_t));
+		if (rc < 0)
+			goto bad;
+		len = le32_to_cpu(*buf);
+		if (len) {
+			rc = str_read(&avrule->object_name, fp, len);
+			if (rc < 0)
+				goto bad;
+		}
+	}
+
 	if (avrule->specified & AVRULE_XPERMS) {
 		uint8_t buf8;
 		size_t nel = ARRAY_SIZE(avrule->xperms->perms);
@@ -3633,6 +3660,7 @@  static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
 	}
 
 	if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
+	    p->policyvers < MOD_POLICYDB_VERSION_AVRULE_FTRANS &&
 	    filename_trans_rule_read(p, &decl->avrules, fp))
 		return -1;
 
diff --git a/libsepol/src/write.c b/libsepol/src/write.c
index 12f14670..5ba3f2b0 100644
--- a/libsepol/src/write.c
+++ b/libsepol/src/write.c
@@ -2024,8 +2024,9 @@  static int avrule_write(policydb_t *p, avrule_t * avrule,
 	uint32_t buf[32], len;
 	class_perm_node_t *cur;
 
-	/* skip filename transitions for now */
-	if (avrule->specified & AVRULE_TRANSITION && avrule->object_name)
+	/* skip filename transitions if writing older version without name */
+	if (p->policyvers < MOD_POLICYDB_VERSION_AVRULE_FTRANS &&
+	    avrule->specified & AVRULE_TRANSITION && avrule->object_name)
 		return POLICYDB_SUCCESS;
 
 	if (p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS &&
@@ -2072,6 +2073,21 @@  static int avrule_write(policydb_t *p, avrule_t * avrule,
 		cur = cur->next;
 	}
 
+	if (p->policyvers >= MOD_POLICYDB_VERSION_AVRULE_FTRANS &&
+	    avrule->specified & AVRULE_TRANSITION) {
+		len = avrule->object_name ? strlen(avrule->object_name) : 0;
+		*buf = cpu_to_le32(len);
+		items = put_entry(buf, sizeof(uint32_t), 1, fp);
+		if (items != 1)
+			return POLICYDB_ERROR;
+		if (avrule->object_name) {
+			items = put_entry(avrule->object_name, sizeof(char),
+					  len, fp);
+			if (items != len)
+				return POLICYDB_ERROR;
+		}
+	}
+
 	if (avrule->specified & AVRULE_XPERMS) {
 		size_t nel = ARRAY_SIZE(avrule->xperms->perms);
 		uint32_t buf32[nel];
@@ -2121,7 +2137,8 @@  static int avrule_write_list(policydb_t *p, avrule_t * avrules,
 	avrule = avrules;
 	len = 0;
 	while (avrule) {
-		if (!(avrule->specified & AVRULE_TRANSITION &&
+		if (p->policyvers >= MOD_POLICYDB_VERSION_AVRULE_FTRANS ||
+		    !(avrule->specified & AVRULE_TRANSITION &&
 		      avrule->object_name))
 			len++;
 		avrule = avrule->next;
@@ -2356,6 +2373,7 @@  static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms,
 	}
 
 	if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
+	    p->policyvers < MOD_POLICYDB_VERSION_AVRULE_FTRANS &&
 	    filename_trans_rule_write(p, decl->avrules, fp))
 		return POLICYDB_ERROR;