Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

67 changed files with 3150 additions and 2656 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

162
.gitignore vendored
View File

@ -1 +1,161 @@
SOURCES/libsemanage-2.9.tar.gz
libsemanage-1.0.tgz
libsemanage-1.1.4.tgz
libsemanage-1.1.6.tgz
libsemanage-1.3.1.tgz
libsemanage-1.3.2.tgz
libsemanage-1.3.3.tgz
libsemanage-1.3.4.tgz
libsemanage-1.3.5.tgz
libsemanage-1.3.7.tgz
libsemanage-1.3.8.tgz
libsemanage-1.3.9.tgz
libsemanage-1.3.10.tgz
libsemanage-1.3.11.tgz
libsemanage-1.3.14.tgz
libsemanage-1.3.18.tgz
libsemanage-1.3.20.tgz
libsemanage-1.3.23.tgz
libsemanage-1.3.24.tgz
libsemanage-1.3.28.tgz
libsemanage-1.3.30.tgz
libsemanage-1.3.31.tgz
libsemanage-1.3.32.tgz
libsemanage-1.3.34.tgz
libsemanage-1.3.35.tgz
libsemanage-1.3.36.tgz
libsemanage-1.3.38.tgz
libsemanage-1.3.39.tgz
libsemanage-1.3.40.tgz
libsemanage-1.3.41.tgz
libsemanage-1.3.43.tgz
libsemanage-1.3.45.tgz
libsemanage-1.3.48.tgz
libsemanage-1.3.51.tgz
libsemanage-1.3.52.tgz
libsemanage-1.3.53.tgz
libsemanage-1.3.56.tgz
libsemanage-1.3.59.tgz
libsemanage-1.3.61.tgz
libsemanage-1.3.63.tgz
libsemanage-1.3.64.tgz
libsemanage-1.4.tgz
libsemanage-1.5.1.tgz
libsemanage-1.5.2.tgz
libsemanage-1.5.3.tgz
libsemanage-1.5.4.tgz
libsemanage-1.5.6.tgz
libsemanage-1.5.8.tgz
libsemanage-1.5.9.tgz
libsemanage-1.5.11.tgz
libsemanage-1.5.14.tgz
libsemanage-1.5.15.tgz
libsemanage-1.5.16.tgz
libsemanage-1.5.18.tgz
libsemanage-1.5.19.tgz
libsemanage-1.5.20.tgz
libsemanage-1.5.21.tgz
libsemanage-1.5.23.tgz
libsemanage-1.5.26.tgz
libsemanage-1.5.28.tgz
libsemanage-1.5.29.tgz
libsemanage-1.5.31.tgz
libsemanage-1.6.tgz
libsemanage-1.6.2.tgz
libsemanage-1.6.3.tgz
libsemanage-1.6.5.tgz
libsemanage-1.6.6.tgz
libsemanage-1.6.7.tgz
libsemanage-1.6.8.tgz
libsemanage-1.6.9.tgz
libsemanage-1.6.11.tgz
libsemanage-1.6.12.tgz
libsemanage-1.6.13.tgz
libsemanage-1.6.15.tgz
libsemanage-1.6.16.tgz
libsemanage-1.6.17.tgz
libsemanage-1.8.tgz
libsemanage-1.9.1.tgz
libsemanage-1.9.2.tgz
libsemanage-1.10.0.tgz
libsemanage-1.10.1.tgz
libsemanage-2.0.0.tgz
libsemanage-2.0.1.tgz
libsemanage-2.0.2.tgz
libsemanage-2.0.3.tgz
libsemanage-2.0.4.tgz
libsemanage-2.0.5.tgz
libsemanage-2.0.6.tgz
libsemanage-2.0.9.tgz
libsemanage-2.0.10.tgz
libsemanage-2.0.11.tgz
libsemanage-2.0.12.tgz
libsemanage-2.0.14.tgz
libsemanage-2.0.15.tgz
libsemanage-2.0.16.tgz
libsemanage-2.0.18.tgz
libsemanage-2.0.19.tgz
libsemanage-2.0.20.tgz
libsemanage-2.0.22.tgz
libsemanage-2.0.23.tgz
libsemanage-2.0.24.tgz
libsemanage-2.0.25.tgz
libsemanage-2.0.26.tgz
libsemanage-2.0.27.tgz
libsemanage-2.0.28.tgz
libsemanage-2.0.29.tgz
libsemanage-2.0.30.tgz
libsemanage-2.0.31.tgz
libsemanage-2.0.32.tgz
libsemanage-2.0.33.tgz
libsemanage-2.0.35.tgz
libsemanage-2.0.36.tgz
libsemanage-2.0.37.tgz
libsemanage-2.0.38.tgz
libsemanage-2.0.39.tgz
libsemanage-2.0.40.tgz
libsemanage-2.0.41.tgz
libsemanage-2.0.42.tgz
libsemanage-2.0.43.tgz
libsemanage-2.0.44.tgz
libsemanage-2.0.45.tgz
/libsemanage-2.0.46.tgz
/libsemanage-2.1.0.tgz
/libsemanage-2.1.2.tgz
/libsemanage-2.1.3.tgz
/libsemanage-2.1.4.tgz
/libsemanage-2.1.5.tgz
/libsemanage-2.1.6.tgz
/libsemanage-2.1.7.tgz
/libsemanage-2.1.8.tgz
/libsemanage-2.1.9.tgz
/libsemanage-2.1.10.tgz
/libsemanage-2.2.tgz
/libsemanage-2.3.tgz
/libsemanage-2.4.tar.gz
/libsemanage-2.5-rc1.tar.gz
/libsemanage-2.5.tar.gz
/libsemanage-2.6.tar.gz
/libsemanage-2.7.tar.gz
/libsemanage-2.8-rc1.tar.gz
/libsemanage-2.8-rc2.tar.gz
/libsemanage-2.8-rc3.tar.gz
/libsemanage-2.8.tar.gz
/libsemanage-2.9-rc1.tar.gz
/libsemanage-2.9-rc2.tar.gz
/libsemanage-2.9.tar.gz
/libsemanage-3.0-rc1.tar.gz
/libsemanage-3.0.tar.gz
/libsemanage-3.1.tar.gz
/libsemanage-3.2-rc1.tar.gz
/libsemanage-3.2-rc2.tar.gz
/libsemanage-3.2.tar.gz
/libsemanage-3.3-rc2.tar.gz
/libsemanage-3.3-rc3.tar.gz
/libsemanage-3.3.tar.gz
/libsemanage-3.4.tar.gz
/libsemanage-3.5-rc1.tar.gz
/libsemanage-3.5-rc2.tar.gz
/libsemanage-3.5-rc3.tar.gz
/libsemanage-3.5.tar.gz
/libsemanage-3.6-rc1.tar.gz
/libsemanage-3.6.tar.gz

View File

@ -1 +0,0 @@
4c669c72c4626391d67e5c7e69be8397d71ee31e SOURCES/libsemanage-2.9.tar.gz

View File

@ -0,0 +1,25 @@
From a87290f734ba136e7b648a9ce9754767cbb5eed3 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <lautrbach@redhat.com>
Date: Mon, 13 Nov 2023 13:37:36 +0100
Subject: [PATCH] Revert "Do not automatically install Russian translations"
Content-type: text/plain
This reverts commit 14f35fde50cd080650ac3b0136234464a3ea6fbe.
---
libsemanage/man/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libsemanage/man/Makefile b/libsemanage/man/Makefile
index 5e21a65ea725..f626447dadbe 100644
--- a/libsemanage/man/Makefile
+++ b/libsemanage/man/Makefile
@@ -1,5 +1,5 @@
# Installation directories.
-LINGUAS ?=
+LINGUAS ?= ru
PREFIX ?= /usr
MANDIR ?= $(PREFIX)/share/man
MAN3SUBDIR ?= man3
--
2.41.0

View File

@ -0,0 +1,138 @@
From 020da857956beea5749c9347cafbd527774aeaa5 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <lautrbach@redhat.com>
Date: Mon, 13 Nov 2023 13:37:57 +0100
Subject: [PATCH] Revert "libsemanage: Remove the Russian translations"
Content-type: text/plain
This reverts commit 1303a6af486eeef1138a99513214700f543c0ef7.
---
libsemanage/man/ru/man5/semanage.conf.5 | 117 ++++++++++++++++++++++++
1 file changed, 117 insertions(+)
create mode 100644 libsemanage/man/ru/man5/semanage.conf.5
diff --git a/libsemanage/man/ru/man5/semanage.conf.5 b/libsemanage/man/ru/man5/semanage.conf.5
new file mode 100644
index 000000000000..548aa58d37b6
--- /dev/null
+++ b/libsemanage/man/ru/man5/semanage.conf.5
@@ -0,0 +1,117 @@
+.TH semanage.conf "5" "Сентябрь 2011" "semanage.conf" "Администрирование системы Linux"
+.SH ИМЯ
+semanage.conf \- глобальный файл конфигурации для библиотеки управления SELinux
+.SH ОПИСАНИЕ
+.PP
+Файл
+.BR semanage.conf
+обычно располагается в каталоге /etc/selinux и используется для конфигурации поведения библиотеки управления SELinux в среде выполнения.
+
+.PP
+Каждая строка должна содержать параметр конфигурации, за которым следует знак равенства ("=") и значение конфигурации этого параметра. Все символы, которые следуют за "#", игнорируются (аналогично пустым строкам).
+
+.PP
+Разрешены следующие параметры:
+
+.RS
+.TP
+.B module-store
+Указать, как библиотека управления SELinux должна взаимодействовать с хранилищем политики SELinux. Если установлено "direct", библиотека управления SELinux выполняет запись напрямую в хранилище модулей политики SELinux (это значение по умолчанию).
+В ином случае в качестве аргумента может использоваться путь к сокету или имя сервера.
+Если аргумент начинается с "/" (как в "/foo/bar"), он представляет собой путь к именованному сокету, который следует использовать для подключения сервера управления политикой.
+Если аргумент не начинается с "/" (как в "example.com:4242"), он должен интерпретироваться как имя удалённого сервера управления политикой, который следует использовать через TCP-подключение (порт по умолчанию 4242, если только после имени сервера через двоеточие, разделяющее два поля, не указан другой порт).
+
+.TP
+.B root
+Указать альтернативный корневой путь к хранилищу. По умолчанию: "/"
+
+.TP
+.B store-root
+Указать альтернативный путь store_root. По умолчанию: "/var/lib/selinux"
+
+.TP
+.B compiler-directory
+Указать альтернативный каталог, который содержит компиляторы HLL в CIL. Значение по умолчанию: "/usr/libexec/selinux/hll".
+
+.TP
+.B ignore-module-cache
+Определяет, следует ли игнорировать кэш модулей CIL, скомпилированных из HLL. Можно установить либо значение "true", либо значение "false" (по умолчанию установлено "false").
+Если кэш игнорируется, все модули CIL перекомпилируются из соответствующих модулей HLL.
+
+.TP
+.B policy-version
+При создании политики
+.BR semanage
+по умолчанию устанавливает версию политики POLICYDB_VERSION_MAX, как определено в <sepol/policydb/policydb.h>. Измените этот параметр, если для политики требуется установить другую версию.
+
+.TP
+.B target-platform
+Целевая платформа, для которой создаются политики. Действительными значениями являются "selinux" и "xen" (по умолчанию установлено "selinux").
+
+.TP
+.B expand-check
+Определяет, следует ли проверять правила "neverallow" при исполнении всех команд
+.BR semanage.
+Для этого параметра можно установить либо значение "0" (отключён), либо "1" (включён). По умолчанию параметр включён. Время выполнения может сильно возрасти, если этот параметр включён.
+
+.TP
+.B file-mode
+По умолчанию для разрешительного режима для файлов среды выполнения политики установлено значение 0644.
+
+.TP
+.B save-previous
+Определяет, следует ли сохранять прежний каталог модуля после успешной фиксации модуля в хранилище политики. Для параметра можно установить либо значение "true", либо значение "false". По умолчанию установлено "false" (прежняя версия удаляется).
+
+.TP
+.B save-linked
+Определяет, следует ли сохранять прежний связанный модуль (с именем "base.linked") после успешной фиксации модуля в хранилище политики.
+Для параметра можно установить либо значение "true", либо значение "false". По умолчанию установлено "false" (прежний модуль удаляется).
+
+.TP
+.B ignoredirs
+Разделённый ";" список каталогов, которые следует игнорировать при установке домашних каталогов пользователей.
+В некоторых дистрибутивах этот параметр используется для того, чтобы /root не отмечался как домашний каталог.
+
+.TP
+.B usepasswd
+Определяет, использовать ли getpwent(), чтобы получить список домашних каталогов, для которых следует проставить метки. Для параметра можно установить либо значение "true", либо значение "false" (по умолчанию установлено "true").
+
+.TP
+.B disable-genhomedircon
+Определяет, следует ли исполнять функцию genhomedircon при использовании команды
+.BR semanage.
+Для параметра можно установить либо значение "true", либо значение "false". По умолчанию возможность genhomedircon включена (эквивалентно установке значения "false" для этого параметра).
+
+.TP
+.B handle-unknown
+Этот параметр управляет тем, как ядро обрабатывает разрешения, которые определены в ядре, но отсутствуют в фактической политике.
+Возможные значения: "deny", "reject" или "allow".
+
+.TP
+.B bzip-blocksize
+Этот параметр должен находиться в диапазоне 0-9. Значение 0 означает отсутствие сжатия. По умолчанию значение размера блока bzip равняется 9 (фактическое значение размера блока получается путём умножения на 100000).
+
+.TP
+.B bzip-small
+Если для этого параметра установлено значение "true", алгоритм bzip попытается уменьшить использование системной памяти. Также для этого параметра можно установить значение "false" (по умолчанию установлено это значение).
+
+.TP
+.B remove-hll
+Если для этого параметра установлено значение "true", файлы HLL будут удалены после компиляции в CIL. Чтобы удалить уже cкомпилированные в CIL файлы HLL, необходимо перекомпилировать модули, установив для параметра
+.BR ignore-module-cache
+значение "true", или используя параметр
+.BR ignore-module-cache
+с semodule. Для параметра remove-hll можно установить либо значение "true", либо значение "false" (по умолчанию установлено "false").
+
+Обратите внимание: так как этот параметр удаляет все файлы HLL, обновлённый компилятор HLL не сможет перекомпилировать исходный файл HLL в CIL.
+Чтобы скомпилировать исходный файл HLL в CIL, необходимо переустановить этот файл HLL.
+
+.SH "СМОТРИТЕ ТАКЖЕ"
+.TP
+semanage(8)
+.PP
+
+.SH АВТОРЫ
+Эта страница руководства была написана Guido Trentalancia <guido@trentalancia.com>.
+Библиотека управления SELinux была написана Tresys Technology LLC и Red Hat Inc.
+Перевод на русский язык выполнила Герасименко Олеся <gammaray@basealt.ru>.
--
2.41.0

View File

