|
|
d477aa |
From 090a82e33be97d42eaa75bec85a32ccb6b7a13e8 Mon Sep 17 00:00:00 2001
|
|
|
d477aa |
From: Ondrej Mosnacek <omosnace@redhat.com>
|
|
|
d477aa |
Date: Thu, 3 Feb 2022 17:53:26 +0100
|
|
|
d477aa |
Subject: [PATCH] libsemanage: optionally rebuild policy when modules are
|
|
|
d477aa |
changed externally
|
|
|
d477aa |
|
|
|
d477aa |
In Fedora/RHEL's selinux-policy package we ship a pre-built SELinux
|
|
|
d477aa |
policy store in the RPMs. When updating the main policy RPM, care must
|
|
|
d477aa |
be taken to rebuild the policy using `semodule -B` if there are any
|
|
|
d477aa |
other SELinux modules installed (whether shipped via another RPM or
|
|
|
d477aa |
manually installed locally).
|
|
|
d477aa |
|
|
|
d477aa |
However, this way of shipping/managing the policy creates complications
|
|
|
d477aa |
on systems, where system files are managed by rpm-ostree (such as Fedora
|
|
|
d477aa |
CoreOS or Red Hat CoreOS), where the "package update" process is more
|
|
|
d477aa |
sophisticated.
|
|
|
d477aa |
|
|
|
d477aa |
(Disclaimer: The following is written according to my current limited
|
|
|
d477aa |
understanding of rpm-ostree and may not be entirely accurate, but the
|
|
|
d477aa |
gist of it should match the reality.)
|
|
|
d477aa |
|
|
|
d477aa |
Basically, one can think of rpm-ostree as a kind of Git for system
|
|
|
d477aa |
files. The package content is provided on a "branch", where each
|
|
|
d477aa |
"commit" represents a set of package updates layered on top of the
|
|
|
d477aa |
previous commit (i.e. it is a rolling release with some defined
|
|
|
d477aa |
package content snapshots). The user can then maintain their own branch
|
|
|
d477aa |
with additional package updates/installations/... and "rebase" it on top
|
|
|
d477aa |
of the main branch as needed. On top of that, the user can also have
|
|
|
d477aa |
additional configuration files (or modifications to existing files) in
|
|
|
d477aa |
/etc, which represent an additional layer on top of the package content.
|
|
|
d477aa |
|
|
|
d477aa |
When updating the system (i.e. rebasing on a new "commit" of the "main
|
|
|
d477aa |
branch"), the files on the running system are not touched and the new
|
|
|
d477aa |
system state is prepared under a new root directory, which is chrooted
|
|
|
d477aa |
into on the next reboot.
|
|
|
d477aa |
|
|
|
d477aa |
When an rpm-ostree system is updated, there are three moments when the
|
|
|
d477aa |
SELinux module store needs to be rebuilt to ensure that all modules are
|
|
|
d477aa |
included in the binary policy:
|
|
|
d477aa |
1. When the local RPM installations are applied on top of the base
|
|
|
d477aa |
system snapshot.
|
|
|
d477aa |
2. When local user configuartion is applied on top of that.
|
|
|
d477aa |
3. On system shutdown, to ensure that any changes in local configuration
|
|
|
d477aa |
performed since (2.) are reflected in the final new system image.
|
|
|
d477aa |
|
|
|
d477aa |
Forcing a full rebuild at each step is not optimal and in many cases is
|
|
|
d477aa |
not necessary, as the user may not have any custom modules installed.
|
|
|
d477aa |
|
|
|
d477aa |
Thus, this patch extends libsemanage to compute a checksum of the
|
|
|
d477aa |
content of all enabled modules, which is stored in the store, and adds a
|
|
|
d477aa |
flag to the libsemanage handle that instructs it to check the module
|
|
|
d477aa |
content checksum against the one from the last successful transaction
|
|
|
d477aa |
and force a full policy rebuild if they don't match.
|
|
|
d477aa |
|
|
|
d477aa |
This will allow rpm-ostree systems to potentially reduce delays when
|
|
|
d477aa |
reconciling the module store when applying updates.
|
|
|
d477aa |
|
|
|
d477aa |
I wasn't able to measure any noticeable overhead of the hash
|
|
|
d477aa |
computation, which is now added for every transaction (both before and
|
|
|
d477aa |
after this change a full policy rebuild took about 7 seconds on my test
|
|
|
d477aa |
x86 VM). With the new option check_ext_changes enabled, rebuilding a
|
|
|
d477aa |
policy store with unchanged modules took only about 0.96 seconds.
|
|
|
d477aa |
|
|
|
d477aa |
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
|
|
d477aa |
---
|
|
|
d477aa |
libsemanage/include/semanage/handle.h | 5 +
|
|
|
d477aa |
libsemanage/src/direct_api.c | 187 +++++++++++++++++++++-----
|
|
|
d477aa |
libsemanage/src/handle.c | 11 +-
|
|
|
d477aa |
libsemanage/src/handle.h | 1 +
|
|
|
d477aa |
libsemanage/src/libsemanage.map | 1 +
|
|
|
d477aa |
libsemanage/src/modules.c | 4 +-
|
|
|
d477aa |
libsemanage/src/modules.h | 3 +
|
|
|
d477aa |
libsemanage/src/semanage_store.c | 1 +
|
|
|
d477aa |
libsemanage/src/semanage_store.h | 1 +
|
|
|
d477aa |
9 files changed, 175 insertions(+), 39 deletions(-)
|
|
|
d477aa |
|
|
|
d477aa |
diff --git a/libsemanage/include/semanage/handle.h b/libsemanage/include/semanage/handle.h
|
|
|
d477aa |
index c8165900..7f298a49 100644
|
|
|
d477aa |
--- a/libsemanage/include/semanage/handle.h
|
|
|
d477aa |
+++ b/libsemanage/include/semanage/handle.h
|
|
|
d477aa |
@@ -66,6 +66,11 @@ void semanage_set_reload(semanage_handle_t * handle, int do_reload);
|
|
|
d477aa |
* 1 for yes, 0 for no (default) */
|
|
|
d477aa |
void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild);
|
|
|
d477aa |
|
|
|
d477aa |
+/* set whether to rebuild the policy on commit when potential changes
|
|
|
d477aa |
+ * to module files since last rebuild are detected,
|
|
|
d477aa |
+ * 1 for yes (default), 0 for no */
|
|
|
d477aa |
+extern void semanage_set_check_ext_changes(semanage_handle_t * handle, int do_check);
|
|
|
d477aa |
+
|
|
|
d477aa |
/* Fills *compiler_path with the location of the hll compiler sh->conf->compiler_directory_path
|
|
|
d477aa |
* corresponding to lang_ext.
|
|
|
d477aa |
* Upon success returns 0, -1 on error. */
|
|
|
d477aa |
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
|
|
|
d477aa |
index 7e99a59f..bbdca2b2 100644
|
|
|
d477aa |
--- a/libsemanage/src/direct_api.c
|
|
|
d477aa |
+++ b/libsemanage/src/direct_api.c
|
|
|
d477aa |
@@ -33,6 +33,8 @@
|
|
|
d477aa |
#include <unistd.h>
|
|
|
d477aa |
#include <sys/stat.h>
|
|
|
d477aa |
#include <sys/types.h>
|
|
|
d477aa |
+#include <sys/mman.h>
|
|
|
d477aa |
+#include <sys/wait.h>
|
|
|
d477aa |
#include <limits.h>
|
|
|
d477aa |
#include <errno.h>
|
|
|
d477aa |
#include <dirent.h>
|
|
|
d477aa |
@@ -56,8 +58,7 @@
|
|
|
d477aa |
#include "semanage_store.h"
|
|
|
d477aa |
#include "database_policydb.h"
|
|
|
d477aa |
#include "policy.h"
|
|
|
d477aa |
-#include <sys/mman.h>
|
|
|
d477aa |
-#include <sys/wait.h>
|
|
|
d477aa |
+#include "sha256.h"
|
|
|
d477aa |
|
|
|
d477aa |
#define PIPE_READ 0
|
|
|
d477aa |
#define PIPE_WRITE 1
|
|
|
d477aa |
@@ -450,7 +451,7 @@ static int parse_module_headers(semanage_handle_t * sh, char *module_data,
|
|
|
d477aa |
/* Writes a block of data to a file. Returns 0 on success, -1 on
|
|
|
d477aa |
* error. */
|
|
|
d477aa |
static int write_file(semanage_handle_t * sh,
|
|
|
d477aa |
- const char *filename, char *data, size_t num_bytes)
|
|
|
d477aa |
+ const char *filename, const char *data, size_t num_bytes)
|
|
|
d477aa |
{
|
|
|
d477aa |
int out;
|
|
|
d477aa |
|
|
|
d477aa |
@@ -850,8 +851,21 @@ cleanup:
|
|
|
d477aa |
return ret;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
+static void update_checksum_with_len(Sha256Context *context, size_t s)
|
|
|
d477aa |
+{
|
|
|
d477aa |
+ int i;
|
|
|
d477aa |
+ uint8_t buffer[8];
|
|
|
d477aa |
+
|
|
|
d477aa |
+ for (i = 0; i < 8; i++) {
|
|
|
d477aa |
+ buffer[i] = s & 0xff;
|
|
|
d477aa |
+ s >>= 8;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+ Sha256Update(context, buffer, 8);
|
|
|
d477aa |
+}
|
|
|
d477aa |
+
|
|
|
d477aa |
static int semanage_compile_module(semanage_handle_t *sh,
|
|
|
d477aa |
- semanage_module_info_t *modinfo)
|
|
|
d477aa |
+ semanage_module_info_t *modinfo,
|
|
|
d477aa |
+ Sha256Context *context)
|
|
|
d477aa |
{
|
|
|
d477aa |
char cil_path[PATH_MAX];
|
|
|
d477aa |
char hll_path[PATH_MAX];
|
|
|
d477aa |
@@ -922,6 +936,11 @@ static int semanage_compile_module(semanage_handle_t *sh,
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
+ if (context) {
|
|
|
d477aa |
+ update_checksum_with_len(context, cil_data_len);
|
|
|
d477aa |
+ Sha256Update(context, cil_data, cil_data_len);
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
|
|
|
d477aa |
if (status == -1) {
|
|
|
d477aa |
ERR(sh, "Failed to write %s\n", cil_path);
|
|
|
d477aa |
@@ -950,18 +969,40 @@ cleanup:
|
|
|
d477aa |
return status;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
+static int modinfo_cmp(const void *a, const void *b)
|
|
|
d477aa |
+{
|
|
|
d477aa |
+ const semanage_module_info_t *ma = a;
|
|
|
d477aa |
+ const semanage_module_info_t *mb = b;
|
|
|
d477aa |
+
|
|
|
d477aa |
+ return strcmp(ma->name, mb->name);
|
|
|
d477aa |
+}
|
|
|
d477aa |
+
|
|
|
d477aa |
static int semanage_compile_hll_modules(semanage_handle_t *sh,
|
|
|
d477aa |
- semanage_module_info_t *modinfos,
|
|
|
d477aa |
- int num_modinfos)
|
|
|
d477aa |
+ semanage_module_info_t *modinfos,
|
|
|
d477aa |
+ int num_modinfos,
|
|
|
d477aa |
+ char *cil_checksum)
|
|
|
d477aa |
{
|
|
|
d477aa |
- int status = 0;
|
|
|
d477aa |
- int i;
|
|
|
d477aa |
+ /* to be incremented when checksum input data format changes */
|
|
|
d477aa |
+ static const size_t CHECKSUM_EPOCH = 1;
|
|
|
d477aa |
+
|
|
|
d477aa |
+ int i, status = 0;
|
|
|
d477aa |
char cil_path[PATH_MAX];
|
|
|
d477aa |
struct stat sb;
|
|
|
d477aa |
+ Sha256Context context;
|
|
|
d477aa |
+ SHA256_HASH hash;
|
|
|
d477aa |
+ struct file_contents contents = {};
|
|
|
d477aa |
|
|
|
d477aa |
assert(sh);
|
|
|
d477aa |
assert(modinfos);
|
|
|
d477aa |
|
|
|
d477aa |
+ /* Sort modules by name to get consistent ordering. */
|
|
|
d477aa |
+ qsort(modinfos, num_modinfos, sizeof(*modinfos), &modinfo_cmp);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ Sha256Initialise(&context);
|
|
|
d477aa |
+ update_checksum_with_len(&context, CHECKSUM_EPOCH);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ /* prefix with module count to avoid collisions */
|
|
|
d477aa |
+ update_checksum_with_len(&context, num_modinfos);
|
|
|
d477aa |
for (i = 0; i < num_modinfos; i++) {
|
|
|
d477aa |
status = semanage_module_get_path(
|
|
|
d477aa |
sh,
|
|
|
d477aa |
@@ -969,29 +1010,91 @@ static int semanage_compile_hll_modules(semanage_handle_t *sh,
|
|
|
d477aa |
SEMANAGE_MODULE_PATH_CIL,
|
|
|
d477aa |
cil_path,
|
|
|
d477aa |
sizeof(cil_path));
|
|
|
d477aa |
- if (status != 0) {
|
|
|
d477aa |
- goto cleanup;
|
|
|
d477aa |
- }
|
|
|
d477aa |
+ if (status != 0)
|
|
|
d477aa |
+ return -1;
|
|
|
d477aa |
|
|
|
d477aa |
- if (semanage_get_ignore_module_cache(sh) == 0 &&
|
|
|
d477aa |
- (status = stat(cil_path, &sb)) == 0) {
|
|
|
d477aa |
- continue;
|
|
|
d477aa |
- }
|
|
|
d477aa |
- if (status != 0 && errno != ENOENT) {
|
|
|
d477aa |
- ERR(sh, "Unable to access %s: %s\n", cil_path, strerror(errno));
|
|
|
d477aa |
- goto cleanup; //an error in the "stat" call
|
|
|
d477aa |
+ if (!semanage_get_ignore_module_cache(sh)) {
|
|
|
d477aa |
+ status = stat(cil_path, &sb);
|
|
|
d477aa |
+ if (status == 0) {
|
|
|
d477aa |
+ status = map_compressed_file(sh, cil_path, &contents);
|
|
|
d477aa |
+ if (status < 0) {
|
|
|
d477aa |
+ ERR(sh, "Error mapping file: %s", cil_path);
|
|
|
d477aa |
+ return -1;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
+ /* prefix with length to avoid collisions */
|
|
|
d477aa |
+ update_checksum_with_len(&context, contents.len);
|
|
|
d477aa |
+ Sha256Update(&context, contents.data, contents.len);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ unmap_compressed_file(&contents);
|
|
|
d477aa |
+ continue;
|
|
|
d477aa |
+ } else if (errno != ENOENT) {
|
|
|
d477aa |
+ ERR(sh, "Unable to access %s: %s\n", cil_path,
|
|
|
d477aa |
+ strerror(errno));
|
|
|
d477aa |
+ return -1; //an error in the "stat" call
|
|
|
d477aa |
+ }
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
- status = semanage_compile_module(sh, &modinfos[i]);
|
|
|
d477aa |
- if (status < 0) {
|
|
|
d477aa |
- goto cleanup;
|
|
|
d477aa |
+ status = semanage_compile_module(sh, &modinfos[i], &context);
|
|
|
d477aa |
+ if (status < 0)
|
|
|
d477aa |
+ return -1;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+ Sha256Finalise(&context, &hash);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ semanage_hash_to_checksum_string(hash.bytes, cil_checksum);
|
|
|
d477aa |
+ return 0;
|
|
|
d477aa |
+}
|
|
|
d477aa |
+
|
|
|
d477aa |
+static int semanage_compare_checksum(semanage_handle_t *sh, const char *reference)
|
|
|
d477aa |
+{
|
|
|
d477aa |
+ const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
|
|
|
d477aa |
+ struct stat sb;
|
|
|
d477aa |
+ int fd, retval;
|
|
|
d477aa |
+ char *data;
|
|
|
d477aa |
+
|
|
|
d477aa |
+ fd = open(path, O_RDONLY);
|
|
|
d477aa |
+ if (fd == -1) {
|
|
|
d477aa |
+ if (errno != ENOENT) {
|
|
|
d477aa |
+ ERR(sh, "Unable to open %s: %s\n", path, strerror(errno));
|
|
|
d477aa |
+ return -1;
|
|
|
d477aa |
}
|
|
|
d477aa |
+ /* Checksum file not present - force a rebuild. */
|
|
|
d477aa |
+ return 1;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
+ if (fstat(fd, &sb) == -1) {
|
|
|
d477aa |
+ ERR(sh, "Unable to stat %s\n", path);
|
|
|
d477aa |
+ retval = -1;
|
|
|
d477aa |
+ goto out_close;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
- status = 0;
|
|
|
d477aa |
+ if (sb.st_size != (off_t)CHECKSUM_CONTENT_SIZE) {
|
|
|
d477aa |
+ /* Incompatible/invalid hash type - just force a rebuild. */
|
|
|
d477aa |
+ WARN(sh, "Module checksum invalid - forcing a rebuild\n");
|
|
|
d477aa |
+ retval = 1;
|
|
|
d477aa |
+ goto out_close;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
|
|
|
d477aa |
-cleanup:
|
|
|
d477aa |
- return status;
|
|
|
d477aa |
+ data = mmap(NULL, CHECKSUM_CONTENT_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
|
d477aa |
+ if (data == MAP_FAILED) {
|
|
|
d477aa |
+ ERR(sh, "Unable to mmap %s\n", path);
|
|
|
d477aa |
+ retval = -1;
|
|
|
d477aa |
+ goto out_close;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
+ retval = memcmp(data, reference, CHECKSUM_CONTENT_SIZE) != 0;
|
|
|
d477aa |
+ munmap(data, sb.st_size);
|
|
|
d477aa |
+out_close:
|
|
|
d477aa |
+ close(fd);
|
|
|
d477aa |
+ return retval;
|
|
|
d477aa |
+}
|
|
|
d477aa |
+
|
|
|
d477aa |
+static int semanage_write_modules_checksum(semanage_handle_t *sh,
|
|
|
d477aa |
+ const char *checksum)
|
|
|
d477aa |
+{
|
|
|
d477aa |
+ const char *path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES_CHECKSUM);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ return write_file(sh, path, checksum, CHECKSUM_CONTENT_SIZE);
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
/* Files that must exist in order to skip policy rebuild. */
|
|
|
d477aa |
@@ -1030,6 +1133,7 @@ static int semanage_direct_commit(semanage_handle_t * sh)
|
|
|
d477aa |
semanage_module_info_t *modinfos = NULL;
|
|
|
d477aa |
mode_t mask = umask(0077);
|
|
|
d477aa |
struct stat sb;
|
|
|
d477aa |
+ char modules_checksum[CHECKSUM_CONTENT_SIZE + 1 /* '\0' */];
|
|
|
d477aa |
|
|
|
d477aa |
int do_rebuild, do_write_kernel, do_install;
|
|
|
d477aa |
int fcontexts_modified, ports_modified, seusers_modified,
|
|
|
d477aa |
@@ -1159,28 +1263,45 @@ static int semanage_direct_commit(semanage_handle_t * sh)
|
|
|
d477aa |
}
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
- /*
|
|
|
d477aa |
- * If there were policy changes, or explicitly requested, or
|
|
|
d477aa |
- * any required files are missing, rebuild the policy.
|
|
|
d477aa |
- */
|
|
|
d477aa |
- if (do_rebuild) {
|
|
|
d477aa |
- /* =================== Module expansion =============== */
|
|
|
d477aa |
-
|
|
|
d477aa |
+ if (do_rebuild || sh->check_ext_changes) {
|
|
|
d477aa |
retval = semanage_get_active_modules(sh, &modinfos, &num_modinfos);
|
|
|
d477aa |
if (retval < 0) {
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
+ /* No modules - nothing to rebuild. */
|
|
|
d477aa |
if (num_modinfos == 0) {
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
- retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos);
|
|
|
d477aa |
+ retval = semanage_compile_hll_modules(sh, modinfos, num_modinfos,
|
|
|
d477aa |
+ modules_checksum);
|
|
|
d477aa |
if (retval < 0) {
|
|
|
d477aa |
ERR(sh, "Failed to compile hll files into cil files.\n");
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
+ if (!do_rebuild && sh->check_ext_changes) {
|
|
|
d477aa |
+ retval = semanage_compare_checksum(sh, modules_checksum);
|
|
|
d477aa |
+ if (retval < 0)
|
|
|
d477aa |
+ goto cleanup;
|
|
|
d477aa |
+ do_rebuild = retval;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
+ retval = semanage_write_modules_checksum(sh, modules_checksum);
|
|
|
d477aa |
+ if (retval < 0) {
|
|
|
d477aa |
+ ERR(sh, "Failed to write module checksum file.\n");
|
|
|
d477aa |
+ goto cleanup;
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+ }
|
|
|
d477aa |
+
|
|
|
d477aa |
+ /*
|
|
|
d477aa |
+ * If there were policy changes, or explicitly requested, or
|
|
|
d477aa |
+ * any required files are missing, rebuild the policy.
|
|
|
d477aa |
+ */
|
|
|
d477aa |
+ if (do_rebuild) {
|
|
|
d477aa |
+ /* =================== Module expansion =============== */
|
|
|
d477aa |
+
|
|
|
d477aa |
retval = semanage_get_cil_paths(sh, modinfos, num_modinfos, &mod_filenames);
|
|
|
d477aa |
if (retval < 0)
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
@@ -1696,7 +1817,7 @@ static int semanage_direct_extract(semanage_handle_t * sh,
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
- rc = semanage_compile_module(sh, _modinfo);
|
|
|
d477aa |
+ rc = semanage_compile_module(sh, _modinfo, NULL);
|
|
|
d477aa |
if (rc < 0) {
|
|
|
d477aa |
goto cleanup;
|
|
|
d477aa |
}
|
|
|
d477aa |
diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c
|
|
|
d477aa |
index e5109aef..8a01c53a 100644
|
|
|
d477aa |
--- a/libsemanage/src/handle.c
|
|
|
d477aa |
+++ b/libsemanage/src/handle.c
|
|
|
d477aa |
@@ -118,20 +118,23 @@ semanage_handle_t *semanage_handle_create(void)
|
|
|
d477aa |
|
|
|
d477aa |
void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
|
|
|
d477aa |
{
|
|
|
d477aa |
-
|
|
|
d477aa |
assert(sh != NULL);
|
|
|
d477aa |
|
|
|
d477aa |
sh->do_rebuild = do_rebuild;
|
|
|
d477aa |
- return;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
void semanage_set_reload(semanage_handle_t * sh, int do_reload)
|
|
|
d477aa |
{
|
|
|
d477aa |
-
|
|
|
d477aa |
assert(sh != NULL);
|
|
|
d477aa |
|
|
|
d477aa |
sh->do_reload = do_reload;
|
|
|
d477aa |
- return;
|
|
|
d477aa |
+}
|
|
|
d477aa |
+
|
|
|
d477aa |
+void semanage_set_check_ext_changes(semanage_handle_t * sh, int do_check)
|
|
|
d477aa |
+{
|
|
|
d477aa |
+ assert(sh != NULL);
|
|
|
d477aa |
+
|
|
|
d477aa |
+ sh->check_ext_changes = do_check;
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
int semanage_get_hll_compiler_path(semanage_handle_t *sh,
|
|
|
d477aa |
diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h
|
|
|
d477aa |
index a91907b0..c4a6e7ea 100644
|
|
|
d477aa |
--- a/libsemanage/src/handle.h
|
|
|
d477aa |
+++ b/libsemanage/src/handle.h
|
|
|
d477aa |
@@ -62,6 +62,7 @@ struct semanage_handle {
|
|
|
d477aa |
int is_in_transaction;
|
|
|
d477aa |
int do_reload; /* whether to reload policy after commit */
|
|
|
d477aa |
int do_rebuild; /* whether to rebuild policy if there were no changes */
|
|
|
d477aa |
+ int check_ext_changes; /* whether to rebuild if external changes are detected via checksum */
|
|
|
d477aa |
int commit_err; /* set by semanage_direct_commit() if there are
|
|
|
d477aa |
* any errors when building or committing the
|
|
|
d477aa |
* sandbox to kernel policy at /etc/selinux
|
|
|
d477aa |
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
|
|
|
d477aa |
index a986b2d2..1ef664be 100644
|
|
|
d477aa |
--- a/libsemanage/src/libsemanage.map
|
|
|
d477aa |
+++ b/libsemanage/src/libsemanage.map
|
|
|
d477aa |
@@ -66,4 +66,5 @@ LIBSEMANAGE_1.1 {
|
|
|
d477aa |
|
|
|
d477aa |
LIBSEMANAGE_3.4 {
|
|
|
d477aa |
semanage_module_compute_checksum;
|
|
|
d477aa |
+ semanage_set_check_ext_changes;
|
|
|
d477aa |
} LIBSEMANAGE_1.1;
|
|
|
d477aa |
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
|
|
|
d477aa |
index 3a82d275..f1fe160d 100644
|
|
|
d477aa |
--- a/libsemanage/src/modules.c
|
|
|
d477aa |
+++ b/libsemanage/src/modules.c
|
|
|
d477aa |
@@ -1149,9 +1149,9 @@ int semanage_module_remove_key(semanage_handle_t *sh,
|
|
|
d477aa |
}
|
|
|
d477aa |
|
|
|
d477aa |
static const char CHECKSUM_TYPE[] = "sha256";
|
|
|
d477aa |
-static const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
|
|
|
d477aa |
+const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
|
|
|
d477aa |
|
|
|
d477aa |
-static void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
|
|
|
d477aa |
+void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
|
|
|
d477aa |
{
|
|
|
d477aa |
size_t i;
|
|
|
d477aa |
|
|
|
d477aa |
diff --git a/libsemanage/src/modules.h b/libsemanage/src/modules.h
|
|
|
d477aa |
index 8a5c01f4..b828a534 100644
|
|
|
d477aa |
--- a/libsemanage/src/modules.h
|
|
|
d477aa |
+++ b/libsemanage/src/modules.h
|
|
|
d477aa |
@@ -109,4 +109,7 @@ int semanage_module_get_path(semanage_handle_t *sh,
|
|
|
d477aa |
char *path,
|
|
|
d477aa |
size_t len);
|
|
|
d477aa |
|
|
|
d477aa |
+extern const size_t CHECKSUM_CONTENT_SIZE;
|
|
|
d477aa |
+void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum);
|
|
|
d477aa |
+
|
|
|
d477aa |
#endif
|
|
|
d477aa |
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
|
|
|
d477aa |
index c5ce071c..1fff667d 100644
|
|
|
d477aa |
--- a/libsemanage/src/semanage_store.c
|
|
|
d477aa |
+++ b/libsemanage/src/semanage_store.c
|
|
|
d477aa |
@@ -115,6 +115,7 @@ static const char *semanage_sandbox_paths[SEMANAGE_STORE_NUM_PATHS] = {
|
|
|
d477aa |
"/disable_dontaudit",
|
|
|
d477aa |
"/preserve_tunables",
|
|
|
d477aa |
"/modules/disabled",
|
|
|
d477aa |
+ "/modules_checksum",
|
|
|
d477aa |
"/policy.kern",
|
|
|
d477aa |
"/file_contexts.local",
|
|
|
d477aa |
"/file_contexts.homedirs",
|
|
|
d477aa |
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
|
|
|
d477aa |
index b9ec5664..1fc77da8 100644
|
|
|
d477aa |
--- a/libsemanage/src/semanage_store.h
|
|
|
d477aa |
+++ b/libsemanage/src/semanage_store.h
|
|
|
d477aa |
@@ -60,6 +60,7 @@ enum semanage_sandbox_defs {
|
|
|
d477aa |
SEMANAGE_DISABLE_DONTAUDIT,
|
|
|
d477aa |
SEMANAGE_PRESERVE_TUNABLES,
|
|
|
d477aa |
SEMANAGE_MODULES_DISABLED,
|
|
|
d477aa |
+ SEMANAGE_MODULES_CHECKSUM,
|
|
|
d477aa |
SEMANAGE_STORE_KERNEL,
|
|
|
d477aa |
SEMANAGE_STORE_FC_LOCAL,
|
|
|
d477aa |
SEMANAGE_STORE_FC_HOMEDIRS,
|
|
|
d477aa |
--
|
|
|
d477aa |
2.30.2
|
|
|
d477aa |
|