diff --git a/Optimized-the-way-libsepol-policy-are-generated.patch b/Optimized-the-way-libsepol-policy-are-generated.patch new file mode 100644 index 0000000..9db24dc --- /dev/null +++ b/Optimized-the-way-libsepol-policy-are-generated.patch @@ -0,0 +1,272 @@ +From ae864f32d4f70e789d5dc3eec74525e508df1720 Mon Sep 17 00:00:00 2001 +From: jinlun +Date: Mon, 28 Apr 2025 10:00:40 +0800 +Subject: [PATCH] Optimized the way libsepol policy are generated + +There are optimization patches in the kernel community that can save + the memory space of the policy, which causes the results of the + /sys/fs/selinux/policy generated by the kernel to be inconsistent + with the policy generated bt the call sepol_policydb_read. + +--- + libsepol-3.5/include/sepol/policydb.h | 3 + + .../include/sepol/policydb/policydb.h | 4 + + libsepol-3.5/src/hashtab.c | 9 +- + libsepol-3.5/src/libsepol.map.in | 1 + + libsepol-3.5/src/policydb.c | 86 +++++++++++++++++-- + libsepol-3.5/src/policydb_public.c | 5 ++ + 6 files changed, 98 insertions(+), 10 deletions(-) + +diff --git a/libsepol-3.5/include/sepol/policydb.h b/libsepol-3.5/include/sepol/policydb.h +index 792913d..0f74467 100644 +--- a/libsepol-3.5/include/sepol/policydb.h ++++ b/libsepol-3.5/include/sepol/policydb.h +@@ -111,6 +111,7 @@ extern int sepol_policydb_optimize(sepol_policydb_t * p); + * image contents. + */ + extern int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf); ++extern int sepol_policydb_read_canonicalize(sepol_policydb_t * p, sepol_policy_file_t * pf); + + /* + * Write a policydb to a policy file. +diff --git a/libsepol-3.5/include/sepol/policydb/policydb.h b/libsepol-3.5/include/sepol/policydb/policydb.h +index ef1a014..5a84aba 100644 +--- a/libsepol-3.5/include/sepol/policydb/policydb.h ++++ b/libsepol-3.5/include/sepol/policydb/policydb.h +@@ -727,6 +727,10 @@ extern void policy_file_init(policy_file_t * x); + + extern int policydb_read(policydb_t * p, struct policy_file *fp, + unsigned int verbose); ++extern int policydb_read_canonicalize(policydb_t * p, struct policy_file *fp, ++ unsigned int verbose); ++ ++ + extern int avrule_read_list(policydb_t * p, avrule_t ** avrules, + struct policy_file *fp); + +diff --git a/libsepol-3.5/src/hashtab.c b/libsepol-3.5/src/hashtab.c +index 6f01d09..1d6825b 100644 +--- a/libsepol-3.5/src/hashtab.c ++++ b/libsepol-3.5/src/hashtab.c +@@ -34,15 +34,22 @@ + + #include "private.h" + ++static size_t hashtab_compute_size(size_t nel) ++{ ++ if (nel == 0) ++ return 0; ++ return (size_t)(1 << (32 - __builtin_clz((nel) - 1))); ++} + hashtab_t hashtab_create(unsigned int (*hash_value) (hashtab_t h, + const_hashtab_key_t key), + int (*keycmp) (hashtab_t h, + const_hashtab_key_t key1, + const_hashtab_key_t key2), +- unsigned int size) ++ unsigned int nel) + { + + hashtab_t p; ++ unsigned int size = hashtab_compute_size(nel); + + p = (hashtab_t) malloc(sizeof(hashtab_val_t)); + if (p == NULL) +diff --git a/libsepol-3.5/src/libsepol.map.in b/libsepol-3.5/src/libsepol.map.in +index 844924f..3061a66 100644 +--- a/libsepol-3.5/src/libsepol.map.in ++++ b/libsepol-3.5/src/libsepol.map.in +@@ -288,4 +288,5 @@ LIBSEPOL_3.4 { + sepol_string_to_av_perm; + sepol_string_to_security_class; + sepol_validate_transition_reason_buffer; ++ sepol_policydb_read_canonicalize; + } LIBSEPOL_3.0; +diff --git a/libsepol-3.5/src/policydb.c b/libsepol-3.5/src/policydb.c +index 21bcad7..ecc1480 100644 +--- a/libsepol-3.5/src/policydb.c ++++ b/libsepol-3.5/src/policydb.c +@@ -2090,7 +2090,7 @@ static int perm_read(policydb_t * p + return -1; + } + +-static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) ++static int common_read_pre(policydb_t * p, hashtab_t h, struct policy_file *fp, int canonicalize) + { + char *key = 0; + common_datum_t *comdatum; +@@ -2113,12 +2113,18 @@ static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + + comdatum->s.value = le32_to_cpu(buf[1]); + +- if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) ++ nel = le32_to_cpu(buf[3]); ++ ++ if (!canonicalize) ++ rc = symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE); ++ else ++ rc = symtab_init(&comdatum->permissions, nel); ++ ++ if (rc) + goto bad; + comdatum->permissions.nprim = le32_to_cpu(buf[2]); + if (comdatum->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; +- nel = le32_to_cpu(buf[3]); + + key = malloc(len + 1); + if (!key) +@@ -2143,6 +2149,16 @@ static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + return -1; + } + ++static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) ++{ ++ return common_read_pre(p, h, fp, 1); ++} ++ ++static int common_read_canonicalize(policydb_t * p, hashtab_t h, struct policy_file *fp) ++{ ++ return common_read_pre(p, h, fp, 1); ++} ++ + static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep, + unsigned int ncons, + int allowxtarget, struct policy_file *fp) +@@ -2238,7 +2254,7 @@ static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep, + return 0; + } + +-static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) ++static int class_read_pre(policydb_t * p, hashtab_t h, struct policy_file *fp, int canonicalize) + { + char *key = 0; + class_datum_t *cladatum; +@@ -2265,12 +2281,17 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + if (cladatum->s.value > UINT16_MAX) + goto bad; + +- if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) ++ nel = le32_to_cpu(buf[4]); ++ if (!canonicalize) ++ rc = symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE); ++ else ++ rc = symtab_init(&cladatum->permissions, nel); ++ if (rc) + goto bad; ++ + cladatum->permissions.nprim = le32_to_cpu(buf[3]); + if (cladatum->permissions.nprim > PERM_SYMTAB_SIZE) + goto bad; +- nel = le32_to_cpu(buf[4]); + + ncons = le32_to_cpu(buf[5]); + +@@ -2351,6 +2372,16 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + return -1; + } + ++static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) ++{ ++ return class_read_pre(p, h, fp, 0); ++} ++ ++static int class_read_canonicalize(policydb_t * p, hashtab_t h, struct policy_file *fp) ++{ ++ return class_read_pre(p, h, fp, 1); ++} ++ + static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + { + char *key = 0; +@@ -3507,6 +3538,11 @@ static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h, + common_read, class_read, role_read, type_read, user_read, + cond_read_bool, sens_read, cat_read,}; + ++static int (*read_f_canonicalize[SYM_NUM]) (policydb_t * p, hashtab_t h, ++ struct policy_file * fp) = { ++common_read_canonicalize, class_read_canonicalize, role_read, type_read, user_read, ++ cond_read_bool, sens_read, cat_read,}; ++ + /************** module reading functions below **************/ + + static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp) +@@ -4226,7 +4262,7 @@ static sepol_access_vector_t policydb_string_to_av_perm( + * Read the configuration data from a policy database binary + * representation file into a policy database structure. + */ +-int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) ++int policydb_read_pre(policydb_t * p, struct policy_file *fp, unsigned verbose, int canonicalize) + { + + unsigned int i, j, r_policyvers; +@@ -4444,9 +4480,26 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + ERR(fp->handle, "unexpected items in symbol table with no symbol"); + goto bad; + } +- for (j = 0; j < nel; j++) { +- if (read_f[i] (p, p->symtab[i].table, fp)) ++ ++ if (canonicalize) { ++ hashtab_destroy(p->symtab[i].table); ++ if (symtab_init(&p->symtab[i], nel)) + goto bad; ++ if (i == SYM_ROLES) { ++ if (roles_init(p)) ++ goto bad; ++ } ++ } ++ ++ ++ for (j = 0; j < nel; j++) { ++ if (canonicalize) { ++ if (read_f_canonicalize[i] (p, p->symtab[i].table, fp)) ++ goto bad; ++ } else { ++ if (read_f[i] (p, p->symtab[i].table, fp)) ++ goto bad; ++ } + } + + p->symtab[i].nprim = nprim; +@@ -4579,9 +4632,24 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + + return POLICYDB_SUCCESS; + bad: ++ if (canonicalize) { ++ for (i = 0; i < SYM_NUM; i++) { ++ hashtab_destroy(p->symtab[i].table); ++ } ++ } + return POLICYDB_ERROR; + } + ++int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) ++{ ++ return policydb_read_pre(p, fp, verbose, 0); ++} ++ ++int policydb_read_canonicalize(policydb_t * p, struct policy_file *fp, unsigned verbose) ++{ ++ return policydb_read_pre(p, fp, verbose, 1); ++} ++ + int policydb_reindex_users(policydb_t * p) + { + unsigned int i = SYM_USERS; +diff --git a/libsepol-3.5/src/policydb_public.c b/libsepol-3.5/src/policydb_public.c +index 0218c94..bbc2583 100644 +--- a/libsepol-3.5/src/policydb_public.c ++++ b/libsepol-3.5/src/policydb_public.c +@@ -212,3 +212,8 @@ int sepol_policydb_compat_net(const sepol_policydb_t * p) + return (hashtab_search(p->p.p_classes.table, PACKET_CLASS_NAME) == + NULL); + } ++ ++int sepol_policydb_read_canonicalize(sepol_policydb_t * p, sepol_policy_file_t * pf) ++{ ++ return policydb_read_canonicalize(&p->p, &pf->pf, 0); ++} +-- +2.33.0 + diff --git a/libsepol.spec b/libsepol.spec index 4aecce7..246d059 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,6 +1,6 @@ Name: libsepol Version: 3.5 -Release: 7 +Release: 8 Summary: SELinux binary policy manipulation library License: LGPLv2+ URL: https://github.com/SELinuxProject/selinux/wiki/Releases @@ -43,6 +43,8 @@ Patch0034: backport-libsepol-cil-Initialize-avtab_datum-on-declaration.patc Patch0035: backport-libsepol-cil-Optionally-allow-duplicate-role-declaration.patch Patch0036: backport-libsepol-Remove-special-handling-of-roles-in-module_to_cil.patch +Patch9000: Optimized-the-way-libsepol-policy-are-generated.patch + BuildRequires: gcc flex %description @@ -102,6 +104,9 @@ make DESTDIR="%{buildroot}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install %{_mandir}/man3/* %changelog +* Mon Apr 28 2025 jinlun - 3.5-8 +- Optimized the way libsepol policy are generated + * Mon Apr 21 2025 changhan - 3.5-7 - backport libsepol: Remove special handling of roles in module_to_cil.c