@ -0,0 +1,146 @@
From d238e71d979dce51afed11b9b8af0898be5daafe Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Mon, 29 Jul 2024 13:26:45 +0200
Subject: [PATCH] libsemanage: Preserve file context and ownership in policy
store
Make sure that file context (all parts) and ownership of
files/directories in policy store does not change no matter which user
and under which context executes policy rebuild.
Fixes:
# semodule -B
# ls -lZ /etc/selinux/targeted/contexts/files
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 421397 Jul 11 09:57 file_contexts
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 593470 Jul 11 09:57 file_contexts.bin
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 14704 Jul 11 09:57 file_contexts.homedirs
-rw-r--r--. 1 root root unconfined_u:object_r:file_context_t:s0 20289 Jul 11 09:57 file_contexts.homedirs.bin
SELinux user changed from system_u to the user used to execute semodule
# capsh --user=testuser --caps="cap_dac_override,cap_chown+eip" --addamb=cap_dac_override,cap_chown -- -c "semodule -B"
# ls -lZ /etc/selinux/targeted/contexts/files
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 421397 Jul 19 09:10 file_contexts
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 593470 Jul 19 09:10 file_contexts.bin
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 14704 Jul 19 09:10 file_contexts.homedirs
-rw-r--r--. 1 testuser testuser unconfined_u:object_r:file_context_t:s0 20289 Jul 19 09:10 file_contexts.homedirs.bin
Both file context and ownership changed -- causes remote login
failures and other issues in some scenarios.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
libsemanage/src/semanage_store.c | 32 ++++++++++++++++++++++++++++++++
libsemanage/src/semanage_store.h | 1 +
2 files changed, 33 insertions(+)
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 27c5d349..0ac2e5b2 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -36,6 +36,7 @@ typedef struct dbase_policydb dbase_t;
#include "database_policydb.h"
#include "handle.h"
+#include <selinux/restorecon.h>
#include <selinux/selinux.h>
#include <sepol/policydb.h>
#include <sepol/module.h>
@@ -767,6 +768,7 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode,
if (!retval && rename(tmp, dst) == -1)
return -1;
+ semanage_setfiles(dst);
out:
errno = errsv;
return retval;
@@ -819,6 +821,8 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
goto cleanup;
}
umask(mask);
+
+ semanage_setfiles(dst);
}
for (i = 0; i < len; i++) {
@@ -837,6 +841,7 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
goto cleanup;
}
umask(mask);
+ semanage_setfiles(path2);
} else if (S_ISREG(sb.st_mode) && flag == 1) {
mask = umask(0077);
if (semanage_copy_file(path, path2, sb.st_mode,
@@ -938,6 +943,7 @@ int semanage_mkdir(semanage_handle_t *sh, const char *path)
}
umask(mask);
+ semanage_setfiles(path);
}
else {
/* check that it really is a directory */
@@ -1614,16 +1620,19 @@ static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh)
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) {
goto cleanup;
}
+ semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_BIN));
if (sefcontext_compile(sh,
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) {
goto cleanup;
}
+ semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL_BIN));
if (sefcontext_compile(sh,
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) {
goto cleanup;
}
+ semanage_setfiles(semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS_BIN));
status = 0;
cleanup:
@@ -3018,3 +3027,26 @@ int semanage_nc_sort(semanage_handle_t * sh, const char *buf, size_t buf_len,
return 0;
}
+
+/* Make sure the file context and ownership of files in the policy
+ * store does not change */
+void semanage_setfiles(const char *path){
+ struct stat sb;
+ int fd;
+ /* Fix the user and role portions of the context, ignore errors
+ * since this is not a critical operation */
+ selinux_restorecon(path, SELINUX_RESTORECON_SET_SPECFILE_CTX | SELINUX_RESTORECON_IGNORE_NOENTRY);
+
+ /* Make sure "path" is owned by root */
+ if ((geteuid() != 0 || getegid() != 0) &&
+ ((fd = open(path, O_RDONLY)) != -1)){
+ /* Skip files with the SUID or SGID bit set -- abuse protection */
+ if ((fstat(fd, &sb) != -1) &&
+ !(S_ISREG(sb.st_mode) &&
+ (sb.st_mode & (S_ISUID | S_ISGID))) &&
+ (fchown(fd, 0, 0) == -1))
+ fprintf(stderr, "Warning! Could not set ownership of %s to root\n", path);
+
+ close(fd);
+ }
+}
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 1fc77da8..e21dadeb 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -124,6 +124,7 @@ int semanage_get_cil_paths(semanage_handle_t * sh, semanage_module_info_t *modin
int semanage_get_active_modules(semanage_handle_t *sh,
semanage_module_info_t **modinfo, int *num_modules);
+void semanage_setfiles(const char *path);
/* lock file routines */
int semanage_get_trans_lock(semanage_handle_t * sh);
--
2.45.2

View File

@ -0,0 +1,46 @@
From b23d81a2cc4cb500fb864dd5c9e867d23bf2c8b5 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <lautrbach@redhat.com>
Date: Thu, 7 Nov 2024 16:40:51 +0100
Subject: [PATCH] libsemanage: open lock_file with O_RDWR
Content-type: text/plain
man 2 flock:
Since Linux 2.6.12, NFS clients support flock() locks by emulating
them as fcntl(2) byte-range locks on the entire file. This means
that fcntl(2) and flock() locks do interact with one another
over NFS. It also means that in order to place an exclusive lock,
the file must be opened for writing.
Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
---
libsemanage/src/semanage_store.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 0ac2e5b2ad39..c26f5667b3cd 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -1899,14 +1899,12 @@ static int semanage_get_lock(semanage_handle_t * sh,
struct timeval origtime, curtime;
int got_lock = 0;
- if ((fd = open(lock_file, O_RDONLY)) == -1) {
- if ((fd =
- open(lock_file, O_RDWR | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR)) == -1) {
- ERR(sh, "Could not open direct %s at %s.", lock_name,
- lock_file);
- return -1;
- }
+ if ((fd =
+ open(lock_file, O_RDWR | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR)) == -1) {
+ ERR(sh, "Could not open direct %s at %s.", lock_name,
+ lock_file);
+ return -1;
}
if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
ERR(sh, "Could not set close-on-exec for %s at %s.", lock_name,
--
2.47.0

View File

@ -1,66 +0,0 @@
From dc105dcb5e34e256bcbcf547fea590cfcee06933 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Wed, 7 Nov 2018 18:17:34 +0100
Subject: [PATCH] libsemanage: Fix RESOURCE_LEAK and USE_AFTER_FREE coverity
scan defects
---
libsemanage/src/direct_api.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index c58961be..8e4d116d 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1028,7 +1028,7 @@ static int semanage_direct_write_langext(semanage_handle_t *sh,
fp = NULL;
- ret = 0;
+ return 0;
cleanup:
if (fp != NULL) fclose(fp);
@@ -2177,7 +2177,6 @@ cleanup:
semanage_module_info_destroy(sh, modinfo);
free(modinfo);
- if (fp != NULL) fclose(fp);
return status;
}
@@ -2342,16 +2341,6 @@ static int semanage_direct_get_module_info(semanage_handle_t *sh,
free(tmp);
tmp = NULL;
- if (fclose(fp) != 0) {
- ERR(sh,
- "Unable to close %s module lang ext file.",
- (*modinfo)->name);
- status = -1;
- goto cleanup;
- }
-
- fp = NULL;
-
/* lookup enabled/disabled status */
ret = semanage_module_get_path(sh,
*modinfo,
@@ -2395,7 +2384,13 @@ cleanup:
free(modinfos);
}
- if (fp != NULL) fclose(fp);
+ if (fp != NULL && fclose(fp) != 0) {
+ ERR(sh,
+ "Unable to close %s module lang ext file.",
+ (*modinfo)->name);
+ status = -1;
+ }
+
return status;
}
--
2.21.0

View File

@ -1,48 +0,0 @@
From d68976d353bf334c43fd084f9cc4535874860006 Mon Sep 17 00:00:00 2001
From: Vit Mojzis <vmojzis@redhat.com>
Date: Tue, 8 Oct 2019 14:22:12 +0200
Subject: [PATCH] libsemanage: Add support for DCCP and SCTP protocols
This is necessary for "semanage port" to be able to handle DCCP and SCTP
protocols.
Fixes:
"port_parse" only handles TCP and UDP protocols
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
libsemanage/include/semanage/port_record.h | 2 ++
libsemanage/src/ports_file.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/libsemanage/include/semanage/port_record.h b/libsemanage/include/semanage/port_record.h
index 20ae4bd9..71074800 100644
--- a/libsemanage/include/semanage/port_record.h
+++ b/libsemanage/include/semanage/port_record.h
@@ -16,6 +16,8 @@ typedef struct semanage_port_key semanage_port_key_t;
#define SEMANAGE_PROTO_UDP 0
#define SEMANAGE_PROTO_TCP 1
+#define SEMANAGE_PROTO_DCCP 2
+#define SEMANAGE_PROTO_SCTP 3
/* Key */
extern int semanage_port_compare(const semanage_port_t * port,
diff --git a/libsemanage/src/ports_file.c b/libsemanage/src/ports_file.c
index 46ee2f00..4738d467 100644
--- a/libsemanage/src/ports_file.c
+++ b/libsemanage/src/ports_file.c
@@ -84,6 +84,10 @@ static int port_parse(semanage_handle_t * handle,
semanage_port_set_proto(port, SEMANAGE_PROTO_TCP);
else if (!strcasecmp(str, "udp"))
semanage_port_set_proto(port, SEMANAGE_PROTO_UDP);
+ else if (!strcasecmp(str, "dccp"))
+ semanage_port_set_proto(port, SEMANAGE_PROTO_DCCP);
+ else if (!strcasecmp(str, "sctp"))
+ semanage_port_set_proto(port, SEMANAGE_PROTO_SCTP);
else {
ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str,
info->filename, info->lineno, info->orig_line);
--
2.21.0

View File

@ -1,156 +0,0 @@
From dc4f1d03d6e17d851283f9b10b2faeeca9b10e14 Mon Sep 17 00:00:00 2001
From: Stephen Smalley <stephen.smalley.work@gmail.com>
Date: Wed, 13 May 2020 15:34:19 -0400
Subject: [PATCH] libsemanage: fsync final files before rename
Prior to rename(2)'ing the final selinux policy files into place,
fsync(2) them to ensure the contents will be fully written prior to
rename. While we are here, also fix checking of write(2) to detect
short writes and treat them as an error. This code could be more
generally improved but keeping to the minimal changes required to fix
this bug.
Fixes: https://github.com/SELinuxProject/selinux/issues/237
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Source:
https://github.com/SELinuxProject/selinux/commit/331a109f91ea46473fd858c2494f6eab1ef43f66
---
libsemanage/src/direct_api.c | 10 +++++-----
libsemanage/src/semanage_store.c | 20 +++++++++++++++-----
libsemanage/src/semanage_store.h | 4 +++-
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 8e4d116d..abc3a4cb 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1188,7 +1188,7 @@ cleanup:
* overwrite it. If source doesn't exist then return success.
* Returns 0 on success, -1 on error. */
static int copy_file_if_exists(const char *src, const char *dst, mode_t mode){
- int rc = semanage_copy_file(src, dst, mode);
+ int rc = semanage_copy_file(src, dst, mode, false);
return (rc < 0 && errno != ENOENT) ? rc : 0;
}
@@ -1481,7 +1481,7 @@ rebuild:
retval = semanage_copy_file(path,
semanage_path(SEMANAGE_TMP,
SEMANAGE_STORE_SEUSERS),
- 0);
+ 0, false);
if (retval < 0)
goto cleanup;
pseusers->dtable->drop_cache(pseusers->dbase);
@@ -1499,7 +1499,7 @@ rebuild:
retval = semanage_copy_file(path,
semanage_path(SEMANAGE_TMP,
SEMANAGE_USERS_EXTRA),
- 0);
+ 0, false);
if (retval < 0)
goto cleanup;
pusers_extra->dtable->drop_cache(pusers_extra->dbase);
@@ -1588,7 +1588,7 @@ rebuild:
retval = semanage_copy_file(semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_KERNEL),
- sh->conf->file_mode);
+ sh->conf->file_mode, false);
if (retval < 0) {
goto cleanup;
}
@@ -1627,7 +1627,7 @@ rebuild:
retval = semanage_copy_file(
semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS),
semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS),
- sh->conf->file_mode);
+ sh->conf->file_mode, false);
if (retval < 0) {
goto cleanup;
}
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 58dded6e..733df8da 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -707,7 +707,8 @@ static int semanage_filename_select(const struct dirent *d)
/* Copies a file from src to dst. If dst already exists then
* overwrite it. Returns 0 on success, -1 on error. */
-int semanage_copy_file(const char *src, const char *dst, mode_t mode)
+int semanage_copy_file(const char *src, const char *dst, mode_t mode,
+ bool syncrequired)
{
int in, out, retval = 0, amount_read, n, errsv = errno;
char tmp[PATH_MAX];
@@ -735,8 +736,11 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode)
}
umask(mask);
while (retval == 0 && (amount_read = read(in, buf, sizeof(buf))) > 0) {
- if (write(out, buf, amount_read) < 0) {
- errsv = errno;
+ if (write(out, buf, amount_read) != amount_read) {
+ if (errno)
+ errsv = errno;
+ else
+ errsv = EIO;
retval = -1;
}
}
@@ -745,6 +749,10 @@ int semanage_copy_file(const char *src, const char *dst, mode_t mode)
retval = -1;
}
close(in);
+ if (syncrequired && fsync(out) < 0) {
+ errsv = errno;
+ retval = -1;
+ }
if (close(out) < 0) {
errsv = errno;
retval = -1;
@@ -811,7 +819,8 @@ static int semanage_copy_dir_flags(const char *src, const char *dst, int flag)
umask(mask);
} else if (S_ISREG(sb.st_mode) && flag == 1) {
mask = umask(0077);
- if (semanage_copy_file(path, path2, sb.st_mode) < 0) {
+ if (semanage_copy_file(path, path2, sb.st_mode,
+ false) < 0) {
umask(mask);
goto cleanup;
}
@@ -1640,7 +1649,8 @@ static int semanage_install_final_tmp(semanage_handle_t * sh)
goto cleanup;
}
- ret = semanage_copy_file(src, dst, sh->conf->file_mode);
+ ret = semanage_copy_file(src, dst, sh->conf->file_mode,
+ true);
if (ret < 0) {
ERR(sh, "Could not copy %s to %s.", src, dst);
goto cleanup;
diff --git a/libsemanage/src/semanage_store.h b/libsemanage/src/semanage_store.h
index 34bf8523..b9ec5664 100644
--- a/libsemanage/src/semanage_store.h
+++ b/libsemanage/src/semanage_store.h
@@ -24,6 +24,7 @@
#ifndef SEMANAGE_MODULE_STORE_H
#define SEMANAGE_MODULE_STORE_H
+#include <stdbool.h>
#include <sys/time.h>
#include <sepol/module.h>
#include <sepol/cil/cil.h>
@@ -162,6 +163,7 @@ int semanage_nc_sort(semanage_handle_t * sh,
size_t buf_len,
char **sorted_buf, size_t * sorted_buf_len);
-int semanage_copy_file(const char *src, const char *dst, mode_t mode);
+int semanage_copy_file(const char *src, const char *dst, mode_t mode,
+ bool syncrequired);
#endif
--
2.25.4

View File

@ -1,55 +0,0 @@
From 11e381e5aa3468aa5c2634f14706336c7824f226 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Wed, 27 Jan 2021 12:00:55 +0100
Subject: [PATCH] libsemanage: sync filesystem with sandbox
Commit 331a109f91ea ("libsemanage: fsync final files before rename")
added fsync() for policy files and improved situation when something
unexpected happens right after rename(). However the module store could
be affected as well. After the following steps module files could be 0
size:
1. Run `semanage fcontext -a -t var_t "/tmp/abc"`
2. Force shutdown the server during the command is run, or right after
it's finished
3. Boot the system and look for empty files:
# find /var/lib/selinux/targeted/ -type f -size 0 | wc -l
1266
It looks like this situation can be avoided if the filesystem with the
sandbox is sync()ed before we start to rename() directories in the
store.
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
libsemanage/src/semanage_store.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index 733df8da37c2..ae023582e907 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -1737,6 +1737,19 @@ static int semanage_commit_sandbox(semanage_handle_t * sh)
}
close(fd);
+ /* sync changes in sandbox to filesystem */
+ fd = open(sandbox, O_DIRECTORY);
+ if (fd == -1) {
+ ERR(sh, "Error while opening %s for syncfs(): %d", sandbox, errno);
+ return -1;
+ }
+ if (syncfs(fd) == -1) {
+ ERR(sh, "Error while syncing %s to filesystem: %d", sandbox, errno);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
retval = commit_number;
if (semanage_get_active_lock(sh) < 0) {
--
2.30.0

View File

@ -1,76 +0,0 @@
From ac10bc27090916fe8fcdaf4a9f0e8cc0165f7210 Mon Sep 17 00:00:00 2001
From: Unto Sten <sten.unto@gmail.com>
Date: Sat, 11 May 2019 01:04:16 +0300
Subject: [PATCH] Trivial style fixes
---
libsemanage/src/direct_api.c | 2 +-
libsemanage/src/modules.c | 2 +-
libsemanage/src/seusers_local.c | 2 +-
libsemanage/src/users_local.c | 4 ++--
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index abc3a4cb..b037890a 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -517,7 +517,7 @@ ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
size_t size = 1<<18;
size_t bufsize = size;
int bzerror;
- size_t total=0;
+ size_t total = 0;
char* uncompress = NULL;
char* tmpalloc = NULL;
int ret = -1;
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index 62af1018..fa84d33e 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -1130,7 +1130,7 @@ int semanage_module_install_info(semanage_handle_t *sh,
int semanage_module_remove_key(semanage_handle_t *sh,
const semanage_module_key_t *modkey)
{
- if (sh->funcs->remove_key== NULL) {
+ if (sh->funcs->remove_key == NULL) {
ERR(sh,
"No remove key function defined for this connection type.");
return -1;
diff --git a/libsemanage/src/seusers_local.c b/libsemanage/src/seusers_local.c
index a79e2d3d..3e2761c4 100644
--- a/libsemanage/src/seusers_local.c
+++ b/libsemanage/src/seusers_local.c
@@ -133,7 +133,7 @@ int semanage_seuser_modify_local(semanage_handle_t * handle,
semanage_seuser_t *new = NULL;
if (!sename) {
- errno=EINVAL;
+ errno = EINVAL;
return -1;
}
rc = semanage_seuser_clone(handle, data, &new);
diff --git a/libsemanage/src/users_local.c b/libsemanage/src/users_local.c
index 7aa43d44..8193476d 100644
--- a/libsemanage/src/users_local.c
+++ b/libsemanage/src/users_local.c
@@ -38,7 +38,7 @@ static int lookup_seuser(semanage_handle_t * handle, const semanage_user_key_t *
semanage_seuser_list_local(handle,
&records,
&count);
- for(i=0; i<count; i++) {
+ for(i = 0; i < count; i++) {
sename = semanage_seuser_get_sename(records[i]);
if (strcmp(name, sename) == 0) {
errno = EINVAL;
@@ -47,7 +47,7 @@ static int lookup_seuser(semanage_handle_t * handle, const semanage_user_key_t *
rc = -1;
}
}
- for(i=0; i<count; i++)
+ for(i = 0; i < count; i++)
semanage_seuser_free(records[i]);
free(records);
semanage_user_free(user);
--
2.30.2

View File

@ -1,31 +0,0 @@
From e14a8a078b2cfecb0498ff98ddff08403b3be1cd Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 17 Dec 2020 15:59:49 +0100
Subject: [PATCH] libsemanage: Free contents of modkey in
semanage_direct_remove
semanage_direct_remove allocates struct semanage_module_key_t on
stack, then calls semanage_module_key_set_name which allocates
modkey->name on heap, but modkey->name wasn't free()-d anywhere,
creating a small leak.
Signed-off-by: Jakub Hrozek <jhrozek@redhat.com>
---
libsemanage/src/direct_api.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index b037890a..c32939c0 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1944,6 +1944,7 @@ static int semanage_direct_remove(semanage_handle_t * sh, char *module_name)
status = semanage_direct_remove_key(sh, &modkey);
cleanup:
+ semanage_module_key_destroy(sh, &modkey);
return status;
}
--
2.30.2

View File

@ -1,42 +0,0 @@
From 30da7a4907893bd43fe9da40728a3bcabdf3d7a4 Mon Sep 17 00:00:00 2001
From: Petr Lautrbach <plautrba@redhat.com>
Date: Wed, 28 Jul 2021 11:21:35 +0200
Subject: [PATCH] libsemanage: Fix USE_AFTER_FREE (CWE-672) in
semanage_direct_write_langext()
>From fclose(3):
Upon successful completion, 0 is returned. Otherwise, EOF is returned
and errno is set to indicate the error. In either case, any further
access (including another call to fclose()) to the stream results in
undefined behavior.
Fixes:
Error: USE_AFTER_FREE (CWE-672): [#def1]
libsemanage-3.2/src/direct_api.c:1023: freed_arg: "fclose" frees "fp".
libsemanage-3.2/src/direct_api.c:1034: use_closed_file: Calling "fclose" uses file handle "fp" after closing it.
# 1032|
# 1033| cleanup:
# 1034|-> if (fp != NULL) fclose(fp);
# 1035|
# 1036| return ret;
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
---
libsemanage/src/direct_api.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index c32939c0..7638653a 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1022,6 +1022,7 @@ static int semanage_direct_write_langext(semanage_handle_t *sh,
if (fclose(fp) != 0) {
ERR(sh, "Unable to close %s module ext file.", modinfo->name);
+ fp = NULL;
ret = -1;
goto cleanup;
}
--
2.30.2

View File

@ -1,37 +0,0 @@
From ecf6e6a9fda1a28cc3df36841b44326ed0c12312 Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Thu, 3 Feb 2022 17:53:22 +0100
Subject: [PATCH] libsemanage: add missing include to boolean_record.c
It uses asprintf(3), but doesn't directly include <stdio.h> - fix it.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
libsemanage/src/boolean_record.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/libsemanage/src/boolean_record.c b/libsemanage/src/boolean_record.c
index c234094e..bdddfa23 100644
--- a/libsemanage/src/boolean_record.c
+++ b/libsemanage/src/boolean_record.c
@@ -7,6 +7,9 @@
*/
#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
#include <sepol/boolean_record.h>
#include "handle_internal.h"
@@ -21,7 +24,6 @@ typedef semanage_bool_key_t record_key_t;
#include "boolean_internal.h"
#include "handle.h"
#include "database.h"
-#include <stdlib.h>
#include <selinux/selinux.h>
/* Key */
--
2.30.2

View File

@ -1,555 +0,0 @@
From 066007029b3dd250305d7fac0bfd53aa1e4543cf Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Thu, 3 Feb 2022 17:53:23 +0100
Subject: [PATCH] semodule,libsemanage: move module hashing into libsemanage
The main goal of this move is to have the SHA-256 implementation under
libsemanage, since upcoming patches will make use of SHA-256 for a
different (but similar) purpose in libsemanage. Having the hashing code
in libsemanage will reduce code duplication and allow for easier hash
algorithm upgrade in the future.
Note that libselinux currently also contains a hash function
implementation (for yet another different purpose). This patch doesn't
make any effort to address that duplicity yet.
This patch also changes the format of the hash string printed by
semodule to include the name of the hash. The intent is to avoid
ambiguity and potential collisions when the algorithm is potentially
changed in the future.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
libsemanage/include/semanage/modules.h | 26 +++
libsemanage/src/libsemanage.map | 4 +
libsemanage/src/modules.c | 59 +++++
libsemanage/src/sha256.c | 294 +++++++++++++++++++++++++
libsemanage/src/sha256.h | 89 ++++++++
5 files changed, 472 insertions(+)
create mode 100644 libsemanage/src/sha256.c
create mode 100644 libsemanage/src/sha256.h
diff --git a/libsemanage/include/semanage/modules.h b/libsemanage/include/semanage/modules.h
index 4b93e54e..26ac40b2 100644
--- a/libsemanage/include/semanage/modules.h
+++ b/libsemanage/include/semanage/modules.h
@@ -282,4 +282,30 @@ int semanage_module_get_enabled(semanage_handle_t *sh,
const semanage_module_key_t *modkey,
int *enabled);
+/* Compute checksum for @modkey module contents.
+ *
+ * If @checksum is NULL, the function will just return the length of the
+ * checksum string in @checksum_len (checksum strings are guaranteed to
+ * have a fixed length for a given libsemanage binary). @modkey and @cil
+ * are ignored in this case and should be set to NULL and 0 (respectively).
+ *
+ * If @checksum is non-NULL, on success, @checksum will point to a buffer
+ * containing the checksum string and @checksum_len will point to the
+ * length of the string (without the null terminator). The semantics of
+ * @cil are the same as for @extract_cil in semanage_module_extract().
+ *
+ * The caller is responsible to free the buffer returned in @checksum (using
+ * free(3)).
+ *
+ * Callers may assume that if the checksum strings for two modules match,
+ * the module content is the same (collisions are theoretically possible,
+ * yet extremely unlikely).
+ *
+ * Returns 0 on success and -1 on error.
+ */
+extern int semanage_module_compute_checksum(semanage_handle_t *sh,
+ semanage_module_key_t *modkey,
+ int cil, char **checksum,
+ size_t *checksum_len);
+
#endif
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 02036696..a986b2d2 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -63,3 +63,7 @@ LIBSEMANAGE_1.1 {
semanage_module_remove_key;
semanage_set_store_root;
} LIBSEMANAGE_1.0;
+
+LIBSEMANAGE_3.4 {
+ semanage_module_compute_checksum;
+} LIBSEMANAGE_1.1;
diff --git a/libsemanage/src/modules.c b/libsemanage/src/modules.c
index fa84d33e..3a82d275 100644
--- a/libsemanage/src/modules.c
+++ b/libsemanage/src/modules.c
@@ -34,11 +34,13 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mman.h>
#include <errno.h>
#include <ctype.h>
#include "handle.h"
#include "modules.h"
+#include "sha256.h"
#include "debug.h"
asm(".symver semanage_module_get_enabled_1_1,semanage_module_get_enabled@@LIBSEMANAGE_1.1");
@@ -1146,3 +1148,60 @@ int semanage_module_remove_key(semanage_handle_t *sh,
return sh->funcs->remove_key(sh, modkey);
}
+static const char CHECKSUM_TYPE[] = "sha256";
+static const size_t CHECKSUM_CONTENT_SIZE = sizeof(CHECKSUM_TYPE) + 1 + 2 * SHA256_HASH_SIZE;
+
+static void semanage_hash_to_checksum_string(const uint8_t *hash, char *checksum)
+{
+ size_t i;
+
+ checksum += sprintf(checksum, "%s:", CHECKSUM_TYPE);
+ for (i = 0; i < SHA256_HASH_SIZE; i++) {
+ checksum += sprintf(checksum, "%02x", (unsigned)hash[i]);
+ }
+}
+
+int semanage_module_compute_checksum(semanage_handle_t *sh,
+ semanage_module_key_t *modkey,
+ int cil, char **checksum,
+ size_t *checksum_len)
+{
+ semanage_module_info_t *extract_info = NULL;
+ Sha256Context context;
+ SHA256_HASH sha256_hash;
+ char *checksum_str;
+ void *data;
+ size_t data_len = 0;
+ int result;
+
+ if (!checksum_len)
+ return -1;
+
+ if (!checksum) {
+ *checksum_len = CHECKSUM_CONTENT_SIZE;
+ return 0;
+ }
+
+ result = semanage_module_extract(sh, modkey, cil, &data, &data_len, &extract_info);
+ if (result != 0)
+ return -1;
+
+ semanage_module_info_destroy(sh, extract_info);
+ free(extract_info);
+
+ Sha256Initialise(&context);
+ Sha256Update(&context, data, data_len);
+ Sha256Finalise(&context, &sha256_hash);
+
+ munmap(data, data_len);
+
+ checksum_str = malloc(CHECKSUM_CONTENT_SIZE + 1 /* '\0' */);
+ if (!checksum_str)
+ return -1;
+
+ semanage_hash_to_checksum_string(sha256_hash.bytes, checksum_str);
+
+ *checksum = checksum_str;
+ *checksum_len = CHECKSUM_CONTENT_SIZE;
+ return 0;
+}
diff --git a/libsemanage/src/sha256.c b/libsemanage/src/sha256.c
new file mode 100644
index 00000000..fe2aeef0
--- /dev/null
+++ b/libsemanage/src/sha256.c
@@ -0,0 +1,294 @@
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// WjCryptLib_Sha256
+//
+// Implementation of SHA256 hash function.
+// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+// Modified by WaterJuice retaining Public Domain license.
+//
+// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// IMPORTS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "sha256.h"
+#include <memory.h>
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// MACROS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
+
+#define MIN(x, y) ( ((x)<(y))?(x):(y) )
+
+#define STORE32H(x, y) \
+ { (y)[0] = (uint8_t)(((x)>>24)&255); (y)[1] = (uint8_t)(((x)>>16)&255); \
+ (y)[2] = (uint8_t)(((x)>>8)&255); (y)[3] = (uint8_t)((x)&255); }
+
+#define LOAD32H(x, y) \
+ { x = ((uint32_t)((y)[0] & 255)<<24) | \
+ ((uint32_t)((y)[1] & 255)<<16) | \
+ ((uint32_t)((y)[2] & 255)<<8) | \
+ ((uint32_t)((y)[3] & 255)); }
+
+#define STORE64H(x, y) \
+ { (y)[0] = (uint8_t)(((x)>>56)&255); (y)[1] = (uint8_t)(((x)>>48)&255); \
+ (y)[2] = (uint8_t)(((x)>>40)&255); (y)[3] = (uint8_t)(((x)>>32)&255); \
+ (y)[4] = (uint8_t)(((x)>>24)&255); (y)[5] = (uint8_t)(((x)>>16)&255); \
+ (y)[6] = (uint8_t)(((x)>>8)&255); (y)[7] = (uint8_t)((x)&255); }
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CONSTANTS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// The K array
+static const uint32_t K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+#define BLOCK_SIZE 64
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// INTERNAL FUNCTIONS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// Various logical functions
+#define Ch( x, y, z ) (z ^ (x & (y ^ z)))
+#define Maj( x, y, z ) (((x | y) & z) | (x & y))
+#define S( x, n ) ror((x),(n))
+#define R( x, n ) (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0( x ) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1( x ) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0( x ) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1( x ) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+
+#define Sha256Round( a, b, c, d, e, f, g, h, i ) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// TransformFunction
+//
+// Compress 512-bits
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+static
+void
+ TransformFunction
+ (
+ Sha256Context* Context,
+ uint8_t const* Buffer
+ )
+{
+ uint32_t S[8];
+ uint32_t W[64];
+ uint32_t t0;
+ uint32_t t1;
+ uint32_t t;
+ int i;
+
+ // Copy state into S
+ for( i=0; i<8; i++ )
+ {
+ S[i] = Context->state[i];
+ }
+
+ // Copy the state into 512-bits into W[0..15]
+ for( i=0; i<16; i++ )
+ {
+ LOAD32H( W[i], Buffer + (4*i) );
+ }
+
+ // Fill W[16..63]
+ for( i=16; i<64; i++ )
+ {
+ W[i] = Gamma1( W[i-2]) + W[i-7] + Gamma0( W[i-15] ) + W[i-16];
+ }
+
+ // Compress
+ for( i=0; i<64; i++ )
+ {
+ Sha256Round( S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i );
+ t = S[7];
+ S[7] = S[6];
+ S[6] = S[5];
+ S[5] = S[4];
+ S[4] = S[3];
+ S[3] = S[2];
+ S[2] = S[1];
+ S[1] = S[0];
+ S[0] = t;
+ }
+
+ // Feedback
+ for( i=0; i<8; i++ )
+ {
+ Context->state[i] = Context->state[i] + S[i];
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC FUNCTIONS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Initialise
+//
+// Initialises a SHA256 Context. Use this to initialise/reset a context.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Initialise
+ (
+ Sha256Context* Context // [out]
+ )
+{
+ Context->curlen = 0;
+ Context->length = 0;
+ Context->state[0] = 0x6A09E667UL;
+ Context->state[1] = 0xBB67AE85UL;
+ Context->state[2] = 0x3C6EF372UL;
+ Context->state[3] = 0xA54FF53AUL;
+ Context->state[4] = 0x510E527FUL;
+ Context->state[5] = 0x9B05688CUL;
+ Context->state[6] = 0x1F83D9ABUL;
+ Context->state[7] = 0x5BE0CD19UL;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Update
+//
+// Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
+// calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Update
+ (
+ Sha256Context* Context, // [in out]
+ void const* Buffer, // [in]
+ uint32_t BufferSize // [in]
+ )
+{
+ uint32_t n;
+
+ if( Context->curlen > sizeof(Context->buf) )
+ {
+ return;
+ }
+
+ while( BufferSize > 0 )
+ {
+ if( Context->curlen == 0 && BufferSize >= BLOCK_SIZE )
+ {
+ TransformFunction( Context, (uint8_t*)Buffer );
+ Context->length += BLOCK_SIZE * 8;
+ Buffer = (uint8_t*)Buffer + BLOCK_SIZE;
+ BufferSize -= BLOCK_SIZE;
+ }
+ else
+ {
+ n = MIN( BufferSize, (BLOCK_SIZE - Context->curlen) );
+ memcpy( Context->buf + Context->curlen, Buffer, (size_t)n );
+ Context->curlen += n;
+ Buffer = (uint8_t*)Buffer + n;
+ BufferSize -= n;
+ if( Context->curlen == BLOCK_SIZE )
+ {
+ TransformFunction( Context, Context->buf );
+ Context->length += 8*BLOCK_SIZE;
+ Context->curlen = 0;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Finalise
+//
+// Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
+// calling this, Sha256Initialised must be used to reuse the context.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Finalise
+ (
+ Sha256Context* Context, // [in out]
+ SHA256_HASH* Digest // [out]
+ )
+{
+ int i;
+
+ if( Context->curlen >= sizeof(Context->buf) )
+ {
+ return;
+ }
+
+ // Increase the length of the message
+ Context->length += Context->curlen * 8;
+
+ // Append the '1' bit
+ Context->buf[Context->curlen++] = (uint8_t)0x80;
+
+ // if the length is currently above 56 bytes we append zeros
+ // then compress. Then we can fall back to padding zeros and length
+ // encoding like normal.
+ if( Context->curlen > 56 )
+ {
+ while( Context->curlen < 64 )
+ {
+ Context->buf[Context->curlen++] = (uint8_t)0;
+ }
+ TransformFunction(Context, Context->buf);
+ Context->curlen = 0;
+ }
+
+ // Pad up to 56 bytes of zeroes
+ while( Context->curlen < 56 )
+ {
+ Context->buf[Context->curlen++] = (uint8_t)0;
+ }
+
+ // Store length
+ STORE64H( Context->length, Context->buf+56 );
+ TransformFunction( Context, Context->buf );
+
+ // Copy output
+ for( i=0; i<8; i++ )
+ {
+ STORE32H( Context->state[i], Digest->bytes+(4*i) );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Calculate
+//
+// Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
+// buffer.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Calculate
+ (
+ void const* Buffer, // [in]
+ uint32_t BufferSize, // [in]
+ SHA256_HASH* Digest // [in]
+ )
+{
+ Sha256Context context;
+
+ Sha256Initialise( &context );
+ Sha256Update( &context, Buffer, BufferSize );
+ Sha256Finalise( &context, Digest );
+}
diff --git a/libsemanage/src/sha256.h b/libsemanage/src/sha256.h
new file mode 100644
index 00000000..406ed869
--- /dev/null
+++ b/libsemanage/src/sha256.h
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// WjCryptLib_Sha256
+//
+// Implementation of SHA256 hash function.
+// Original author: Tom St Denis, tomstdenis@gmail.com, http://libtom.org
+// Modified by WaterJuice retaining Public Domain license.
+//
+// This is free and unencumbered software released into the public domain - June 2013 waterjuice.org
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// IMPORTS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <stdint.h>
+#include <stdio.h>
+
+typedef struct
+{
+ uint64_t length;
+ uint32_t state[8];
+ uint32_t curlen;
+ uint8_t buf[64];
+} Sha256Context;
+
+#define SHA256_HASH_SIZE ( 256 / 8 )
+
+typedef struct
+{
+ uint8_t bytes [SHA256_HASH_SIZE];
+} SHA256_HASH;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC FUNCTIONS
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Initialise
+//
+// Initialises a SHA256 Context. Use this to initialise/reset a context.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Initialise
+ (
+ Sha256Context* Context // [out]
+ );
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Update
+//
+// Adds data to the SHA256 context. This will process the data and update the internal state of the context. Keep on
+// calling this function until all the data has been added. Then call Sha256Finalise to calculate the hash.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Update
+ (
+ Sha256Context* Context, // [in out]
+ void const* Buffer, // [in]
+ uint32_t BufferSize // [in]
+ );
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Finalise
+//
+// Performs the final calculation of the hash and returns the digest (32 byte buffer containing 256bit hash). After
+// calling this, Sha256Initialised must be used to reuse the context.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Finalise
+ (
+ Sha256Context* Context, // [in out]
+ SHA256_HASH* Digest // [out]
+ );
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Sha256Calculate
+//
+// Combines Sha256Initialise, Sha256Update, and Sha256Finalise into one function. Calculates the SHA256 hash of the
+// buffer.
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+void
+ Sha256Calculate
+ (
+ void const* Buffer, // [in]
+ uint32_t BufferSize, // [in]
+ SHA256_HASH* Digest // [in]
+ );
--
2.30.2

View File

@ -1,824 +0,0 @@
From f8c74eaf19df123deabe9e2c71bd5b3c2beba06a Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Thu, 3 Feb 2022 17:53:24 +0100
Subject: [PATCH] libsemanage: move compressed file handling into a separate
object
In order to reduce exisiting and future code duplication and to avoid
some unnecessary allocations and copying, factor the compressed file
utility functions out into a separate C/header file and refactor their
interface.
Note that this change effectively removes the __fsetlocking(3) call from
semanage_load_files() - I haven't been able to figure out what purpose
it serves, but it seems pointless...
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
libsemanage/src/compressed_file.c | 224 +++++++++++++++++++++++++
libsemanage/src/compressed_file.h | 78 +++++++++
libsemanage/src/direct_api.c | 263 +++++-------------------------
libsemanage/src/direct_api.h | 4 -
libsemanage/src/semanage_store.c | 52 ++----
5 files changed, 354 insertions(+), 267 deletions(-)
create mode 100644 libsemanage/src/compressed_file.c
create mode 100644 libsemanage/src/compressed_file.h
diff --git a/libsemanage/src/compressed_file.c b/libsemanage/src/compressed_file.c
new file mode 100644
index 00000000..5546b830
--- /dev/null
+++ b/libsemanage/src/compressed_file.c
@@ -0,0 +1,224 @@
+/* Author: Jason Tang <jtang@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Ondrej Mosnacek <omosnacek@gmail.com>
+ *
+ * Copyright (C) 2004-2006 Tresys Technology, LLC
+ * Copyright (C) 2005-2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <bzlib.h>
+
+#include "compressed_file.h"
+
+#include "debug.h"
+
+#define BZ2_MAGICSTR "BZh"
+#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
+
+/* bzip() a data to a file, returning the total number of compressed bytes
+ * in the file. Returns -1 if file could not be compressed. */
+static int bzip(semanage_handle_t *sh, const char *filename, void *data,
+ size_t num_bytes)
+{
+ BZFILE* b;
+ size_t size = 1<<16;
+ int bzerror;
+ size_t total = 0;
+ size_t len = 0;
+ FILE *f;
+
+ if ((f = fopen(filename, "wb")) == NULL) {
+ return -1;
+ }
+
+ if (!sh->conf->bzip_blocksize) {
+ if (fwrite(data, 1, num_bytes, f) < num_bytes) {
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+ return 0;
+ }
+
+ b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
+ if (bzerror != BZ_OK) {
+ BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
+ fclose(f);
+ return -1;
+ }
+
+ while ( num_bytes > total ) {
+ if (num_bytes - total > size) {
+ len = size;
+ } else {
+ len = num_bytes - total;
+ }
+ BZ2_bzWrite ( &bzerror, b, (uint8_t *)data + total, len );
+ if (bzerror == BZ_IO_ERROR) {
+ BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
+ fclose(f);
+ return -1;
+ }
+ total += len;
+ }
+
+ BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
+ fclose(f);
+ if (bzerror == BZ_IO_ERROR) {
+ return -1;
+ }
+ return 0;
+}
+
+/* bunzip() a file to '*data', returning the total number of uncompressed bytes
+ * in the file. Returns -1 if file could not be decompressed. */
+static ssize_t bunzip(semanage_handle_t *sh, FILE *f, void **data)
+{
+ BZFILE* b = NULL;
+ size_t nBuf;
+ uint8_t* buf = NULL;
+ size_t size = 1<<18;
+ size_t bufsize = size;
+ int bzerror;
+ size_t total = 0;
+ uint8_t* uncompress = NULL;
+ uint8_t* tmpalloc = NULL;
+ int ret = -1;
+
+ buf = malloc(bufsize);
+ if (buf == NULL) {
+ ERR(sh, "Failure allocating memory.");
+ goto exit;
+ }
+
+ /* Check if the file is bzipped */
+ bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
+ rewind(f);
+ if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
+ goto exit;
+ }
+
+ b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
+ if ( bzerror != BZ_OK ) {
+ ERR(sh, "Failure opening bz2 archive.");
+ goto exit;
+ }
+
+ uncompress = malloc(size);
+ if (uncompress == NULL) {
+ ERR(sh, "Failure allocating memory.");
+ goto exit;
+ }
+
+ while ( bzerror == BZ_OK) {
+ nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
+ if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
+ if (total + nBuf > size) {
+ size *= 2;
+ tmpalloc = realloc(uncompress, size);
+ if (tmpalloc == NULL) {
+ ERR(sh, "Failure allocating memory.");
+ goto exit;
+ }
+ uncompress = tmpalloc;
+ }
+ memcpy(&uncompress[total], buf, nBuf);
+ total += nBuf;
+ }
+ }
+ if ( bzerror != BZ_STREAM_END ) {
+ ERR(sh, "Failure reading bz2 archive.");
+ goto exit;
+ }
+
+ ret = total;
+ *data = uncompress;
+
+exit:
+ BZ2_bzReadClose ( &bzerror, b );
+ free(buf);
+ if ( ret < 0 ) {
+ free(uncompress);
+ }
+ return ret;
+}
+
+int map_compressed_file(semanage_handle_t *sh, const char *path,
+ struct file_contents *contents)
+{
+ ssize_t size = -1;
+ void *uncompress;
+ int ret = 0, fd = -1;
+ FILE *file = NULL;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ ERR(sh, "Unable to open %s\n", path);
+ return -1;
+ }
+
+ file = fdopen(fd, "r");
+ if (file == NULL) {
+ ERR(sh, "Unable to open %s\n", path);
+ close(fd);
+ return -1;
+ }
+
+ if ((size = bunzip(sh, file, &uncompress)) >= 0) {
+ contents->data = uncompress;
+ contents->len = size;
+ contents->compressed = 1;
+ } else {
+ struct stat sb;
+ if (fstat(fd, &sb) == -1 ||
+ (uncompress = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
+ MAP_FAILED) {
+ ret = -1;
+ } else {
+ contents->data = uncompress;
+ contents->len = sb.st_size;
+ contents->compressed = 0;
+ }
+ }
+ fclose(file);
+ return ret;
+}
+
+void unmap_compressed_file(struct file_contents *contents)
+{
+ if (!contents->data)
+ return;
+
+ if (contents->compressed) {
+ free(contents->data);
+ } else {
+ munmap(contents->data, contents->len);
+ }
+}
+
+int write_compressed_file(semanage_handle_t *sh, const char *path,
+ void *data, size_t len)
+{
+ return bzip(sh, path, data, len);
+}
diff --git a/libsemanage/src/compressed_file.h b/libsemanage/src/compressed_file.h
new file mode 100644
index 00000000..96cfb4b6
--- /dev/null
+++ b/libsemanage/src/compressed_file.h
@@ -0,0 +1,78 @@
+/* Author: Jason Tang <jtang@tresys.com>
+ * Christopher Ashworth <cashworth@tresys.com>
+ * Ondrej Mosnacek <omosnacek@gmail.com>
+ *
+ * Copyright (C) 2004-2006 Tresys Technology, LLC
+ * Copyright (C) 2005-2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SEMANAGE_CIL_FILE_H_
+#define _SEMANAGE_CIL_FILE_H_
+
+#include <sys/mman.h>
+#include <sys/types.h>
+
+#include "handle.h"
+
+struct file_contents {
+ void *data; /** file contents (uncompressed) */
+ size_t len; /** length of contents */
+ int compressed; /** whether file was compressed */
+};
+
+/**
+ * Map/read a possibly-compressed file into memory.
+ *
+ * If the file is bzip compressed map_file will uncompress the file into
+ * @p contents. The caller is responsible for calling
+ * @ref unmap_compressed_file on @p contents on success.
+ *
+ * @param sh semanage handle
+ * @param path path to the file
+ * @param contents pointer to struct file_contents, which will be
+ * populated with data pointer, size, and an indication whether
+ * the file was compressed or not
+ *
+ * @return 0 on success, -1 otherwise.
+ */
+int map_compressed_file(semanage_handle_t *sh, const char *path,
+ struct file_contents *contents);
+
+/**
+ * Destroy a previously mapped possibly-compressed file.
+ *
+ * If all fields of @p contents are zero/NULL, the function is
+ * guaranteed to do nothing.
+ *
+ * @param contents pointer to struct file_contents to destroy
+ */
+void unmap_compressed_file(struct file_contents *contents);
+
+/**
+ * Write bytes into a file, using compression if configured.
+ *
+ * @param sh semanage handle
+ * @param path path to the file
+ * @param data pointer to the data
+ * @param len length of the data
+ *
+ * @return 0 on success, -1 otherwise.
+ */
+int write_compressed_file(semanage_handle_t *sh, const char *path,
+ void *data, size_t len);
+
+#endif
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 7638653a..63a18808 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -50,6 +50,7 @@
#include "debug.h"
#include "handle.h"
+#include "compressed_file.h"
#include "modules.h"
#include "direct_api.h"
#include "semanage_store.h"
@@ -446,194 +447,6 @@ static int parse_module_headers(semanage_handle_t * sh, char *module_data,
return 0;
}
-#include <stdlib.h>
-#include <bzlib.h>
-#include <string.h>
-#include <sys/sendfile.h>
-
-/* bzip() a data to a file, returning the total number of compressed bytes
- * in the file. Returns -1 if file could not be compressed. */
-static ssize_t bzip(semanage_handle_t *sh, const char *filename, char *data,
- size_t num_bytes)
-{
- BZFILE* b;
- size_t size = 1<<16;
- int bzerror;
- size_t total = 0;
- size_t len = 0;
- FILE *f;
-
- if ((f = fopen(filename, "wb")) == NULL) {
- return -1;
- }
-
- if (!sh->conf->bzip_blocksize) {
- if (fwrite(data, 1, num_bytes, f) < num_bytes) {
- fclose(f);
- return -1;
- }
- fclose(f);
- return num_bytes;
- }
-
- b = BZ2_bzWriteOpen( &bzerror, f, sh->conf->bzip_blocksize, 0, 0);
- if (bzerror != BZ_OK) {
- BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
- return -1;
- }
-
- while ( num_bytes > total ) {
- if (num_bytes - total > size) {
- len = size;
- } else {
- len = num_bytes - total;
- }
- BZ2_bzWrite ( &bzerror, b, &data[total], len );
- if (bzerror == BZ_IO_ERROR) {
- BZ2_bzWriteClose ( &bzerror, b, 1, 0, 0 );
- return -1;
- }
- total += len;
- }
-
- BZ2_bzWriteClose ( &bzerror, b, 0, 0, 0 );
- fclose(f);
- if (bzerror == BZ_IO_ERROR) {
- return -1;
- }
- return total;
-}
-
-#define BZ2_MAGICSTR "BZh"
-#define BZ2_MAGICLEN (sizeof(BZ2_MAGICSTR)-1)
-
-/* bunzip() a file to '*data', returning the total number of uncompressed bytes
- * in the file. Returns -1 if file could not be decompressed. */
-ssize_t bunzip(semanage_handle_t *sh, FILE *f, char **data)
-{
- BZFILE* b = NULL;
- size_t nBuf;
- char* buf = NULL;
- size_t size = 1<<18;
- size_t bufsize = size;
- int bzerror;
- size_t total = 0;
- char* uncompress = NULL;
- char* tmpalloc = NULL;
- int ret = -1;
-
- buf = malloc(bufsize);
- if (buf == NULL) {
- ERR(sh, "Failure allocating memory.");
- goto exit;
- }
-
- /* Check if the file is bzipped */
- bzerror = fread(buf, 1, BZ2_MAGICLEN, f);
- rewind(f);
- if ((bzerror != BZ2_MAGICLEN) || memcmp(buf, BZ2_MAGICSTR, BZ2_MAGICLEN)) {
- goto exit;
- }
-
- b = BZ2_bzReadOpen ( &bzerror, f, 0, sh->conf->bzip_small, NULL, 0 );
- if ( bzerror != BZ_OK ) {
- ERR(sh, "Failure opening bz2 archive.");
- goto exit;
- }
-
- uncompress = malloc(size);
- if (uncompress == NULL) {
- ERR(sh, "Failure allocating memory.");
- goto exit;
- }
-
- while ( bzerror == BZ_OK) {
- nBuf = BZ2_bzRead ( &bzerror, b, buf, bufsize);
- if (( bzerror == BZ_OK ) || ( bzerror == BZ_STREAM_END )) {
- if (total + nBuf > size) {
- size *= 2;
- tmpalloc = realloc(uncompress, size);
- if (tmpalloc == NULL) {
- ERR(sh, "Failure allocating memory.");
- goto exit;
- }
- uncompress = tmpalloc;
- }
- memcpy(&uncompress[total], buf, nBuf);
- total += nBuf;
- }
- }
- if ( bzerror != BZ_STREAM_END ) {
- ERR(sh, "Failure reading bz2 archive.");
- goto exit;
- }
-
- ret = total;
- *data = uncompress;
-
-exit:
- BZ2_bzReadClose ( &bzerror, b );
- free(buf);
- if ( ret < 0 ) {
- free(uncompress);
- }
- return ret;
-}
-
-/* mmap() a file to '*data',
- * If the file is bzip compressed map_file will uncompress
- * the file into '*data'.
- * Returns the total number of bytes in memory .
- * Returns -1 if file could not be opened or mapped. */
-static ssize_t map_file(semanage_handle_t *sh, const char *path, char **data,
- int *compressed)
-{
- ssize_t size = -1;
- char *uncompress;
- int fd = -1;
- FILE *file = NULL;
-
- fd = open(path, O_RDONLY);
- if (fd == -1) {
- ERR(sh, "Unable to open %s\n", path);
- return -1;
- }
-
- file = fdopen(fd, "r");
- if (file == NULL) {
- ERR(sh, "Unable to open %s\n", path);
- close(fd);
- return -1;
- }
-
- if ((size = bunzip(sh, file, &uncompress)) > 0) {
- *data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
- if (*data == MAP_FAILED) {
- free(uncompress);
- fclose(file);
- return -1;
- } else {
- memcpy(*data, uncompress, size);
- }
- free(uncompress);
- *compressed = 1;
- } else {
- struct stat sb;
- if (fstat(fd, &sb) == -1 ||
- (*data = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
- MAP_FAILED) {
- size = -1;
- } else {
- size = sb.st_size;
- }
- *compressed = 0;
- }
-
- fclose(file);
-
- return size;
-}
-
/* Writes a block of data to a file. Returns 0 on success, -1 on
* error. */
static int write_file(semanage_handle_t * sh,
@@ -1045,15 +858,12 @@ static int semanage_compile_module(semanage_handle_t *sh,
char *compiler_path = NULL;
char *cil_data = NULL;
char *err_data = NULL;
- char *hll_data = NULL;
char *start = NULL;
char *end = NULL;
- ssize_t hll_data_len = 0;
- ssize_t bzip_status;
int status = 0;
- int compressed;
size_t cil_data_len = 0;
size_t err_data_len = 0;
+ struct file_contents hll_contents = {};
if (!strcasecmp(modinfo->lang_ext, "cil")) {
goto cleanup;
@@ -1084,13 +894,15 @@ static int semanage_compile_module(semanage_handle_t *sh,
goto cleanup;
}
- if ((hll_data_len = map_file(sh, hll_path, &hll_data, &compressed)) <= 0) {
+ status = map_compressed_file(sh, hll_path, &hll_contents);
+ if (status < 0) {
ERR(sh, "Unable to read file %s\n", hll_path);
- status = -1;
goto cleanup;
}
- status = semanage_pipe_data(sh, compiler_path, hll_data, (size_t)hll_data_len, &cil_data, &cil_data_len, &err_data, &err_data_len);
+ status = semanage_pipe_data(sh, compiler_path, hll_contents.data,
+ hll_contents.len, &cil_data, &cil_data_len,
+ &err_data, &err_data_len);
if (err_data_len > 0) {
for (start = end = err_data; end < err_data + err_data_len; end++) {
if (*end == '\n') {
@@ -1110,10 +922,9 @@ static int semanage_compile_module(semanage_handle_t *sh,
goto cleanup;
}
- bzip_status = bzip(sh, cil_path, cil_data, cil_data_len);
- if (bzip_status == -1) {
- ERR(sh, "Failed to bzip %s\n", cil_path);
- status = -1;
+ status = write_compressed_file(sh, cil_path, cil_data, cil_data_len);
+ if (status == -1) {
+ ERR(sh, "Failed to write %s\n", cil_path);
goto cleanup;
}
@@ -1131,9 +942,7 @@ static int semanage_compile_module(semanage_handle_t *sh,
}
cleanup:
- if (hll_data_len > 0) {
- munmap(hll_data, hll_data_len);
- }
+ unmap_compressed_file(&hll_contents);
free(cil_data);
free(err_data);
free(compiler_path);
@@ -1749,19 +1558,17 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
{
int retval = -1;
- char *data = NULL;
- ssize_t data_len = 0;
- int compressed = 0;
char *path = NULL;
char *filename;
char *lang_ext = NULL;
char *module_name = NULL;
char *separator;
char *version = NULL;
+ struct file_contents contents = {};
- if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) {
+ retval = map_compressed_file(sh, install_filename, &contents);
+ if (retval < 0) {
ERR(sh, "Unable to read file %s\n", install_filename);
- retval = -1;
goto cleanup;
}
@@ -1774,7 +1581,7 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
filename = basename(path);
- if (compressed) {
+ if (contents.compressed) {
separator = strrchr(filename, '.');
if (separator == NULL) {
ERR(sh, "Compressed module does not have a valid extension.");
@@ -1798,7 +1605,8 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
}
if (strcmp(lang_ext, "pp") == 0) {
- retval = parse_module_headers(sh, data, data_len, &module_name, &version);
+ retval = parse_module_headers(sh, contents.data, contents.len,
+ &module_name, &version);
free(version);
if (retval != 0)
goto cleanup;
@@ -1815,10 +1623,11 @@ static int semanage_direct_install_file(semanage_handle_t * sh,
fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename);
}
- retval = semanage_direct_install(sh, data, data_len, module_name, lang_ext);
+ retval = semanage_direct_install(sh, contents.data, contents.len,
+ module_name, lang_ext);
cleanup:
- if (data_len > 0) munmap(data, data_len);
+ unmap_compressed_file(&contents);
free(module_name);
free(path);
@@ -1837,10 +1646,8 @@ static int semanage_direct_extract(semanage_handle_t * sh,
enum semanage_module_path_type file_type;
int rc = -1;
semanage_module_info_t *_modinfo = NULL;
- ssize_t _data_len;
- char *_data;
- int compressed;
struct stat sb;
+ struct file_contents contents = {};
/* get path of module */
rc = semanage_module_get_path(
@@ -1896,19 +1703,33 @@ static int semanage_direct_extract(semanage_handle_t * sh,
}
}
- _data_len = map_file(sh, input_file, &_data, &compressed);
- if (_data_len <= 0) {
+ rc = map_compressed_file(sh, input_file, &contents);
+ if (rc < 0) {
ERR(sh, "Error mapping file: %s", input_file);
- rc = -1;
goto cleanup;
}
+ /* The API promises an mmap'ed pointer */
+ if (contents.compressed) {
+ *mapped_data = mmap(NULL, contents.len, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
+ if (*mapped_data == MAP_FAILED) {
+ ERR(sh, "Unable to map memory");
+ rc = -1;
+ goto cleanup;
+ }
+ memcpy(*mapped_data, contents.data, contents.len);
+ free(contents.data);
+ } else {
+ *mapped_data = contents.data;
+ }
+
*modinfo = _modinfo;
- *data_len = (size_t)_data_len;
- *mapped_data = _data;
+ *data_len = contents.len;
cleanup:
if (rc != 0) {
+ unmap_compressed_file(&contents);
semanage_module_info_destroy(sh, _modinfo);
free(_modinfo);
}
@@ -2857,8 +2678,8 @@ static int semanage_direct_install_info(semanage_handle_t *sh,
goto cleanup;
}
- ret = bzip(sh, path, data, data_len);
- if (ret <= 0) {
+ ret = write_compressed_file(sh, path, data, data_len);
+ if (ret < 0) {
ERR(sh, "Error while writing to %s.", path);
status = -3;
goto cleanup;
diff --git a/libsemanage/src/direct_api.h b/libsemanage/src/direct_api.h
index e56107b2..ffd428eb 100644
--- a/libsemanage/src/direct_api.h
+++ b/libsemanage/src/direct_api.h
@@ -39,8 +39,4 @@ int semanage_direct_access_check(struct semanage_handle *sh);
int semanage_direct_mls_enabled(struct semanage_handle *sh);
-#include <stdio.h>
-#include <unistd.h>
-ssize_t bunzip(struct semanage_handle *sh, FILE *f, char **data);
-
#endif
diff --git a/libsemanage/src/semanage_store.c b/libsemanage/src/semanage_store.c
index ae023582..c5ce071c 100644
--- a/libsemanage/src/semanage_store.c
+++ b/libsemanage/src/semanage_store.c
@@ -59,6 +59,7 @@ typedef struct dbase_policydb dbase_t;
#include "debug.h"
#include "utilities.h"
+#include "compressed_file.h"
#define SEMANAGE_CONF_FILE "semanage.conf"
/* relative path names to enum semanage_paths to special files and
@@ -2055,60 +2056,27 @@ int semanage_direct_get_serial(semanage_handle_t * sh)
int semanage_load_files(semanage_handle_t * sh, cil_db_t *cildb, char **filenames, int numfiles)
{
- int retval = 0;
- FILE *fp;
- ssize_t size;
- char *data = NULL;
+ int i, retval = 0;
char *filename;
- int i;
+ struct file_contents contents = {};
for (i = 0; i < numfiles; i++) {
filename = filenames[i];
- if ((fp = fopen(filename, "rb")) == NULL) {
- ERR(sh, "Could not open module file %s for reading.", filename);
- goto cleanup;
- }
-
- if ((size = bunzip(sh, fp, &data)) <= 0) {
- rewind(fp);
- __fsetlocking(fp, FSETLOCKING_BYCALLER);
-
- if (fseek(fp, 0, SEEK_END) != 0) {
- ERR(sh, "Failed to determine size of file %s.", filename);
- goto cleanup;
- }
- size = ftell(fp);
- rewind(fp);
-
- data = malloc(size);
- if (fread(data, size, 1, fp) != 1) {
- ERR(sh, "Failed to read file %s.", filename);
- goto cleanup;
- }
- }
+ retval = map_compressed_file(sh, filename, &contents);
+ if (retval < 0)
+ return -1;
- fclose(fp);
- fp = NULL;
+ retval = cil_add_file(cildb, filename, contents.data, contents.len);
+ unmap_compressed_file(&contents);
- retval = cil_add_file(cildb, filename, data, size);
if (retval != SEPOL_OK) {
ERR(sh, "Error while reading from file %s.", filename);
- goto cleanup;
+ return -1;
}
-
- free(data);
- data = NULL;
}
- return retval;
-
- cleanup:
- if (fp != NULL) {
- fclose(fp);
- }
- free(data);
- return -1;
+ return 0;
}
/*
--
2.30.2

View File

@ -1,150 +0,0 @@
From 129e121c9ab17f726a9a6294cfe04db97016e7ef Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Thu, 3 Feb 2022 17:53:25 +0100
Subject: [PATCH] libsemanage: clean up semanage_direct_commit() a bit
Do some minor cosmetic cleanup, mainly to eliminate the 'rebuilt' goto
label.
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
libsemanage/src/direct_api.c | 91 ++++++++++++++++++------------------
1 file changed, 45 insertions(+), 46 deletions(-)
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 63a18808..7e99a59f 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -994,6 +994,16 @@ cleanup:
return status;
}
+/* Files that must exist in order to skip policy rebuild. */
+static const int semanage_computed_files[] = {
+ SEMANAGE_STORE_KERNEL,
+ SEMANAGE_STORE_FC,
+ SEMANAGE_STORE_SEUSERS,
+ SEMANAGE_LINKED,
+ SEMANAGE_SEUSERS_LINKED,
+ SEMANAGE_USERS_EXTRA_LINKED
+};
+
/* Copies a file from src to dst. If dst already exists then
* overwrite it. If source doesn't exist then return success.
* Returns 0 on success, -1 on error. */
@@ -1053,6 +1063,14 @@ static int semanage_direct_commit(semanage_handle_t * sh)
seusers_modified = seusers->dtable->is_modified(seusers->dbase);
fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase);
+ /* Before we do anything else, flush the join to its component parts.
+ * This *does not* flush to disk automatically */
+ if (users->dtable->is_modified(users->dbase)) {
+ retval = users->dtable->flush(sh, users->dbase);
+ if (retval < 0)
+ goto cleanup;
+ }
+
/* Rebuild if explicitly requested or any module changes occurred. */
do_rebuild = sh->do_rebuild | sh->modules_modified;
@@ -1119,14 +1137,6 @@ static int semanage_direct_commit(semanage_handle_t * sh)
}
}
- /* Before we do anything else, flush the join to its component parts.
- * This *does not* flush to disk automatically */
- if (users->dtable->is_modified(users->dbase)) {
- retval = users->dtable->flush(sh, users->dbase);
- if (retval < 0)
- goto cleanup;
- }
-
/*
* This is for systems that have already migrated with an older version
* of semanage_migrate_store. The older version did not copy
@@ -1135,48 +1145,20 @@ static int semanage_direct_commit(semanage_handle_t * sh)
* in order to skip re-linking are present; otherwise, we force
* a rebuild.
*/
- if (!do_rebuild) {
- int files[] = {SEMANAGE_STORE_KERNEL,
- SEMANAGE_STORE_FC,
- SEMANAGE_STORE_SEUSERS,
- SEMANAGE_LINKED,
- SEMANAGE_SEUSERS_LINKED,
- SEMANAGE_USERS_EXTRA_LINKED};
-
- for (i = 0; i < (int) ARRAY_SIZE(files); i++) {
- path = semanage_path(SEMANAGE_TMP, files[i]);
- if (stat(path, &sb) != 0) {
- if (errno != ENOENT) {
- ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
- retval = -1;
- goto cleanup;
- }
-
- do_rebuild = 1;
- goto rebuild;
+ for (i = 0; !do_rebuild && i < (int)ARRAY_SIZE(semanage_computed_files); i++) {
+ path = semanage_path(SEMANAGE_TMP, semanage_computed_files[i]);
+ if (stat(path, &sb) != 0) {
+ if (errno != ENOENT) {
+ ERR(sh, "Unable to access %s: %s\n", path, strerror(errno));
+ retval = -1;
+ goto cleanup;
}
+
+ do_rebuild = 1;
+ break;
}
}
-rebuild:
- /*
- * Now that we know whether or not a rebuild is required,
- * we can determine what else needs to be done.
- * We need to write the kernel policy if we are rebuilding
- * or if any other policy component that lives in the kernel
- * policy has been modified.
- * We need to install the policy files if any of the managed files
- * that live under /etc/selinux (kernel policy, seusers, file contexts)
- * will be modified.
- */
- do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
- ibendports_modified |
- bools->dtable->is_modified(bools->dbase) |
- ifaces->dtable->is_modified(ifaces->dbase) |
- nodes->dtable->is_modified(nodes->dbase) |
- users->dtable->is_modified(users_base->dbase);
- do_install = do_write_kernel | seusers_modified | fcontexts_modified;
-
/*
* If there were policy changes, or explicitly requested, or
* any required files are missing, rebuild the policy.
@@ -1323,6 +1305,23 @@ rebuild:
}
}
+ /*
+ * Determine what else needs to be done.
+ * We need to write the kernel policy if we are rebuilding
+ * or if any other policy component that lives in the kernel
+ * policy has been modified.
+ * We need to install the policy files if any of the managed files
+ * that live under /etc/selinux (kernel policy, seusers, file contexts)
+ * will be modified.
+ */
+ do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
+ ibendports_modified |
+ bools->dtable->is_modified(bools->dbase) |
+ ifaces->dtable->is_modified(ifaces->dbase) |
+ nodes->dtable->is_modified(nodes->dbase) |
+ users->dtable->is_modified(users_base->dbase);
+ do_install = do_write_kernel | seusers_modified | fcontexts_modified;
+
/* Attach our databases to the policydb we just created or loaded. */
dbase_policydb_attach((dbase_policydb_t *) pusers_base->dbase, out);
dbase_policydb_attach((dbase_policydb_t *) pports->dbase, out);
--
2.30.2

View File

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

View File

@ -1,59 +0,0 @@
From 330b6efa010b3dac732beb49c98894a99dab0545 Mon Sep 17 00:00:00 2001
From: Ondrej Mosnacek <omosnace@redhat.com>
Date: Wed, 8 Jun 2022 19:09:53 +0200
Subject: [PATCH] libsemanage: always write kernel policy when
check_ext_changes is specified
For the use case of rebuilding the policy after package updates, we need
the check_ext_changes operation to always do at least the do_write_kernel
step, because the various semanage dbs may have also changed content
relative to the current binary policy. As this step is itself relatively
fast, we can do it unconditionally.
Fixes: 286a679fadc4 ("libsemanage: optionally rebuild policy when modules are changed externally")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
---
libsemanage/include/semanage/handle.h | 2 +-
libsemanage/src/direct_api.c | 8 +++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/libsemanage/include/semanage/handle.h b/libsemanage/include/semanage/handle.h
index 7f298a49..df919a14 100644
--- a/libsemanage/include/semanage/handle.h
+++ b/libsemanage/include/semanage/handle.h
@@ -67,7 +67,7 @@ void semanage_set_reload(semanage_handle_t * handle, int do_reload);
void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild);
/* set whether to rebuild the policy on commit when potential changes
- * to module files since last rebuild are detected,
+ * to store files since last rebuild are detected,
* 1 for yes (default), 0 for no */
extern void semanage_set_check_ext_changes(semanage_handle_t * handle, int do_check);
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index bbdca2b2..252fc5bb 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1430,13 +1430,15 @@ static int semanage_direct_commit(semanage_handle_t * sh)
* Determine what else needs to be done.
* We need to write the kernel policy if we are rebuilding
* or if any other policy component that lives in the kernel
- * policy has been modified.
+ * policy has been modified. We also want to force it when
+ * check_ext_changes was specified as the various dbases may have
+ * changes as well.
* We need to install the policy files if any of the managed files
* that live under /etc/selinux (kernel policy, seusers, file contexts)
* will be modified.
*/
- do_write_kernel = do_rebuild | ports_modified | ibpkeys_modified |
- ibendports_modified |
+ do_write_kernel = do_rebuild | sh->check_ext_changes |
+ ports_modified | ibpkeys_modified | ibendports_modified |
bools->dtable->is_modified(bools->dbase) |
ifaces->dtable->is_modified(ifaces->dbase) |
nodes->dtable->is_modified(nodes->dbase) |
--
2.37.3

7
gating.yaml Normal file
View File

@ -0,0 +1,7 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View File

@ -1,40 +1,35 @@
%define libsepolver 2.9-1
%define libselinuxver 2.9-1
%define libsepolver 3.6-1
%define libselinuxver 3.6-1
Summary: SELinux binary policy manipulation library
Summary: SELinux binary policy manipulation library
Name: libsemanage
Version: 2.9
Release: 9%{?dist}
Version: 3.6
Release: 3%{?dist}
License: LGPLv2+
Source0: https://github.com/SELinuxProject/selinux/releases/download/20190315/libsemanage-2.9.tar.gz
Source0: https://github.com/SELinuxProject/selinux/releases/download/3.6/libsemanage-3.6.tar.gz
# fedora-selinux/selinux: git checkout c9s; git format-patch -N 3.6 -- libsemanage
# i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done
Patch0001: 0001-libsemanage-Fix-RESOURCE_LEAK-and-USE_AFTER_FREE-cov.patch
Patch0002: 0002-libsemanage-Add-support-for-DCCP-and-SCTP-protocols.patch
Patch0003: 0003-libsemanage-fsync-final-files-before-rename.patch
Patch0004: 0004-libsemanage-sync-filesystem-with-sandbox.patch
Patch0005: 0005-Trivial-style-fixes.patch
Patch0006: 0006-libsemanage-Free-contents-of-modkey-in-semanage_dire.patch
Patch0007: 0007-libsemanage-Fix-USE_AFTER_FREE-CWE-672-in-semanage_d.patch
Patch0008: 0008-libsemanage-add-missing-include-to-boolean_record.c.patch
Patch0009: 0009-semodule-libsemanage-move-module-hashing-into-libsem.patch
Patch0010: 0010-libsemanage-move-compressed-file-handling-into-a-sep.patch
Patch0011: 0011-libsemanage-clean-up-semanage_direct_commit-a-bit.patch
Patch0012: 0012-libsemanage-optionally-rebuild-policy-when-modules-a.patch
Patch0013: 0013-libsemanage-always-write-kernel-policy-when-check_ex.patch
# Patch list start
Patch0001: 0001-Revert-Do-not-automatically-install-Russian-translat.patch
Patch0002: 0002-Revert-libsemanage-Remove-the-Russian-translations.patch
Patch0003: 0003-libsemanage-Preserve-file-context-and-ownership-in-p.patch
Patch0004: 0004-libsemanage-open-lock_file-with-O_RDWR.patch
# Patch list end
URL: https://github.com/SELinuxProject/selinux/wiki
Source1: semanage.conf
BuildRequires: gcc
BuildRequires: gcc make
BuildRequires: libselinux-devel >= %{libselinuxver} swig
BuildRequires: libsepol-devel >= %{libsepolver}
BuildRequires: audit-libs-devel
BuildRequires: bison flex bzip2-devel
BuildRequires: python3
BuildRequires: python3-devel
BuildRequires: python3-devel python3-pip
Requires: bzip2-libs audit-libs
Requires: libselinux%{?_isa} >= %{libselinuxver}
Obsoletes: libsemanage-compat = 3.1-4
%description
Security-enhanced Linux is a feature of the Linux® kernel and a number
@ -83,11 +78,12 @@ The libsemanage-python3 package contains the python 3 bindings for developing
SELinux management applications.
%prep
%autosetup -n libsemanage-%{version} -p 2
%autosetup -p 2 -n libsemanage-%{version}
%build
%set_build_flags
CFLAGS="$CFLAGS -fno-semantic-interposition"
# To support building the Python wrapper against multiple Python runtimes
# Define a function, for how to perform a "build" of the python wrapper against
@ -104,7 +100,7 @@ BuildPythonWrapper() {
make clean
make swigify
make LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" all
%make_build LIBDIR="%{_libdir}" SHLIBDIR="%{_lib}" all
BuildPythonWrapper \
%{__python3}
@ -123,24 +119,19 @@ mkdir -p ${RPM_BUILD_ROOT}%{_libdir}
mkdir -p ${RPM_BUILD_ROOT}%{_includedir}
mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux
mkdir -p ${RPM_BUILD_ROOT}%{_sharedstatedir}/selinux/tmp
make DESTDIR="${RPM_BUILD_ROOT}" LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}" install
%make_install LIBDIR="%{_libdir}" SHLIBDIR="%{_libdir}"
InstallPythonWrapper \
%{__python3} \
$(python3-config --extension-suffix)
cp %{SOURCE1} ${RPM_BUILD_ROOT}/etc/selinux/semanage.conf
ln -sf %{_libdir}/libsemanage.so.1 ${RPM_BUILD_ROOT}/%{_libdir}/libsemanage.so
pathfix.py -i "%{__python3} -E" -p %{buildroot}%{_libexecdir}/selinux/semanage_migrate_store
rm %{buildroot}%{_libexecdir}/selinux/semanage_migrate_store~
cp %{SOURCE1} ${RPM_BUILD_ROOT}%{_sysconfdir}/selinux/semanage.conf
%files
%{!?_licensedir:%global license %%doc}
%license COPYING
%license LICENSE
%dir %{_sysconfdir}/selinux
%config(noreplace) %{_sysconfdir}/selinux/semanage.conf
%{_libdir}/libsemanage.so.1
%{_libdir}/libsemanage.so.2
%{_mandir}/man5/*
%{_mandir}/ru/man5/*
%dir %{_libexecdir}/selinux
@ -166,55 +157,162 @@ rm %{buildroot}%{_libexecdir}/selinux/semanage_migrate_store~
%{_libexecdir}/selinux/semanage_migrate_store
%changelog
* Tue Oct 11 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-9
- always write kernel policy when check_ext_changes is specified (#2129139)
* Fri Nov 08 2024 Petr Lautrbach <lautrbach@redhat.com> - 3.6-3
- open lock_file with O_RDWR (RHEL-60503)
* Tue Feb 22 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-8
- Bump release to get around OSCI issues
* Tue Aug 06 2024 Vit Mojzis <vmojzis@redhat.com> - 3.6-2
- Preserve file context and ownership in policy store (RHEL-31216, RHEL-54389)
* Thu Feb 17 2022 Vit Mojzis <vmojzis@redhat.com> - 2.9-7
- Trivial style fixes
- Free contents of modkey in semanage_direct_remove
- Fix USE_AFTER_FREE (CWE-672) in semanage_direct_write_langext()
- add missing include to boolean_record.c
- move module hashing into libsemanage
- move compressed file handling into a separate object
- clean up semanage_direct_commit() a bit
* Wed Dec 13 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.6-1
- SELinux userspace 3.6 release
* Mon Nov 13 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.6-0.rc1.1
- SELinux userspace 3.6-rc1 release
* Wed Mar 22 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.5-2
- Include more parameters in the module checksum (#2173959)
* Thu Feb 23 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.5-1
- SELinux userspace 3.5 release
* Tue Feb 14 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.5-0.rc3.1
- SELinux userspace 3.5-rc3 release
* Tue Jan 17 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.5-0.rc2.1
- SELinux userspace 3.5-rc2 release
* Mon Jan 2 2023 Petr Lautrbach <lautrbach@redhat.com> - 3.5-0.rc1.1
- SELinux userspace 3.5-rc1 release
* Mon Jul 18 2022 Petr Lautrbach <plautrba@redhat.com> - 3.4-2
- Always write kernel policy when check_ext_changes is specified (#2104935)
* Thu May 19 2022 Petr Lautrbach <plautrba@redhat.com> - 3.4-1
- SELinux userspace 3.4 release
* Wed Apr 27 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-3
- allow spaces in user/group names (#2049665)
- Fall back to semanage_copy_dir when rename() fails (#2068085)
* Tue Feb 15 2022 Petr Lautrbach <plautrba@redhat.com> - 3.3-2
- optionally rebuild policy when modules are changed externally
- add command-line option to detect module changes (#2049186)
* Mon Feb 1 2021 Petr Lautrbach <plautrba@redhat.com> - 2.9-6
- sync filesystem with sandbox (#1913224)
* Fri Oct 22 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-1
- SELinux userspace 3.3 release
* Mon Dec 21 2020 Petr Lautrbach <plautrba@redhat.com> - 2.9-5
- Revert "genhomedircon: check usepasswd" (rhbz#1871786)
- semanage.conf - improve usepasswd=False explanation (rhbz#1871786)
- semanage.conf - expand list of ignoredirs (rhbz#1871786)
* Sun Oct 10 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-0.rc3.1
- SELinux userspace 3.3-rc3 release
* Sun Nov 22 2020 Vit Mojzis <vmojzis@redhat.com> - 2.9-4
- genhomedircon: check usepasswd (rhbz#1871786)
* Wed Sep 29 2021 Petr Lautrbach <plautrba@redhat.com> - 3.3-0.rc2.1
- SELinux userspace 3.3-rc2 release
* Mon Jun 29 2020 Vit Mojzis <vmojzis@redhat.com> - 2.9-3
- Fsync final files before rename (#1838762)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.2-4
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Nov 06 2019 Vit Mojzis <vmojzis@redhat.com> - 2.9-2
- Add support for DCCP and SCTP protocols (#1563742)
* Wed Jul 28 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-4
- Rebase on upstream commit 32611aea6543
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.2-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Mon Mar 8 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-1
- SELinux userspace 3.2 release
* Fri Feb 5 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-0.rc2.1
- SELinux userspace 3.2-rc2 release
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.2-0.rc1.1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jan 20 2021 Petr Lautrbach <plautrba@redhat.com> - 3.2-0.rc1.1
- SELinux userspace 3.2-rc1 release
* Fri Dec 18 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-6
- Drop "genhomedircon: check usepasswd" patch
- genhomedircon to ignore
/root;/bin;/boot;/dev;/etc;/lib;/lib64;/proc;/run;/sbin;/sys;/tmp;/usr;/var by default
- Fix usepasswd=False explanation in semanage.conf
* Fri Nov 20 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-5
- Drop and obsolete libsemanage-compat
- genhomedircon: check usepasswd
* Fri Oct 30 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-4
- Drop deprecated functions and duplicated symbols
- Change library version to libsemanage.so.2
- Temporary ship -compat with libsemanage.so.1
- Based on upstream db0f2f382e31
- Re-enable lto flags
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 3.1-2
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
- Use -fno-semantic-interposition and more make macros
* Fri Jul 10 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-1
- SELinux userspace 3.1 release
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 3.0-4
- Rebuilt for Python 3.9
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Wed Jan 22 2020 Ondrej Mosnacek <omosnace@redhat.com> - 3.0-2
- Enable policy optimization
* Fri Dec 6 2019 Petr Lautrbach <plautrba@redhat.com> - 3.0-1
- SELinux userspace 3.0 release
* Mon Nov 11 2019 Petr Lautrbach <plautrba@redhat.com> - 3.0-0.rc1.1
- SELinux userspace 3.0-rc1 release candidate
* Thu Oct 03 2019 Miro Hrončok <mhroncok@redhat.com> - 2.9-5
- Rebuilt for Python 3.8.0rc1 (#1748018)
* Sun Aug 18 2019 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 2.9-4
- Rebuilt for Python 3.8
* Tue Aug 13 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-3
- Drop python2-libsemanage (#1738466)
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.9-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon Mar 18 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-1
- SELinux userspace 2.9 release
* Thu Dec 6 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-5
* Mon Mar 11 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-0.rc2.1
- SELinux userspace 2.9-rc2 release
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.9-0.rc1.1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jan 25 2019 Petr Lautrbach <plautrba@redhat.com> - 2.9-0.rc1.1
- SELinux userspace 2.9-rc1 release
* Mon Jan 21 2019 Petr Lautrbach <plautrba@redhat.com> - 2.8-8
- Always set errno to 0 before calling getpwent()
- Set selinux policy root around calls to selinux_boolean_sub
* Mon Dec 10 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-7
- genhomedircon - improve handling large groups
* Thu Nov 8 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-4
* Tue Nov 13 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-6
- Fix RESOURCE_LEAK and USE_AFTER_FREE coverity scan defects
* Mon Sep 17 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-3.1
- reset umask before creating directories
* Mon Sep 17 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-5
- Include user name in ROLE_REMOVE audit events
* Wed Jun 6 2018 Petr Lautrbach <plautrba@workstation> - 2.8-2
- Don't build the Python 2 subpackage (#1567359)
* Tue Sep 4 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-4
- Reset umask before creating directories (#1186422)
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.8-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jun 19 2018 Miro Hrončok <mhroncok@redhat.com> - 2.8-2
- Rebuilt for Python 3.7
* Fri May 25 2018 Petr Lautrbach <plautrba@redhat.com> - 2.8-1
- SELinux userspace 2.8 release

7
plans/selinux.fmf Normal file
View File

@ -0,0 +1,7 @@
summary: selinux tests - Tier 1 | libsemanage
discover:
how: fmf
url: https://src.fedoraproject.org/tests/selinux
filter: "tier: 1 | component: libsemanage"
execute:
how: tmt

View File

@ -52,6 +52,7 @@ usepasswd=False
bzip-small=true
bzip-blocksize=5
ignoredirs=/root;/bin;/boot;/dev;/etc;/lib;/lib64;/proc;/run;/sbin;/sys;/tmp;/usr;/var
optimize-policy=true
[sefcontext_compile]
path = /usr/sbin/sefcontext_compile

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (libsemanage-3.6.tar.gz) = 8998b6a1b254a9673b99ae4d70a1edc769bb728a44f573cdf62e0a9c9392b77644ee2d70e1936a2f8a9a7f8b063ce98a981f4b8b7060f5b82791889330d69364

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libsemanage/Sanity/semanage-handle-functions
# Description: Test functions from handle.h
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/libsemanage/Sanity/semanage-handle-functions
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE functions.c test_*.c
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Jan Zarsky <jzarsky@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test functions from handle.h" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RunFor: libsemanage" >> $(METADATA)
@echo "Requires: libsemanage libsemanage-devel glibc gcc" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2+" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
@echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libsemanage/Sanity/semanage-handle-functions
Description: Test functions from handle.h
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -0,0 +1,132 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
void check_result_int(const char *expected, int real) {
int exp = strtol(expected, NULL, 10);
if (exp != real) {
fprintf(stderr, "Expected %d but got %d\n", exp, real);
exit(1);
}
}
semanage_handle_t *test_handle_create() {
semanage_handle_t *sh = NULL;
sh = semanage_handle_create();
printf("semanage_handle_create(): %p\n", (void *) sh);
if (sh == NULL) {
perror("semanage_handle_create");
exit(1);
}
return sh;
}
int test_connect(semanage_handle_t *sh) {
int result = semanage_connect(sh);
printf("semanage_connect(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_connect");
exit(1);
}
return result;
}
int test_disconnect(semanage_handle_t *sh) {
int result = semanage_disconnect(sh);
printf("semanage_disconnect(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_disconnect");
exit(1);
}
return result;
}
int test_begin_transaction(semanage_handle_t *sh) {
int result = semanage_begin_transaction(sh);
printf("semanage_begin_transaction(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_begin_transaction");
exit(1);
}
return result;
}
int test_commit(semanage_handle_t *sh) {
int result = semanage_commit(sh);
printf("semanage_commit(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_commit");
exit(1);
}
return result;
}
#define STATE_INIT 1
#define STATE_HANDLE 2
#define STATE_CONN 3
#define STATE_TRANS 4
int get_state(const char *state_str) {
if (strcmp(state_str, "init") == 0)
return STATE_INIT;
if (strcmp(state_str, "handle") == 0)
return STATE_HANDLE;
if (strcmp(state_str, "conn") == 0)
return STATE_CONN;
if (strcmp(state_str, "trans") == 0)
return STATE_TRANS;
return 0;
}
semanage_handle_t * get_handle(const char *state_str) {
int state;
semanage_handle_t *sh = NULL;
state = get_state(state_str);
if (state >= STATE_INIT)
sh = NULL;
if (state >= STATE_HANDLE)
sh = test_handle_create();
if (state >= STATE_CONN)
test_connect(sh);
if (state >= STATE_TRANS)
test_begin_transaction(sh);
return sh;
}
void destroy_handle(semanage_handle_t *sh, const char *state_str) {
int state;
state = get_state(state_str);
if (state >= STATE_TRANS)
test_commit(sh);
if (state >= STATE_CONN)
test_disconnect(sh);
if (state >= STATE_HANDLE) {
semanage_handle_destroy(sh);
printf("semanage_handle_destroy(%p)\n", (void *) sh);
}
}

View File

@ -0,0 +1,29 @@
init handle conn trans
semanage_set_root x ok ok ok -
semanage_root x ok ok ok -
semanage_handle_create x ok - - -
semanage_set_rebuild fail ok ok -
semanage_set_reload fail ok ok -
semanage_get_hll_compiler_path fail ? ? -
semanage_set_create_store fail ok ok - should be called after connect
semanage_get_disable_dontaudit fail ? ? -
semanage_set_disable_dontaudit fail ? ? -
semanage_get_preserve_tunables fail ? ? -
semanage_set_preserve_tunables fail ? ? -
semanage_get_ignore_module_cache fail ? ? -
semanage_set_ignore_module_cache fail ? ? -
semanage_set_check_contexts fail ok ok -
semanage_get_default_priority fail ok ok -
semanage_set_default_priority fail ok ok -
semanage_is_connected x fail ok ok -
semanage_select_store fail ok ok - should be called before connect
semanage_set_store_root fail ok ok -
semanage_is_managed x fail ok fail -
semanage_mls_enabled x fail ? ok -
semanage_connect x fail ok ? -
semanage_access_check x fail ok ? -
semanage_disconnect x fail fail ok - ok when disconnected twice
semanage_handle_destroy x fail ok ok -
semanage_begin_transaction x fail fail ok ok ok when begin twice
semanage_commit x fail fail fail ok
semanage_reload_policy fail ? ? ?

View File

@ -0,0 +1,122 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/libsemanage/Sanity/semanage-handle-functions
# Description: Test functions from handle.h
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="libsemanage"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
rlAssertRpm ${PACKAGE}-devel
rlAssertRpm "glibc"
rlAssertRpm "gcc"
if rlIsRHEL ">=7" || rlIsFedora; then
rlRun -l "gcc test_root.c -o test_root -lsemanage -Wall -Wextra -std=c99"
fi
rlRun -l "gcc test_handle_create.c -o test_handle_create -lsemanage -Wall -Wextra -Wno-unused-parameter -std=c99"
rlRun -l "gcc test_access_check.c -o test_access_check -lsemanage -Wall -Wextra -std=c99"
rlRun -l "gcc test_is_managed.c -o test_is_managed -lsemanage -Wall -Wextra -std=c99"
rlRun -l "gcc test_connect.c -o test_connect -lsemanage -Wall -Wextra -std=c99"
rlRun -l "gcc test_is_connected.c -o test_is_connected -lsemanage -Wall -Wextra -std=c99"
rlRun -l "gcc test_mls_enabled.c -o test_mls_enabled -lsemanage -Wall -Wextra -std=c99"
rlRun -l "gcc test_transaction.c -o test_transaction -lsemanage -Wall -Wextra -std=c99"
ERR_FAIL=1
ERR_ABORT=134
rlPhaseEnd
if rlIsRHEL ">=7" || rlIsFedora; then
rlPhaseStartTest "semanage_root, semanage_test_root"
rlRun "./test_root init"
rlRun "./test_root handle"
rlRun "./test_root conn"
rlRun "./test_root init /somepath"
rlRun "./test_root handle /somepath"
rlRun "./test_root conn /somepath"
rlPhaseEnd
fi
rlPhaseStartTest "semanage_handle_create, semanage_handle_destroy"
rlRun "./test_handle_create init"
rlPhaseEnd
rlPhaseStartTest "semanage_access_check"
rlRun "./test_access_check init" $ERR_ABORT
rlRun "./test_access_check handle 2"
rlRun "./test_access_check conn 2"
rlPhaseEnd
rlPhaseStartTest "semanage_is_managed"
rlRun "./test_is_managed init" $ERR_ABORT
rlRun "./test_is_managed handle 1"
rlRun "./test_is_managed conn" $ERR_FAIL
rlPhaseEnd
rlPhaseStartTest "semanage_connect, semanage_disconnect"
rlRun "./test_connect init" $ERR_ABORT
rlRun "./test_connect init reversed" $ERR_ABORT
rlRun "./test_connect handle"
rlRun "./test_connect handle twice"
rlRun "./test_connect handle reversed" $ERR_ABORT
# why does it work??
rlRun "./test_connect conn"
rlPhaseEnd
rlPhaseStartTest "semanage_is_connected"
rlRun "./test_is_connected init" $ERR_ABORT
rlRun "./test_is_connected handle 0"
rlRun "./test_is_connected conn 1"
rlPhaseEnd
rlPhaseStartTest "semanage_mls_enabled"
rlRun "./test_mls_enabled init" $ERR_ABORT
rlRun "./test_mls_enabled handle" $ERR_ABORT
rlRun "./test_mls_enabled conn 1"
rlPhaseEnd
rlPhaseStartTest "semanage_begin_transaction, semanage_commit"
rlRun "./test_transaction init" $ERR_ABORT
rlRun "./test_transaction init reversed" $ERR_ABORT
rlRun "./test_transaction handle" $ERR_ABORT
rlRun "./test_transaction handle reversed" $ERR_ABORT
rlRun "./test_transaction conn"
rlRun "./test_transaction conn twice"
rlRun "./test_transaction conn reversed" $ERR_FAIL
rlPhaseEnd
rlPhaseStartCleanup
rlRun "rm -f output test_root test_handle_create test_access_check \
test_is_managed test_connect test_is_connected \
test_mls_enabled test_transaction"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
int result = semanage_access_check(sh);
printf("semanage_access_check(%p): %d\n", (void *) sh, result);
if (result < 0 || (result != 0 && result != SEMANAGE_CAN_READ
&& result != SEMANAGE_CAN_WRITE)) {
perror("semanage_access_check");
exit(1);
}
if (argc >= 3)
check_result_int(argv[2], result);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,33 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
if (argc >= 3 && strcmp(argv[2], "reversed") == 0) {
test_disconnect(sh);
test_connect(sh);
}
else {
test_connect(sh);
test_disconnect(sh);
}
if (argc >= 3 && strcmp(argv[2], "twice") == 0) {
test_disconnect(sh);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh = test_handle_create();
semanage_handle_destroy(sh);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
int result;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
result = semanage_is_connected(sh);
printf("semanage_is_connected(%p): %d\n", (void *) sh, result);
if (result != 0 && result != 1) {
perror("semanage_is_connected");
exit(1);
}
if (argc >= 3)
check_result_int(argv[2], result);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
int result;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
result = semanage_is_managed(sh);
printf("semanage_is_managed(%p): %d\n", (void *) sh, result);
if (result != 0 && result != 1) {
perror("semanage_is_managed");
exit(1);
}
if (argc >= 3)
check_result_int(argv[2], result);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
int result;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
result = semanage_mls_enabled(sh);
printf("semanage_mls_enabled(%p): %d\n", (void *) sh, result);
if (result != 0 && result != 1) {
perror("semanage_mls_enabled");
exit(1);
}
if (argc >= 4)
check_result_int(argv[3], result);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
const char *root;
int result;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
root = semanage_root();
printf("semanage_root(): %s\n", root);
if (root == NULL) {
perror("semanage_root");
exit(1);
}
if (argc >= 3) {
result = semanage_set_root(argv[2]);
printf("semanage_set_root(\"%s\"): %d\n", argv[2], result);
if (root == NULL) {
perror("semanage_set_root");
exit(1);
}
root = semanage_root();
printf("semanage_root(): %s\n", root);
if (result != 0) {
perror("semanage_root");
exit(1);
}
if (strcmp(root, argv[2]) != 0) {
fprintf(stderr, "Expected \"%s\" but got \"%s\"\n", argv[2], root);
exit(1);
}
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
if (argc < 2)
exit(1);
sh = get_handle(argv[1]);
if (argc >= 3 && strcmp(argv[2], "reversed") == 0) {
test_commit(sh);
test_begin_transaction(sh);
}
else if (argc >= 3 && strcmp(argv[2], "twice") == 0) {
test_begin_transaction(sh);
test_begin_transaction(sh);
test_commit(sh);
}
else {
test_begin_transaction(sh);
test_commit(sh);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,63 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libsemanage/Sanity/semanage-seuser-functions
# Description: Test semanage_seuser_* functions
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/libsemanage/Sanity/semanage-seuser-functions
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE functions.c test_*.c
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Jan Zarsky <jzarsky@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Test semanage_seuser_* functions" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 5m" >> $(METADATA)
@echo "RunFor: libsemanage" >> $(METADATA)
@echo "Requires: libsemanage libsemanage-devel glibc gcc" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2+" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
@echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,3 @@
PURPOSE of /CoreOS/libsemanage/Sanity/semanage-seuser-functions
Description: Test semanage_seuser_* functions
Author: Jan Zarsky <jzarsky@redhat.com>

View File

@ -0,0 +1,263 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
void check_result_int(const char *expected, int real) {
int exp = strtol(expected, NULL, 10);
if (exp != real) {
fprintf(stderr, "Expected %d but got %d\n", exp, real);
exit(1);
}
}
semanage_handle_t *test_handle_create() {
semanage_handle_t *sh = NULL;
sh = semanage_handle_create();
printf("semanage_handle_create(): %p\n", (void *) sh);
if (sh == NULL) {
perror("semanage_handle_create");
exit(2);
}
return sh;
}
int test_connect(semanage_handle_t *sh) {
int result = semanage_connect(sh);
printf("semanage_connect(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_connect");
exit(2);
}
return result;
}
int test_disconnect(semanage_handle_t *sh) {
int result = semanage_disconnect(sh);
printf("semanage_disconnect(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_disconnect");
exit(2);
}
return result;
}
int test_begin_transaction(semanage_handle_t *sh) {
int result = semanage_begin_transaction(sh);
printf("semanage_begin_transaction(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_begin_transaction");
exit(2);
}
return result;
}
int test_commit(semanage_handle_t *sh) {
int result = semanage_commit(sh);
printf("semanage_commit(%p): %d\n", (void *) sh, result);
if (result != 0) {
perror("semanage_commit");
exit(2);
}
return result;
}
semanage_seuser_key_t *test_get_key(semanage_handle_t *sh, const char *name) {
semanage_seuser_key_t *key;
int result = semanage_seuser_key_create(sh, name, &key);
printf("semanage_seuser_key_create(%p, %s, %p): %d\n",
(void *) sh, name, (void *) &key, result);
if (key == NULL || result < 0) {
perror("semanage_seuser_key_create");
exit(2);
}
return key;
}
semanage_seuser_t *test_get_seuser_nth(semanage_handle_t *sh, unsigned int index) {
int result;
semanage_seuser_t **records;
unsigned int count;
result = semanage_seuser_list(sh, &records, &count);
printf("semanage_seuser_list(%p, %p, %p): %d\n",
(void *) sh, (void *) &records, (void *) &count, result);
if (result < 0) {
perror("semanage_seuser_list");
exit(2);
}
if (count < index + 1)
exit(2);
return records[index];
}
semanage_seuser_t *test_get_seuser_new(semanage_handle_t *sh) {
int result;
semanage_seuser_t *seuser;
result = semanage_seuser_create(sh, &seuser);
printf("semanage_seuser_create(%p, %p): %d\n",
(void *) sh, (void *) seuser, result);
if (result < 0) {
perror("semanage_seuser_create");
exit(2);
}
return seuser;
}
semanage_seuser_t *test_get_seuser(semanage_handle_t *sh, const char *param) {
if (strcmp(param, "new") == 0)
return test_get_seuser_new(sh);
if (strcmp(param, "first") == 0)
return test_get_seuser_nth(sh, 0);
if (strcmp(param, "second") == 0)
return test_get_seuser_nth(sh, 1);
fprintf(stderr, "Unknown seuser \"%s\" specified\n", param);
exit(2);
}
void test_add_local_seuser(semanage_handle_t *sh, semanage_seuser_t *seuser) {
int result;
semanage_seuser_key_t *key;
result = semanage_seuser_key_extract(sh, seuser, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(2);
}
result = semanage_seuser_modify_local(sh, key, seuser);
printf("semanage_seuser_modify_local(%p, %p, %p): %d\n",
(void *) seuser, (void *) key, (void *) seuser, result);
if (result < 0) {
perror("semanage_seuser_modify_local");
exit(2);
}
}
void test_del_local_seuser(semanage_handle_t *sh, semanage_seuser_t *seuser) {
int result;
semanage_seuser_key_t *key;
result = semanage_seuser_key_extract(sh, seuser, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(2);
}
result = semanage_seuser_del_local(sh, key);
printf("semanage_seuser_del_local(%p, %p): %d\n",
(void *) seuser, (void *) key, result);
if (result < 0) {
perror("semanage_seuser_del_local");
exit(2);
}
}
#define STATE_INIT 1
#define STATE_HANDLE 2
#define STATE_CONN 3
#define STATE_TRANS 4
int get_state(const char *state_str) {
if (strcmp(state_str, "init") == 0)
return STATE_INIT;
if (strcmp(state_str, "handle") == 0)
return STATE_HANDLE;
if (strcmp(state_str, "conn") == 0)
return STATE_CONN;
if (strcmp(state_str, "trans") == 0)
return STATE_TRANS;
return 0;
}
semanage_handle_t * get_handle(const char *state_str) {
int state;
semanage_handle_t *sh = NULL;
state = get_state(state_str);
if (state >= STATE_INIT)
sh = NULL;
if (state >= STATE_HANDLE)
sh = test_handle_create();
if (state >= STATE_CONN)
test_connect(sh);
if (state >= STATE_TRANS)
test_begin_transaction(sh);
return sh;
}
void destroy_handle(semanage_handle_t *sh, const char *state_str) {
int state;
state = get_state(state_str);
if (state >= STATE_TRANS)
test_commit(sh);
if (state >= STATE_CONN)
test_disconnect(sh);
if (state >= STATE_HANDLE) {
semanage_handle_destroy(sh);
printf("semanage_handle_destroy(%p)\n", (void *) sh);
}
}
int strcmp_null(const char *str1, const char *str2) {
if (str1 == NULL && str2 == NULL)
return 0;
if (str1 == NULL) {
if (strcmp(str2, "NULL") == 0)
return 0;
else
return -1;
}
if (str2 == NULL) {
if (strcmp(str1, "NULL") == 0)
return 0;
else
return 1;
}
return strcmp(str1, str2);
}

View File

@ -0,0 +1,255 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/libsemanage/Sanity/semanage-seuser-functions
# Description: Test semanage_seuser_* functions
# Author: Jan Zarsky <jzarsky@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2017 Red Hat, Inc.
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="libsemanage"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
rlAssertRpm ${PACKAGE}-devel
rlAssertRpm "glibc"
rlAssertRpm "gcc"
for f in test_*.c ; do
out=$(echo -n $f | cut -d'.' -f1)
rlRun "gcc $f -o $out -lsemanage -Wall -Wextra -Werror -std=c99"
done
POLICY_TYPE="$(grep -E '^SELINUXTYPE=' /etc/selinux/config | cut -d'=' -f2 | tr '[:upper:]' '[:lower:]' | tr -d ' ')"
if rlIsFedora; then
SEUSERS_PATH="/var/lib/selinux/$POLICY_TYPE/active/seusers"
elif rlIsRHEL '>=7'; then
SEUSERS_PATH="/etc/selinux/$POLICY_TYPE/active/seusers"
else
SEUSERS_PATH="/etc/selinux/$POLICY_TYPE/seusers"
fi
rlRun "cat $SEUSERS_PATH"
SEUSERS_COUNT="$(cat $SEUSERS_PATH | grep -vE '^#|^$' | wc -l)"
rlRun "[[ \"$SEUSERS_COUNT\" -gt 0 ]]"
SEUSERS="$(cat $SEUSERS_PATH | grep -vE '^#|^$' | cut -d':' -f1 | tr '\n' ' ')"
rlRun "[[ -n \"$SEUSERS\" ]]"
first_line="$(cat $SEUSERS_PATH | grep -vE '^#|^$' | head -n 1)"
SEUSER="$(echo -n $first_line | cut -d':' -f1)"
rlRun "[[ -n \"$SEUSER\" ]]"
SEUSER_SENAME="$(echo -n $first_line | cut -d':' -f2)"
rlRun "[[ -n \"$SEUSER_SENAME\" ]]"
SEUSER_MLSRANGE="$(echo -n $first_line | cut -d':' -f3-4)"
rlRun "[[ -n \"$SEUSER_MLSRANGE\" ]]"
SEUSER_NONEXISTENT="nonuser"
SEUSER_DEFAULT="__default__"
ERR_FAIL=1
ERR_ABORT=134
ERR_SEGFAULT=139
# note: each test_*.c program takes first argument which specifies setup
# before executing specified function
# init semanage handle == NULL
# handle semanage handle obtained via semanage_handle_create
# conn connected via semanage_connect
# trans inside transaction, via semanage_begin_transaction
# program returns 1 on error in function, 2 on error in setup
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_key_create, semanage_seuser_key_free"
# FIXME
# rlRun "./test_key_create init $SEUSER" $ERR_ABORT,$ERR_SEGFAULT
# rlRun "./test_key_create handle $SEUSER" $ERR_FAIL
rlRun "./test_key_create conn $SEUSER"
rlRun "./test_key_create trans $SEUSER"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_key_extract"
# FIXME
#rlRun "./test_key_extract conn new"
rlRun "./test_key_extract conn first"
# FIXME
#rlRun "./test_key_extract trans new"
rlRun "./test_key_extract trans first"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_compare"
rlRun "./test_compare conn $SEUSER same"
rlRun "./test_compare conn $SEUSER_NONEXISTENT different"
rlRun "./test_compare trans $SEUSER same"
rlRun "./test_compare trans $SEUSER_NONEXISTENT different"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_compare2"
rlRun "./test_compare2 conn NULL 0" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 conn 0 NULL" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 conn NULL NULL" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 conn 0 0"
rlRun "./test_compare2 conn 0 1"
rlRun "./test_compare2 trans NULL 0" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 trans 0 NULL" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 trans NULL NULL" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_compare2 trans 0 0"
rlRun "./test_compare2 trans 0 1"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_count"
rlRun "./test_count init" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_count handle" $ERR_FAIL
rlRun "./test_count conn $SEUSERS_COUNT"
rlRun "./test_count trans $SEUSERS_COUNT"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_list"
rlRun "./test_list init" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_list handle" $ERR_FAIL
rlRun "./test_list conn $SEUSERS_COUNT $SEUSERS"
rlRun "./test_list trans $SEUSERS_COUNT $SEUSERS"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_iterate"
rlRun "./test_iterate init" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_iterate handle" $ERR_FAIL
rlRun "./test_iterate conn $SEUSERS"
rlRun "./test_iterate trans $SEUSERS"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_exists"
rlRun "./test_exists conn $SEUSER_NONEXISTENT 0"
rlRun "./test_exists conn $SEUSER_DEFAULT 1"
rlRun "./test_exists conn $USER 1"
rlRun "./test_exists trans $SEUSER_NONEXISTENT 0"
rlRun "./test_exists trans $SEUSER_DEFAULT 1"
rlRun "./test_exists trans $SEUSER 1"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_query"
rlRun "./test_query conn $SEUSER_NONEXISTENT" $ERR_FAIL
rlRun "./test_query conn $SEUSER_DEFAULT"
rlRun "./test_query conn $SEUSER"
rlRun "./test_query trans $SEUSER_NONEXISTENT" $ERR_FAIL
rlRun "./test_query trans $SEUSER_DEFAULT"
rlRun "./test_query trans $SEUSER"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_get_name"
rlRun "./test_get_name conn new NULL"
rlRun "./test_get_name conn first $SEUSER"
rlRun "./test_get_name trans new NULL"
rlRun "./test_get_name trans first $SEUSER"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_set_name"
name="someuser"
rlRun "./test_set_name conn $name"
rlRun "./test_set_name trans $name"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_get_sename"
rlRun "./test_get_sename conn new NULL"
rlRun "./test_get_sename conn first $SEUSER_SENAME"
rlRun "./test_get_sename trans new NULL"
rlRun "./test_get_sename trans first $SEUSER_SENAME"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_set_sename"
sename="someuser_u"
rlRun "./test_set_sename conn $sename"
rlRun "./test_set_sename trans $sename"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_get_mlsrange"
rlRun "./test_get_mlsrange conn new NULL"
rlRun "./test_get_mlsrange conn first $SEUSER_MLSRANGE"
rlRun "./test_get_mlsrange trans new NULL"
rlRun "./test_get_mlsrange trans first $SEUSER_MLSRANGE"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_set_mlsrange"
mlsrange="c0-s1:c0.c42"
rlRun "./test_set_mlsrange conn $mlsrange"
rlRun "./test_set_mlsrange trans $mlsrange"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_clone"
# FIXME
#rlRun "./test_clone conn new"
rlRun "./test_clone conn first"
# FIXME
#rlRun "./test_clone trans new"
rlRun "./test_clone trans first"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_create"
# FIXME
#rlRun "./test_create init" $ERR_ABORT,$ERR_SEGFAULT
#rlRun "./test_create handle" $ERR_ABORT,$ERR_SEGFAULT
rlRun "./test_create conn"
rlRun "./test_create trans"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_modify_local"
# function requires transaction
#rlRun "./test_modify_local conn new" $ERR_FAIL
#rlRun "./test_modify_local conn first" $ERR_FAIL
#rlRun "./test_modify_local trans new" $ERR_FAIL
rlRun "./test_modify_local trans first"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_del_local"
# adding local seuser requires transaction
# FIXME
#rlRun "./test_del_local trans first new"
#rlRun "./test_del_local trans first second"
rlRun "./test_del_local trans first first"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_exists_local"
# adding local seuser requires transaction
rlRun "./test_exists_local trans first first 1"
rlRun "./test_exists_local trans first second 0"
rlPhaseEnd
rlPhaseStartTest "semanage_seuser_count_local"
# adding local seuser requires transaction
# FIXME
#rlRun "./test_count_local trans 0"
rlRun "./test_count_local trans 1"
rlRun "./test_count_local trans 2"
rlPhaseEnd
rlPhaseStartCleanup
testfiles="$(ls -1 test_* | grep -v '\.c' | tr '\n' ' ')"
rlRun "rm -f $testfiles"
rlPhaseEnd
rlJournalPrintText
rlJournalEnd

View File

@ -0,0 +1,60 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_t *seuser_clone;
int result;
const char *str;
const char *str_clone;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
result = semanage_seuser_clone(sh, seuser, &seuser_clone);
printf("semanage_seuser_clone(%p, %p): %d\n",
(void *) seuser, (void *) seuser_clone, result);
if (result < 0) {
perror("semanage_seuser_clone");
exit(1);
}
str = semanage_seuser_get_name(seuser);
str_clone = semanage_seuser_get_name(seuser_clone);
if (strcmp(str, str_clone) != 0) {
fprintf(stderr, "Different in get_name\n");
exit(1);
}
str = semanage_seuser_get_sename(seuser);
str_clone = semanage_seuser_get_sename(seuser_clone);
if (strcmp(str, str_clone) != 0) {
fprintf(stderr, "Different in get_sename\n");
exit(1);
}
str = semanage_seuser_get_mlsrange(seuser);
str_clone = semanage_seuser_get_mlsrange(seuser_clone);
if (strcmp(str, str_clone) != 0) {
fprintf(stderr, "Different in get_mlsrange\n");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_key_t *key;
int result;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, "first");
key = test_get_key(sh, argv[2]);
result = semanage_seuser_compare(seuser, key);
printf("semanage_seuser_compare(%p, %p): %d\n",
(void *) seuser, (void *) key, result);
if (argc >= 4) {
if (strcmp(argv[3], "same") == 0 && result != 0) {
fprintf(stderr, "Expected same but got different\n");
exit(1);
}
else if (strcmp(argv[3], "different") == 0 && result == 0) {
fprintf(stderr, "Expected different but got same\n");
exit(1);
}
}
semanage_seuser_key_free(key);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_t *seuser2;
int result;
int first = -1;
int second = -1;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
if (strcmp(argv[2], "NULL") == 0) {
seuser = NULL;
}
else {
first = strtol(argv[2], NULL, 10);
seuser = test_get_seuser_nth(sh, first);
}
if (strcmp(argv[3], "NULL") == 0) {
seuser2 = NULL;
}
else {
second = strtol(argv[3], NULL, 10);
seuser2 = test_get_seuser_nth(sh, second);
}
result = semanage_seuser_compare2(seuser, seuser2);
printf("semanage_seuser_compare(%p, %p): %d\n",
(void *) seuser, (void *) seuser2, result);
if (first == second && result != 0) {
fprintf(stderr, "Expected same but got different\n");
exit(1);
}
else if (first != second && result == 0) {
fprintf(stderr, "Expected different but got same\n");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
unsigned int response;
int result;
if (argc < 2)
exit(2);
sh = get_handle(argv[1]);
result = semanage_seuser_count(sh, &response);
printf("semanage_seuser_count(%p, %p): %d, response: %u\n",
(void *) sh, (void *) &response, result, response);
if (result < 0) {
perror("semanage_seuser_count");
exit(1);
}
if (argc >= 3)
check_result_int(argv[2], response);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
int result;
unsigned int response;
int num;
if (argc < 2)
exit(2);
sh = get_handle(argv[1]);
num = strtol(argv[2], NULL, 10);
for (int i = 0; i < num; i++) {
seuser = test_get_seuser_nth(sh, i);
test_add_local_seuser(sh, seuser);
}
result = semanage_seuser_count_local(sh, &response);
printf("semanage_seuser_count_local(%p, %p): %d, response: %d\n",
(void *) sh, (void *) &response, result, response);
if (result < 0) {
perror("semanage_seuser_count_local");
exit(1);
}
if (argc >= 3)
check_result_int(argv[2], response);
test_del_local_seuser(sh, seuser);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
int result;
const char *str;
if (argc < 2)
exit(2);
sh = get_handle(argv[1]);
result = semanage_seuser_create(sh, &seuser);
printf("semanage_seuser_create(%p, %p): %d\n",
(void *) sh, (void *) seuser, result);
if (result < 0) {
perror("semanage_seuser_create");
exit(1);
}
str = semanage_seuser_get_name(seuser);
if (str != NULL) {
fprintf(stderr, "Expected name == NULL, got %s\n", str);
exit(1);
}
str = semanage_seuser_get_sename(seuser);
if (str != NULL) {
fprintf(stderr, "Expected sename == NULL, got %s\n", str);
exit(1);
}
str = semanage_seuser_get_mlsrange(seuser);
if (str != NULL) {
fprintf(stderr, "Expected mlsrange == NULL, got %s\n", str);
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_t *seuser_del;
semanage_seuser_key_t *key;
semanage_seuser_t **records;
int result;
unsigned int count;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
test_add_local_seuser(sh, seuser);
seuser_del = test_get_seuser(sh, argv[3]);
result = semanage_seuser_key_extract(sh, seuser_del, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser_del, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(2);
}
result = semanage_seuser_del_local(sh, key);
printf("semanage_seuser_del_local(%p, %p): %d\n",
(void *) seuser, (void *) key, result);
if (result < 0) {
perror("semanage_seuser_del_local");
exit(1);
}
result = semanage_seuser_list_local(sh, &records, &count);
printf("semanage_seuser_list_local(%p, %p, %p): %d\n",
(void *) sh, (void *) &records, (void *) &count, result);
if (result < 0) {
perror("semanage_seuser_list_local");
exit(2);
}
if (count != 0) {
fprintf(stderr, "Number of local seusers is not 0!\n");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_key_t *key;
int result;
int response;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
key = test_get_key(sh, argv[2]);
result = semanage_seuser_exists(sh, key, &response);
printf("semanage_seuser_exists(%p, %p, %p): %d, response: %d\n",
(void *) sh, (void *) key, (void *) &response, result, response);
if (result < 0) {
perror("semanage_seuser_exists");
exit(1);
}
if (argc >= 4)
check_result_int(argv[3], response);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,59 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_t *seuser_exists;
semanage_seuser_key_t *key;
int result;
int response;
int exp;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
seuser_exists = test_get_seuser(sh, argv[3]);
test_add_local_seuser(sh, seuser);
result = semanage_seuser_key_extract(sh, seuser_exists, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser_exists, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(2);
}
result = semanage_seuser_exists_local(sh, key, &response);
printf("semanage_seuser_exists_local(%p, %p, %p): %d\n",
(void *) sh, (void *) key, (void *) &response, result);
if (result < 0) {
perror("semanage_seuser_exists_local");
exit(1);
}
if (argc >= 5) {
exp = strtol(argv[4], NULL, 10);
if (response != exp) {
fprintf(stderr, "Expected %d but got %d\n", exp, response);
exit(1);
}
}
test_del_local_seuser(sh, seuser);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
const char *name = semanage_seuser_get_mlsrange(seuser);
printf("semanage_seuser_get_mlsrange(%p): %s\n",
(void *) seuser, name);
if (strcmp_null(argv[3], name) != 0) {
fprintf(stderr, "Expected %s but got %s\n", argv[2], name);
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
const char *name = semanage_seuser_get_name(seuser);
printf("semanage_seuser_get_name(%p): %s\n",
(void *) seuser, name);
if (strcmp_null(argv[3], name) != 0) {
fprintf(stderr, "Expected %s but got %s\n", argv[2], name);
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,32 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
if (argc < 4)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
const char *name = semanage_seuser_get_sename(seuser);
printf("semanage_seuser_get_sename(%p): %s\n",
(void *) seuser, name);
if (strcmp_null(argv[3], name) != 0) {
fprintf(stderr, "Expected %s but got %s\n", argv[2], name);
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,49 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int counter = 0;
int handler(const semanage_seuser_t *record, void *varg) {
char **args = (char **) varg;
const char *name = semanage_seuser_get_name(record);
if (strcmp(name, args[2 + counter++]) != 0)
return -1;
return 0;
}
int main (int argc, char **argv) {
semanage_handle_t *sh;
int result;
if (argc < 2)
exit(2);
sh = get_handle(argv[1]);
char **param = NULL;
if (argc >= 3) {
param = argv;
}
result = semanage_seuser_iterate(sh, &handler, (void *) param);
printf("semanage_seuser_iterate(%p, %p, %p): %d\n",
(void *) sh, (void *) &handler, (void *) param, result);
if (result < 0) {
perror("semanage_seuser_iterate");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,39 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_key_t *key;
const char *name;
int result;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
if (strcmp(argv[2], "NULL") == 0)
name = NULL;
else
name = argv[2];
result = semanage_seuser_key_create(sh, name, &key);
printf("semanage_seuser_key_create(%p, %s, %p): %d\n",
(void *) sh, name, (void *) &key, result);
if (result < 0 || key == NULL) {
perror("semanage_seuser_key_create");
exit(1);
}
semanage_seuser_key_free(key);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,45 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_key_t *key;
int result;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
result = semanage_seuser_key_extract(sh, seuser, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(1);
}
result = semanage_seuser_compare(seuser, key);
printf("semanage_seuser_compare(%p, %p): %d\n",
(void *) seuser, (void *) key, result);
if (result != 0) {
perror("semanage_seuser_compare");
exit(1);
}
semanage_seuser_key_free(key);
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t **records;
unsigned int count;
int result;
if (argc < 2)
exit(2);
sh = get_handle(argv[1]);
result = semanage_seuser_list(sh, &records, &count);
printf("semanage_seuser_list(%p, %p, %p): %d",
(void *) sh, (void *) &records, (void *) &count, result);
if (result < 0) {
perror("semanage_seuser_list");
exit(1);
}
printf(", count: %u, records: ", count);
const char *name;
for (unsigned int i = 0; i < count; i++) {
name = semanage_seuser_get_name(records[i]);
printf("%p (%s), ", (void *) records[i], name);
}
printf("\n");
if (argc >= 3) {
unsigned int exp_count = strtoul(argv[2], NULL, 10);
if (count != exp_count) {
printf("Expected %u but got %u\n", exp_count, count);
exit(1);
}
const char *name;
for (unsigned int i = 0; i < count; i++) {
name = semanage_seuser_get_name(records[i]);
if (strcmp(name, argv[3 + i]) != 0) {
printf("Expected %s but got %s\n", name, argv[3 + i]);
exit(1);
}
}
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *seuser;
semanage_seuser_key_t *key;
semanage_seuser_t **records;
int result;
unsigned int count;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
seuser = test_get_seuser(sh, argv[2]);
result = semanage_seuser_key_extract(sh, seuser, &key);
printf("semanage_seuser_key_extract(%p, %p, %p): %d\n",
(void *) sh, (void *) seuser, (void *) &key, result);
if (result < 0) {
perror("semanage_seuser_key_extract");
exit(2);
}
result = semanage_seuser_modify_local(sh, key, seuser);
printf("semanage_seuser_modify_local(%p, %p, %p): %d\n",
(void *) seuser, (void *) key, (void *) seuser, result);
if (result < 0) {
perror("semanage_seuser_modify_local");
exit(1);
}
result = semanage_seuser_list_local(sh, &records, &count);
printf("semanage_seuser_list_local(%p, %p, %p): %d\n",
(void *) sh, (void *) &records, (void *) &count, result);
if (result < 0) {
perror("semanage_seuser_list_local");
exit(2);
}
if (count != 1) {
fprintf(stderr, "Number of local seusers is %u, expected 1!\n", count);
exit(1);
}
if (semanage_seuser_compare(records[0], key) != 0) {
fprintf(stderr, "Local seuser is different!\n");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,50 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_key_t *key;
semanage_seuser_t *response;
int result;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
result = semanage_seuser_key_create(sh, argv[2], &key);
printf("semanage_seuser_key_create(%p, %s, %p): %d\n",
(void *) sh, argv[2], (void *) &key, result);
if (result < 0 || key == NULL) {
perror("semanage_seuser_key_create");
exit(2);
}
result = semanage_seuser_query(sh, key, &response);
printf("semanage_seuser_query(%p, %p, %p): %d, response: %p\n",
(void *) sh, (void *) key, (void *) &response, result, (void *) response);
if (result < 0) {
perror("semanage_seuser_query");
exit(1);
}
const char *name = semanage_seuser_get_name(response);
printf("semanage_seuser_get_name(%p): %s\n",
(void *) response, name);
if (strcmp(argv[2], name) != 0) {
perror("semanage_seuser_get_name");
exit(2);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *user;
int result;
const char *mlsrange;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
user = test_get_seuser(sh, "first");
if (strcmp(argv[2], "NULL") == 0)
mlsrange = NULL;
else
mlsrange = argv[2];
const char *old_mlsrange = semanage_seuser_get_mlsrange(user);
printf("semanage_seuser_get_mlsrange(%p): %s\n",
(void *) user, old_mlsrange);
if (old_mlsrange == NULL) {
perror("semanage_seuser_get_mlsrange");
exit(2);
}
if (strcmp(old_mlsrange, mlsrange) == 0) {
printf("New mlsrange is the same\n");
exit(2);
}
result = semanage_seuser_set_mlsrange(sh, user, mlsrange);
printf("semanage_seuser_set_mlsrange(%p, %p, %s): %d\n",
(void *) sh, (void *) user, mlsrange, result);
if (result < 0) {
perror("semanage_seuser_set_mlsrange");
exit(1);
}
const char *new_mlsrange = semanage_seuser_get_mlsrange(user);
printf("semanage_seuser_get_mlsrange(%p): %s\n",
(void *) user, new_mlsrange);
if (strcmp(new_mlsrange, mlsrange) != 0) {
perror("semanage_seuser_get_mlsrange");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *user;
int result;
const char *name;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
user = test_get_seuser(sh, "first");
if (strcmp(argv[2], "NULL") == 0)
name = NULL;
else
name = argv[2];
const char *old_name = semanage_seuser_get_name(user);
printf("semanage_seuser_get_name(%p): %s\n",
(void *) user, old_name);
if (old_name == NULL) {
perror("semanage_seuser_get_name");
exit(2);
}
if (strcmp(old_name, name) == 0) {
printf("New name is the same\n");
exit(2);
}
result = semanage_seuser_set_name(sh, user, name);
printf("semanage_seuser_set_name(%p, %p, %s): %d\n",
(void *) sh, (void *) user, name, result);
if (result < 0) {
perror("semanage_seuser_set_name");
exit(1);
}
const char *new_name = semanage_seuser_get_name(user);
printf("semanage_seuser_get_name(%p): %s\n",
(void *) user, new_name);
if (strcmp(new_name, name) != 0) {
perror("semanage_seuser_get_name");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semanage/semanage.h>
#include "functions.c"
int main (int argc, char **argv) {
semanage_handle_t *sh;
semanage_seuser_t *user;
int result;
const char *name;
if (argc < 3)
exit(2);
sh = get_handle(argv[1]);
user = test_get_seuser(sh, "first");
if (strcmp(argv[2], "NULL") == 0)
name = NULL;
else
name = argv[2];
const char *old_name = semanage_seuser_get_sename(user);
printf("semanage_seuser_get_sename(%p): %s\n",
(void *) user, old_name);
if (old_name == NULL) {
perror("semanage_seuser_get_sename");
exit(2);
}
if (strcmp(old_name, name) == 0) {
printf("New name is the same\n");
exit(2);
}
result = semanage_seuser_set_sename(sh, user, name);
printf("semanage_seuser_set_sename(%p, %p, %s): %d\n",
(void *) sh, (void *) user, name, result);
if (result < 0) {
perror("semanage_seuser_set_sename");
exit(1);
}
const char *new_name = semanage_seuser_get_sename(user);
printf("semanage_seuser_get_sename(%p): %s\n",
(void *) user, new_name);
if (strcmp(new_name, name) != 0) {
perror("semanage_seuser_get_sename");
exit(1);
}
destroy_handle(sh, argv[1]);
exit(0);
}

View File

@ -0,0 +1,64 @@
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Makefile of /CoreOS/libsemanage/Sanity/verify-options-in-semanage-conf
# Description: Are the verify options in semanage.conf honored?
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2016 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
export TEST=/CoreOS/libsemanage/Sanity/verify-options-in-semanage-conf
export TESTVERSION=1.0
BUILT_FILES=
FILES=$(METADATA) runtest.sh Makefile PURPOSE empty.te
.PHONY: all install download clean
run: $(FILES) build
./runtest.sh
build: $(BUILT_FILES)
test -x runtest.sh || chmod a+x runtest.sh
clean:
rm -f *~ $(BUILT_FILES)
include /usr/share/rhts/lib/rhts-make.include
$(METADATA): Makefile
@echo "Owner: Milos Malik <mmalik@redhat.com>" > $(METADATA)
@echo "Name: $(TEST)" >> $(METADATA)
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
@echo "Path: $(TEST_DIR)" >> $(METADATA)
@echo "Description: Are the verify options in semanage.conf honored?" >> $(METADATA)
@echo "Type: Sanity" >> $(METADATA)
@echo "TestTime: 10m" >> $(METADATA)
@echo "RunFor: libsemanage" >> $(METADATA)
@echo "Requires: libselinux libselinux-utils libsemanage policycoreutils policycoreutils-python selinux-policy selinux-policy-devel" >> $(METADATA)
@echo "Priority: Normal" >> $(METADATA)
@echo "License: GPLv2" >> $(METADATA)
@echo "Confidential: no" >> $(METADATA)
@echo "Destructive: no" >> $(METADATA)
@echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA)
rhts-lint $(METADATA)

View File

@ -0,0 +1,9 @@
PURPOSE of /CoreOS/libsemanage/Sanity/verify-options-in-semanage-conf
Author: Milos Malik <mmalik@redhat.com>
Are the verify options in semanage.conf honored?
Tested options: verify kernel, verify module, verify linked
Tested tools: semodule, semanage
Positive and negative cases are tested.
Original information found at http://selinuxproject.org/page/PolicyValidate

View File

@ -0,0 +1,2 @@
policy_module(empty,1.0)

View File

@ -0,0 +1,142 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# runtest.sh of /CoreOS/libsemanage/Sanity/verify-options-in-semanage-conf
# Description: Are the verify options in semanage.conf honored?
# Author: Milos Malik <mmalik@redhat.com>
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# Copyright (c) 2016 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing
# to use, modify, copy, or redistribute it subject to the terms
# and conditions of the GNU General Public License version 2.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Include Beaker environment
. /usr/bin/rhts-environment.sh || exit 1
. /usr/share/beakerlib/beakerlib.sh || exit 1
PACKAGE="libsemanage"
MODULE_NAME="empty"
SEMANAGE_CONF="/etc/selinux/semanage.conf"
rlJournalStart
rlPhaseStartSetup
rlAssertRpm ${PACKAGE}
rlAssertRpm policycoreutils
rlAssertRpm selinux-policy
rlFileBackup ${SEMANAGE_CONF}
rlRun "rpm -qf /usr/sbin/semanage"
rlRun "grep -v -e '^#' -e '^$' ${SEMANAGE_CONF}"
OUTPUT_FILE=`mktemp`
rlRun "setenforce 1"
rlRun "sestatus"
rlRun "ls -l ${MODULE_NAME}.te"
rlRun "make -f /usr/share/selinux/devel/Makefile"
rlRun "ls -l ${MODULE_NAME}.pp"
rlPhaseEnd
rlLog "positive cases follow"
# TODO: /bin/true could be replaced a script, which prints the supplied arguments into a file for further inspection
rlPhaseStartTest "verify kernel"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify kernel]\npath = /bin/true\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}"
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}"
rlPhaseEnd
rlPhaseStartTest "verify module"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify module]\npath = /bin/true\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}"
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}"
rlPhaseEnd
if rlIsRHEL '<7.3' ; then # because "[verify linked]" was dropped
rlPhaseStartTest "verify linked"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify linked]\npath = /bin/true\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}"
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertNotGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}"
rlPhaseEnd
fi
rlLog "negative cases follow"
# TODO: /bin/false could be replaced a script, which prints the supplied arguments into a file for further inspection
rlPhaseStartTest "verify kernel"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify kernel]\npath = /bin/false\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}" 1
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}" 1
rlPhaseEnd
rlPhaseStartTest "verify module"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify module]\npath = /bin/false\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}" 1
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}" 1
rlPhaseEnd
if rlIsRHEL '<7.3' ; then # because "[verify linked]" was dropped
rlPhaseStartTest "verify linked"
rlRun "semodule -r ${MODULE_NAME}" 0,1
rlFileRestore
rlRun "echo -en '[verify linked]\npath = /bin/false\nargs = \$@\n[end]\n' >> ${SEMANAGE_CONF}"
rlRun "semodule -i ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "semodule.*failed" ${OUTPUT_FILE} -i
rlRun "semodule -l | grep ${MODULE_NAME}" 1
rlRun "semanage module -a ${MODULE_NAME}.pp 2>&1 | tee ${OUTPUT_FILE}"
rlAssertGrep "could not commit semanage transaction|no such file or directory" ${OUTPUT_FILE} -Ei
rlRun "semanage module -l | grep ${MODULE_NAME}" 1
rlPhaseEnd
fi
rlPhaseStartCleanup
rlRun "rm -f ${MODULE_NAME}.pp ${OUTPUT_FILE}"
rlFileRestore
rlPhaseEnd
rlJournalPrintText
rlJournalEnd