From a21e2f9484e65fe6b8cbb8e60832d7128ac074fd Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Wed, 30 Jan 2019 10:09:38 +0100 Subject: [PATCH] SELinux userspace 2.9-rc1 release candidate --- .gitignore | 7 + policycoreutils-fedora.patch | 96 +- policycoreutils.spec | 83 +- restorecond-fedora.patch | 20 +- selinux-dbus-fedora.patch | 24 +- selinux-gui-fedora.patch | 92 +- selinux-python-fedora.patch | 2363 +--------------------------------- selinux-sandbox-fedora.patch | 32 +- semodule-utils-fedora.patch | 6 +- sources | 14 +- 10 files changed, 200 insertions(+), 2537 deletions(-) diff --git a/.gitignore b/.gitignore index a4c891d..1ae8a1b 100644 --- a/.gitignore +++ b/.gitignore @@ -280,3 +280,10 @@ policycoreutils-2.0.83.tgz /policycoreutils-po.tgz /python-po.tgz /sandbox-po.tgz +/policycoreutils-2.9-rc1.tar.gz +/selinux-python-2.9-rc1.tar.gz +/selinux-gui-2.9-rc1.tar.gz +/selinux-sandbox-2.9-rc1.tar.gz +/selinux-dbus-2.9-rc1.tar.gz +/semodule-utils-2.9-rc1.tar.gz +/restorecond-2.9-rc1.tar.gz diff --git a/policycoreutils-fedora.patch b/policycoreutils-fedora.patch index b1a32a2..fc81890 100644 --- a/policycoreutils-fedora.patch +++ b/policycoreutils-fedora.patch @@ -1,20 +1,7 @@ -diff --git policycoreutils-2.8/newrole/newrole.1 policycoreutils-2.8/newrole/newrole.1 -index 0d9738a..893c42f 100644 ---- policycoreutils-2.8/newrole/newrole.1 -+++ policycoreutils-2.8/newrole/newrole.1 -@@ -44,7 +44,7 @@ specified by that range. If the - or - .B --preserve-environment - option is specified, the shell with the new SELinux context will preserve environment variables, --otherwise a new minimal enviroment is created. -+otherwise a new minimal environment is created. - .PP - Additional arguments - .I ARGS -diff --git policycoreutils-2.8/po/Makefile policycoreutils-2.8/po/Makefile +diff --git policycoreutils-2.9-rc1/po/Makefile policycoreutils-2.9-rc1/po/Makefile index 575e143..18bc1df 100644 ---- policycoreutils-2.8/po/Makefile -+++ policycoreutils-2.8/po/Makefile +--- policycoreutils-2.9-rc1/po/Makefile ++++ policycoreutils-2.9-rc1/po/Makefile @@ -3,7 +3,6 @@ # @@ -110,11 +97,11 @@ index 575e143..18bc1df 100644 refresh-po: Makefile for cat in $(POFILES); do \ -diff --git policycoreutils-2.8/po/POTFILES policycoreutils-2.8/po/POTFILES +diff --git policycoreutils-2.9-rc1/po/POTFILES policycoreutils-2.9-rc1/po/POTFILES new file mode 100644 index 0000000..12237dc --- /dev/null -+++ policycoreutils-2.8/po/POTFILES ++++ policycoreutils-2.9-rc1/po/POTFILES @@ -0,0 +1,9 @@ +../run_init/open_init_pty.c +../run_init/run_init.c @@ -125,10 +112,10 @@ index 0000000..12237dc +../semodule/semodule.c +../setfiles/setfiles.c +../secon/secon.c -diff --git policycoreutils-2.8/scripts/fixfiles policycoreutils-2.8/scripts/fixfiles +diff --git policycoreutils-2.9-rc1/scripts/fixfiles policycoreutils-2.9-rc1/scripts/fixfiles index b277958..53d28c7 100755 ---- policycoreutils-2.8/scripts/fixfiles -+++ policycoreutils-2.8/scripts/fixfiles +--- policycoreutils-2.9-rc1/scripts/fixfiles ++++ policycoreutils-2.9-rc1/scripts/fixfiles @@ -108,6 +108,7 @@ exclude_dirs_from_relabelling() { fullFlag=0 BOOTTIME="" @@ -137,10 +124,10 @@ index b277958..53d28c7 100755 FORCEFLAG="" RPMFILES="" PREFC="" -diff --git policycoreutils-2.8/setfiles/setfiles.8 policycoreutils-2.8/setfiles/setfiles.8 +diff --git policycoreutils-2.9-rc1/setfiles/setfiles.8 policycoreutils-2.9-rc1/setfiles/setfiles.8 index ccaaf4d..a8a76c8 100644 ---- policycoreutils-2.8/setfiles/setfiles.8 -+++ policycoreutils-2.8/setfiles/setfiles.8 +--- policycoreutils-2.9-rc1/setfiles/setfiles.8 ++++ policycoreutils-2.9-rc1/setfiles/setfiles.8 @@ -57,7 +57,7 @@ check the validity of the contexts against the specified binary policy. .TP .B \-d @@ -150,64 +137,3 @@ index ccaaf4d..a8a76c8 100644 .TP .BI \-e \ directory directory to exclude (repeat option for more than one directory). -diff --git policycoreutils-2.8/setsebool/setsebool.c policycoreutils-2.8/setsebool/setsebool.c -index 53d3566..a5157ef 100644 ---- policycoreutils-2.8/setsebool/setsebool.c -+++ policycoreutils-2.8/setsebool/setsebool.c -@@ -18,7 +18,7 @@ - #include - - int permanent = 0; --int reload = 1; -+int no_reload = 0; - int verbose = 0; - - int setbool(char **list, size_t start, size_t end); -@@ -38,11 +38,6 @@ int main(int argc, char **argv) - if (argc < 2) - usage(); - -- if (is_selinux_enabled() <= 0) { -- fputs("setsebool: SELinux is disabled.\n", stderr); -- return 1; -- } -- - while (1) { - clflag = getopt(argc, argv, "PNV"); - if (clflag == -1) -@@ -53,7 +48,7 @@ int main(int argc, char **argv) - permanent = 1; - break; - case 'N': -- reload = 0; -+ no_reload = 1; - break; - case 'V': - verbose = 1; -@@ -130,6 +125,7 @@ static int semanage_set_boolean_list(size_t boolcnt, - semanage_bool_key_t *bool_key = NULL; - int managed; - int result; -+ int enabled = is_selinux_enabled(); - - handle = semanage_handle_create(); - if (handle == NULL) { -@@ -191,7 +187,7 @@ static int semanage_set_boolean_list(size_t boolcnt, - boolean) < 0) - goto err; - -- if (semanage_bool_set_active(handle, bool_key, boolean) < 0) { -+ if (enabled && semanage_bool_set_active(handle, bool_key, boolean) < 0) { - fprintf(stderr, "Failed to change boolean %s: %m\n", - boollist[j].name); - goto err; -@@ -202,7 +198,8 @@ static int semanage_set_boolean_list(size_t boolcnt, - boolean = NULL; - } - -- semanage_set_reload(handle, reload); -+ if (no_reload) -+ semanage_set_reload(handle, 0); - if (semanage_commit(handle) < 0) - goto err; - diff --git a/policycoreutils.spec b/policycoreutils.spec index d32f3de..dc546dc 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -1,8 +1,8 @@ %global libauditver 2.1.3-4 -%global libsepolver 2.8-3 -%global libsemanagever 2.8-8 -%global libselinuxver 2.8-7 -%global sepolgenver 2.8 +%global libsepolver 2.9-0 +%global libsemanagever 2.9-0 +%global libselinuxver 2.9-0 +%global sepolgenver 2.9 %global generatorsdir %{_prefix}/lib/systemd/system-generators @@ -11,18 +11,18 @@ Summary: SELinux policy core utilities Name: policycoreutils -Version: 2.8 -Release: 17%{?dist} +Version: 2.9 +Release: 0.rc1.1%{?dist} License: GPLv2 # https://github.com/SELinuxProject/selinux/wiki/Releases -Source0: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/policycoreutils-2.8.tar.gz -Source1: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/selinux-python-2.8.tar.gz -Source2: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/selinux-gui-2.8.tar.gz -Source3: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/selinux-sandbox-2.8.tar.gz -Source4: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/selinux-dbus-2.8.tar.gz -Source5: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/semodule-utils-2.8.tar.gz -Source6: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20180524/restorecond-2.8.tar.gz -URL: https://github.com/SELinuxProject +Source0: https://github.com/SELinuxProject/selinux/releases/download/20190125/policycoreutils-2.9-rc1.tar.gz +Source1: https://github.com/SELinuxProject/selinux/releases/download/20190125/selinux-python-2.9-rc1.tar.gz +Source2: https://github.com/SELinuxProject/selinux/releases/download/20190125/selinux-gui-2.9-rc1.tar.gz +Source3: https://github.com/SELinuxProject/selinux/releases/download/20190125/selinux-sandbox-2.9-rc1.tar.gz +Source4: https://github.com/SELinuxProject/selinux/releases/download/20190125/selinux-dbus-2.9-rc1.tar.gz +Source5: https://github.com/SELinuxProject/selinux/releases/download/20190125/semodule-utils-2.9-rc1.tar.gz +Source6: https://github.com/SELinuxProject/selinux/releases/download/20190125/restorecond-2.9-rc1.tar.gz +URL: https://github.com/SELinuxProject/selinux Source12: policycoreutils_man_ru2.tar.bz2 Source13: system-config-selinux.png Source14: sepolicy-icons.tgz @@ -37,9 +37,9 @@ Source22: gui-po.tgz Source23: sandbox-po.tgz # download https://raw.githubusercontent.com/fedora-selinux/scripts/master/selinux/make-fedora-selinux-patch.sh # run: -# HEAD https://github.com/fedora-selinux/selinux/commit/c19a6cbd95123e7f6088f6d95698800c8bc9f5ae +# HEAD https://github.com/fedora-selinux/selinux/commit/a69fe203e41c9493e13ffafa51908d17da6fa7a2 # $ for i in policycoreutils selinux-python selinux-gui selinux-sandbox selinux-dbus semodule-utils restorecond; do -# VERSION=2.8 ./make-fedora-selinux-patch.sh $i +# VERSION=2.9-rc1 ./make-fedora-selinux-patch.sh $i # done Patch: policycoreutils-fedora.patch Patch1: selinux-python-fedora.patch @@ -90,8 +90,8 @@ to switch roles. %setup -q -T -D -a 6 -n selinux %patch -p0 -b .policycoreutils-fedora -cp %{SOURCE13} selinux-gui-%{version}/ -tar -xvf %{SOURCE14} -C selinux-python-%{version}/sepolicy/ +cp %{SOURCE13} selinux-gui-%{version}-rc1/ +tar -xvf %{SOURCE14} -C selinux-python-%{version}-rc1/sepolicy/ %patch1 -p0 -b .selinux-python %patch2 -p0 -b .selinux-gui %patch3 -p0 -b .selinux-sandbox @@ -101,22 +101,22 @@ tar -xvf %{SOURCE14} -C selinux-python-%{version}/sepolicy/ # Since patches containing translation changes were too big, translations were moved to separate tarballs # For more information see README.translations -tar -x -f %{SOURCE20} -C policycoreutils-%{version} -z -tar -x -f %{SOURCE21} -C selinux-python-%{version} -z -tar -x -f %{SOURCE22} -C selinux-gui-%{version} -z -tar -x -f %{SOURCE23} -C selinux-sandbox-%{version} -z +tar -x -f %{SOURCE20} -C policycoreutils-%{version}-rc1 -z +tar -x -f %{SOURCE21} -C selinux-python-%{version}-rc1 -z +tar -x -f %{SOURCE22} -C selinux-gui-%{version}-rc1 -z +tar -x -f %{SOURCE23} -C selinux-sandbox-%{version}-rc1 -z %build %set_build_flags export PYTHON=%{__python3} -make -C policycoreutils-%{version} LSPP_PRIV=y SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" SEMODULE_PATH="/usr/sbin" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C selinux-python-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C selinux-gui-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C selinux-sandbox-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C selinux-dbus-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C semodule-utils-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all -make -C restorecond-%{version} SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C policycoreutils-%{version}-rc1 LSPP_PRIV=y SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" SEMODULE_PATH="/usr/sbin" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C selinux-python-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C selinux-gui-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C selinux-sandbox-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C selinux-dbus-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C semodule-utils-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all +make -C restorecond-%{version}-rc1 SBINDIR="%{_sbindir}" LSPP_PRIV=y LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" all %install mkdir -p %{buildroot}%{_bindir} @@ -126,20 +126,20 @@ mkdir -p %{buildroot}%{_mandir}/man5 mkdir -p %{buildroot}%{_mandir}/man8 %{__mkdir} -p %{buildroot}/%{_usr}/share/doc/%{name}/ -make -C policycoreutils-%{version} LSPP_PRIV=y DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" SEMODULE_PATH="/usr/sbin" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C policycoreutils-%{version}-rc1 LSPP_PRIV=y DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" SEMODULE_PATH="/usr/sbin" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C selinux-python-%{version} PYTHON=%{__python2} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C selinux-python-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C selinux-python-%{version}-rc1 PYTHON=%{__python2} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C selinux-python-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C selinux-gui-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C selinux-gui-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C selinux-sandbox-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C selinux-sandbox-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C selinux-dbus-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C selinux-dbus-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C semodule-utils-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C semodule-utils-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install -make -C restorecond-%{version} PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install +make -C restorecond-%{version}-rc1 PYTHON=%{__python3} DESTDIR="%{buildroot}" SBINDIR="%{_sbindir}" LIBDIR="%{_libdir}" LIBSEPOLA="%{_libdir}/libsepol.a" install # Systemd @@ -426,8 +426,6 @@ system-config-selinux is a utility for managing the SELinux environment %{_datadir}/system-config-selinux/system-config-selinux.png %{_datadir}/system-config-selinux/*Page.py %{_datadir}/system-config-selinux/__pycache__/*Page.* -%{_datadir}/system-config-selinux/html_util.py -%{_datadir}/system-config-selinux/__pycache__/html_util.* %{_datadir}/system-config-selinux/polgengui.py %{_datadir}/system-config-selinux/__pycache__/polgengui.* %{_datadir}/system-config-selinux/system-config-selinux.py @@ -493,7 +491,7 @@ system-config-selinux is a utility for managing the SELinux environment %dir %{_datadir}/bash-completion %{_datadir}/bash-completion/completions/setsebool %{!?_licensedir:%global license %%doc} -%license policycoreutils-%{version}/COPYING +%license policycoreutils-%{version}-rc1/COPYING %doc %{_usr}/share/doc/%{name} %package restorecond @@ -513,7 +511,7 @@ The policycoreutils-restorecond package contains the restorecond service. %{_mandir}/man8/restorecond.8* %{_mandir}/ru/man8/restorecond.8* %{!?_licensedir:%global license %%doc} -%license policycoreutils-%{version}/COPYING +%license policycoreutils-%{version}-rc1/COPYING %post %systemd_post selinux-autorelabel-mark.service @@ -531,6 +529,9 @@ The policycoreutils-restorecond package contains the restorecond service. %systemd_postun_with_restart restorecond.service %changelog +* Fri Jan 25 2019 Petr Lautrbach - 2.9-0.rc1.1 +- SELinux userspace 2.9-rc1 release candidate + * Fri Jan 25 2019 Petr Lautrbach - 2.8-17 - python2-policycoreutils requires python2-ipaddress (#1669230) diff --git a/restorecond-fedora.patch b/restorecond-fedora.patch index 3e28d8e..6f6efd0 100644 --- a/restorecond-fedora.patch +++ b/restorecond-fedora.patch @@ -1,7 +1,7 @@ -diff --git restorecond-2.8/Makefile restorecond-2.8/Makefile -index 25be18d..26eb411 100644 ---- restorecond-2.8/Makefile -+++ restorecond-2.8/Makefile +diff --git restorecond-2.9-rc1/Makefile restorecond-2.9-rc1/Makefile +index 8a0ada1..6155ca4 100644 +--- restorecond-2.9-rc1/Makefile ++++ restorecond-2.9-rc1/Makefile @@ -50,7 +50,7 @@ install: all -mkdir -p $(DESTDIR)$(AUTOSTARTDIR) install -m 644 restorecond.desktop $(DESTDIR)$(AUTOSTARTDIR)/restorecond.desktop @@ -11,15 +11,3 @@ index 25be18d..26eb411 100644 -mkdir -p $(DESTDIR)$(SYSTEMDDIR)/system install -m 644 restorecond.service $(DESTDIR)$(SYSTEMDDIR)/system/ relabel: install -diff --git restorecond-2.8/restorecond.c restorecond-2.8/restorecond.c -index 6fbbd35..e1d26cb 100644 ---- restorecond-2.8/restorecond.c -+++ restorecond-2.8/restorecond.c -@@ -105,6 +105,7 @@ static int write_pid_file(void) - } - if (write(pidfd, val, (unsigned int)len) != len) { - syslog(LOG_ERR, "Unable to write to pidfile (%s)", strerror(errno)); -+ close(pidfd); - return 1; - } - close(pidfd); diff --git a/selinux-dbus-fedora.patch b/selinux-dbus-fedora.patch index 28e4cc2..cd35d03 100644 --- a/selinux-dbus-fedora.patch +++ b/selinux-dbus-fedora.patch @@ -1,25 +1,7 @@ -diff --git selinux-dbus-2.8/org.selinux.conf selinux-dbus-2.8/org.selinux.conf -index a350978..1ae079d 100644 ---- selinux-dbus-2.8/org.selinux.conf -+++ selinux-dbus-2.8/org.selinux.conf -@@ -12,12 +12,8 @@ - - -- -- -- - -- -+ - - - -diff --git selinux-dbus-2.8/org.selinux.policy selinux-dbus-2.8/org.selinux.policy +diff --git selinux-dbus-2.9-rc1/org.selinux.policy selinux-dbus-2.9-rc1/org.selinux.policy index 0126610..9772127 100644 ---- selinux-dbus-2.8/org.selinux.policy -+++ selinux-dbus-2.8/org.selinux.policy +--- selinux-dbus-2.9-rc1/org.selinux.policy ++++ selinux-dbus-2.9-rc1/org.selinux.policy @@ -70,9 +70,9 @@ auth_admin_keep diff --git a/selinux-gui-fedora.patch b/selinux-gui-fedora.patch index 9b9982f..c1175e0 100644 --- a/selinux-gui-fedora.patch +++ b/selinux-gui-fedora.patch @@ -1,8 +1,8 @@ -diff --git selinux-gui-2.8/Makefile selinux-gui-2.8/Makefile -index a72e58c..ffe8b97 100644 ---- selinux-gui-2.8/Makefile -+++ selinux-gui-2.8/Makefile -@@ -21,6 +21,7 @@ system-config-selinux.ui \ +diff --git selinux-gui-2.9-rc1/Makefile selinux-gui-2.9-rc1/Makefile +index d42348b..1959e7d 100644 +--- selinux-gui-2.9-rc1/Makefile ++++ selinux-gui-2.9-rc1/Makefile +@@ -20,6 +20,7 @@ system-config-selinux.ui \ usersPage.py all: $(TARGETS) system-config-selinux.py polgengui.py @@ -10,7 +10,7 @@ index a72e58c..ffe8b97 100644 install: all -mkdir -p $(DESTDIR)$(MANDIR)/man8 -@@ -46,6 +47,8 @@ install: all +@@ -45,6 +46,8 @@ install: all install -m 644 sepolicy_$${i}.png $(DESTDIR)$(DATADIR)/icons/hicolor/$${i}x$${i}/apps/sepolicy.png; \ done install -m 644 org.selinux.config.policy $(DESTDIR)$(DATADIR)/polkit-1/actions/ @@ -19,10 +19,10 @@ index a72e58c..ffe8b97 100644 clean: indent: -diff --git selinux-gui-2.8/booleansPage.py selinux-gui-2.8/booleansPage.py +diff --git selinux-gui-2.9-rc1/booleansPage.py selinux-gui-2.9-rc1/booleansPage.py index 7849bea..dd12b6d 100644 ---- selinux-gui-2.8/booleansPage.py -+++ selinux-gui-2.8/booleansPage.py +--- selinux-gui-2.9-rc1/booleansPage.py ++++ selinux-gui-2.9-rc1/booleansPage.py @@ -38,7 +38,7 @@ DISABLED = 2 ## ## I18N @@ -32,10 +32,10 @@ index 7849bea..dd12b6d 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/domainsPage.py selinux-gui-2.8/domainsPage.py +diff --git selinux-gui-2.9-rc1/domainsPage.py selinux-gui-2.9-rc1/domainsPage.py index bad5140..6bbe4de 100644 ---- selinux-gui-2.8/domainsPage.py -+++ selinux-gui-2.8/domainsPage.py +--- selinux-gui-2.9-rc1/domainsPage.py ++++ selinux-gui-2.9-rc1/domainsPage.py @@ -30,7 +30,7 @@ from semanagePage import * ## ## I18N @@ -45,10 +45,10 @@ index bad5140..6bbe4de 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/fcontextPage.py selinux-gui-2.8/fcontextPage.py +diff --git selinux-gui-2.9-rc1/fcontextPage.py selinux-gui-2.9-rc1/fcontextPage.py index 370bbee..e424366 100644 ---- selinux-gui-2.8/fcontextPage.py -+++ selinux-gui-2.8/fcontextPage.py +--- selinux-gui-2.9-rc1/fcontextPage.py ++++ selinux-gui-2.9-rc1/fcontextPage.py @@ -47,7 +47,7 @@ class context: ## ## I18N @@ -58,10 +58,10 @@ index 370bbee..e424366 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/loginsPage.py selinux-gui-2.8/loginsPage.py +diff --git selinux-gui-2.9-rc1/loginsPage.py selinux-gui-2.9-rc1/loginsPage.py index b67eb8b..cbfb0cc 100644 ---- selinux-gui-2.8/loginsPage.py -+++ selinux-gui-2.8/loginsPage.py +--- selinux-gui-2.9-rc1/loginsPage.py ++++ selinux-gui-2.9-rc1/loginsPage.py @@ -29,7 +29,7 @@ from semanagePage import * ## ## I18N @@ -71,10 +71,10 @@ index b67eb8b..cbfb0cc 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/modulesPage.py selinux-gui-2.8/modulesPage.py +diff --git selinux-gui-2.9-rc1/modulesPage.py selinux-gui-2.9-rc1/modulesPage.py index 34c5d9e..627ad95 100644 ---- selinux-gui-2.8/modulesPage.py -+++ selinux-gui-2.8/modulesPage.py +--- selinux-gui-2.9-rc1/modulesPage.py ++++ selinux-gui-2.9-rc1/modulesPage.py @@ -30,7 +30,7 @@ from semanagePage import * ## ## I18N @@ -84,11 +84,11 @@ index 34c5d9e..627ad95 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/po/Makefile selinux-gui-2.8/po/Makefile +diff --git selinux-gui-2.9-rc1/po/Makefile selinux-gui-2.9-rc1/po/Makefile new file mode 100644 index 0000000..a0f5439 --- /dev/null -+++ selinux-gui-2.8/po/Makefile ++++ selinux-gui-2.9-rc1/po/Makefile @@ -0,0 +1,82 @@ +# +# Makefile for the PO files (translation) catalog @@ -172,11 +172,11 @@ index 0000000..a0f5439 +.PHONY: missing depend + +relabel: -diff --git selinux-gui-2.8/po/POTFILES selinux-gui-2.8/po/POTFILES +diff --git selinux-gui-2.9-rc1/po/POTFILES selinux-gui-2.9-rc1/po/POTFILES new file mode 100644 index 0000000..1795c5c --- /dev/null -+++ selinux-gui-2.8/po/POTFILES ++++ selinux-gui-2.9-rc1/po/POTFILES @@ -0,0 +1,17 @@ +../booleansPage.py +../domainsPage.py @@ -195,10 +195,10 @@ index 0000000..1795c5c +../system-config-selinux.py +../system-config-selinux.ui +../usersPage.py -diff --git selinux-gui-2.8/polgen.ui selinux-gui-2.8/polgen.ui +diff --git selinux-gui-2.9-rc1/polgen.ui selinux-gui-2.9-rc1/polgen.ui index aa4c70a..6a8c067 100644 ---- selinux-gui-2.8/polgen.ui -+++ selinux-gui-2.8/polgen.ui +--- selinux-gui-2.9-rc1/polgen.ui ++++ selinux-gui-2.9-rc1/polgen.ui @@ -1975,7 +1975,7 @@ Tab True @@ -226,10 +226,10 @@ index aa4c70a..6a8c067 100644 True -diff --git selinux-gui-2.8/polgengui.py selinux-gui-2.8/polgengui.py +diff --git selinux-gui-2.9-rc1/polgengui.py selinux-gui-2.9-rc1/polgengui.py index 1601dbe..7e0d9d0 100644 ---- selinux-gui-2.8/polgengui.py -+++ selinux-gui-2.8/polgengui.py +--- selinux-gui-2.9-rc1/polgengui.py ++++ selinux-gui-2.9-rc1/polgengui.py @@ -63,7 +63,7 @@ def get_all_modules(): ## ## I18N @@ -239,10 +239,10 @@ index 1601dbe..7e0d9d0 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/portsPage.py selinux-gui-2.8/portsPage.py +diff --git selinux-gui-2.9-rc1/portsPage.py selinux-gui-2.9-rc1/portsPage.py index 30f5838..a537ecc 100644 ---- selinux-gui-2.8/portsPage.py -+++ selinux-gui-2.8/portsPage.py +--- selinux-gui-2.9-rc1/portsPage.py ++++ selinux-gui-2.9-rc1/portsPage.py @@ -35,7 +35,7 @@ from semanagePage import * ## ## I18N @@ -252,10 +252,10 @@ index 30f5838..a537ecc 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/semanagePage.py selinux-gui-2.8/semanagePage.py +diff --git selinux-gui-2.9-rc1/semanagePage.py selinux-gui-2.9-rc1/semanagePage.py index 4127804..5361d69 100644 ---- selinux-gui-2.8/semanagePage.py -+++ selinux-gui-2.8/semanagePage.py +--- selinux-gui-2.9-rc1/semanagePage.py ++++ selinux-gui-2.9-rc1/semanagePage.py @@ -22,7 +22,7 @@ from gi.repository import Gdk, Gtk ## ## I18N @@ -265,10 +265,10 @@ index 4127804..5361d69 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/statusPage.py selinux-gui-2.8/statusPage.py +diff --git selinux-gui-2.9-rc1/statusPage.py selinux-gui-2.9-rc1/statusPage.py index 766854b..a8f079b 100644 ---- selinux-gui-2.8/statusPage.py -+++ selinux-gui-2.8/statusPage.py +--- selinux-gui-2.9-rc1/statusPage.py ++++ selinux-gui-2.9-rc1/statusPage.py @@ -35,7 +35,7 @@ RELABELFILE = "/.autorelabel" ## ## I18N @@ -278,10 +278,10 @@ index 766854b..a8f079b 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/system-config-selinux.py selinux-gui-2.8/system-config-selinux.py +diff --git selinux-gui-2.9-rc1/system-config-selinux.py selinux-gui-2.9-rc1/system-config-selinux.py index ce7c74b..a81e9dd 100644 ---- selinux-gui-2.8/system-config-selinux.py -+++ selinux-gui-2.8/system-config-selinux.py +--- selinux-gui-2.9-rc1/system-config-selinux.py ++++ selinux-gui-2.9-rc1/system-config-selinux.py @@ -45,7 +45,7 @@ import selinux ## ## I18N @@ -291,10 +291,10 @@ index ce7c74b..a81e9dd 100644 try: import gettext kwargs = {} -diff --git selinux-gui-2.8/usersPage.py selinux-gui-2.8/usersPage.py +diff --git selinux-gui-2.9-rc1/usersPage.py selinux-gui-2.9-rc1/usersPage.py index 26794ed..d15d4c5 100644 ---- selinux-gui-2.8/usersPage.py -+++ selinux-gui-2.8/usersPage.py +--- selinux-gui-2.9-rc1/usersPage.py ++++ selinux-gui-2.9-rc1/usersPage.py @@ -29,7 +29,7 @@ from semanagePage import * ## ## I18N diff --git a/selinux-python-fedora.patch b/selinux-python-fedora.patch index 2abff87..71a2bfe 100644 --- a/selinux-python-fedora.patch +++ b/selinux-python-fedora.patch @@ -1,351 +1,18 @@ -diff --git selinux-python-2.8/Makefile selinux-python-2.8/Makefile -index 80bc124..891bdee 100644 ---- selinux-python-2.8/Makefile -+++ selinux-python-2.8/Makefile +diff --git selinux-python-2.9-rc1/Makefile selinux-python-2.9-rc1/Makefile +index 9b66d52..00312db 100644 +--- selinux-python-2.9-rc1/Makefile ++++ selinux-python-2.9-rc1/Makefile @@ -1,4 +1,4 @@ -SUBDIRS = sepolicy audit2allow semanage sepolgen chcat +SUBDIRS = sepolicy audit2allow semanage sepolgen chcat po - all install relabel clean indent: + all install relabel clean indent test: @for subdir in $(SUBDIRS); do \ -diff --git selinux-python-2.8/audit2allow/.gitignore selinux-python-2.8/audit2allow/.gitignore -index 3816d2e..2cd46af 100644 ---- selinux-python-2.8/audit2allow/.gitignore -+++ selinux-python-2.8/audit2allow/.gitignore -@@ -1 +1,2 @@ - sepolgen-ifgen-attr-helper -+test_dummy_policy -diff --git selinux-python-2.8/audit2allow/Makefile selinux-python-2.8/audit2allow/Makefile -index 513bb2b..06fc3b6 100644 ---- selinux-python-2.8/audit2allow/Makefile -+++ selinux-python-2.8/audit2allow/Makefile -@@ -1,4 +1,5 @@ - PYTHON ?= python -+SECILC ?= secilc - - # Installation directories. - PREFIX ?= /usr -@@ -22,9 +23,12 @@ sepolgen-ifgen-attr-helper: sepolgen-ifgen-attr-helper.o $(LIBSEPOLA) - audit2why: - ln -sf audit2allow audit2why - --test: all -+test: all test_dummy_policy - @$(PYTHON) test_audit2allow.py -v - -+test_dummy_policy: test_dummy_policy.cil -+ $(SECILC) -o $@ -f /dev/null $< -+ - install: all - -mkdir -p $(DESTDIR)$(BINDIR) - install -m 755 audit2allow $(DESTDIR)$(BINDIR) -@@ -36,7 +40,7 @@ install: all - install -m 644 audit2why.1 $(DESTDIR)$(MANDIR)/man1/ - - clean: -- rm -f *~ *.o sepolgen-ifgen-attr-helper -+ rm -f *~ *.o sepolgen-ifgen-attr-helper test_dummy_policy - - indent: - ../../scripts/Lindent $(wildcard *.[ch]) -diff --git selinux-python-2.8/audit2allow/audit2allow selinux-python-2.8/audit2allow/audit2allow -index 37ab23a..18fe0a5 100644 ---- selinux-python-2.8/audit2allow/audit2allow -+++ selinux-python-2.8/audit2allow/audit2allow -@@ -86,6 +86,8 @@ class AuditToPolicy: - dest="type") - parser.add_option("--perm-map", dest="perm_map", help="file name of perm map") - parser.add_option("--interface-info", dest="interface_info", help="file name of interface information") -+ parser.add_option("-x", "--xperms", action="store_true", dest="xperms", -+ default=False, help="generate extended permission rules") - parser.add_option("--debug", dest="debug", action="store_true", default=False, - help="leave generated modules for -M") - parser.add_option("-w", "--why", dest="audit2why", action="store_true", default=(os.path.basename(sys.argv[0]) == "audit2why"), -@@ -240,7 +242,10 @@ class AuditToPolicy: - - def __output_audit2why(self): - import selinux -- import sepolicy -+ try: -+ import sepolicy -+ except (ImportError, ValueError): -+ sepolicy = None - for i in self.__parser.avc_msgs: - rc = i.type - data = i.data -@@ -260,11 +265,13 @@ class AuditToPolicy: - if len(data) > 1: - print("\tOne of the following booleans was set incorrectly.") - for b in data: -- print("\tDescription:\n\t%s\n" % sepolicy.boolean_desc(b[0])) -+ if sepolicy is not None: -+ print("\tDescription:\n\t%s\n" % sepolicy.boolean_desc(b[0])) - print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (b[0], b[1])) - else: - print("\tThe boolean %s was set incorrectly. " % (data[0][0])) -- print("\tDescription:\n\t%s\n" % sepolicy.boolean_desc(data[0][0])) -+ if sepolicy is not None: -+ print("\tDescription:\n\t%s\n" % sepolicy.boolean_desc(data[0][0])) - print("\tAllow access by executing:\n\t# setsebool -P %s %d" % (data[0][0], data[0][1])) - continue - -@@ -314,6 +321,10 @@ class AuditToPolicy: - ifs, perm_maps = self.__load_interface_info() - g.set_gen_refpol(ifs, perm_maps) - -+ # Extended permissions -+ if self.__options.xperms: -+ g.set_gen_xperms(True) -+ - # Explanation - if self.__options.verbose: - g.set_gen_explain(policygen.SHORT_EXPLANATION) -diff --git selinux-python-2.8/audit2allow/audit2allow.1 selinux-python-2.8/audit2allow/audit2allow.1 -index 21d286b..c61067b 100644 ---- selinux-python-2.8/audit2allow/audit2allow.1 -+++ selinux-python-2.8/audit2allow/audit2allow.1 -@@ -85,6 +85,9 @@ This is the default behavior. - Generate reference policy using installed macros. - This attempts to match denials against interfaces and may be inaccurate. - .TP -+.B "\-x" | "\-\-xperms" -+Generate extended permission access vector rules -+.TP - .B "\-w" | "\-\-why" - Translates SELinux audit messages into a description of why the access was denied - -diff --git selinux-python-2.8/audit2allow/sepolgen-ifgen selinux-python-2.8/audit2allow/sepolgen-ifgen -index acf9638..c482f22 100644 ---- selinux-python-2.8/audit2allow/sepolgen-ifgen -+++ selinux-python-2.8/audit2allow/sepolgen-ifgen -@@ -56,6 +56,8 @@ def parse_options(): - help="print debuging output") - parser.add_option("-d", "--debug", action="store_true", default=False, - help="extra debugging output") -+ parser.add_option("--attr-helper", default=ATTR_HELPER, -+ help="path to sepolgen-ifgen-attr-helper") - parser.add_option("--no_attrs", action="store_true", default=False, - help="do not retrieve attribute access from kernel policy") - options, args = parser.parse_args() -@@ -77,7 +79,7 @@ def get_policy(): - return None - - --def get_attrs(policy_path): -+def get_attrs(policy_path, attr_helper): - try: - if not policy_path: - policy_path = get_policy() -@@ -93,10 +95,10 @@ def get_attrs(policy_path): - return None - - fd = open("/dev/null", "w") -- ret = subprocess.Popen([ATTR_HELPER, policy_path, outfile.name], stdout=fd).wait() -+ ret = subprocess.Popen([attr_helper, policy_path, outfile.name], stdout=fd).wait() - fd.close() - if ret != 0: -- sys.stderr.write("could not run attribute helper") -+ sys.stderr.write("could not run attribute helper\n") - return None - - attrs = interfaces.AttributeSet() -@@ -127,7 +129,7 @@ def main(): - # Get the attibutes from the binary - attrs = None - if not options.no_attrs: -- attrs = get_attrs(options.policy_path) -+ attrs = get_attrs(options.policy_path, options.attr_helper) - if attrs is None: - return 1 - -@@ -135,8 +137,7 @@ def main(): - try: - headers = refparser.parse_headers(options.headers, output=log, debug=options.debug) - except ValueError as e: -- print("error parsing headers") -- print(str(e)) -+ sys.stderr.write("error parsing headers: %s\n" % e) - return 1 - - if_set = interfaces.InterfaceSet(output=log) -diff --git selinux-python-2.8/audit2allow/test.log selinux-python-2.8/audit2allow/test.log -index 05249dc..718aca7 100644 ---- selinux-python-2.8/audit2allow/test.log -+++ selinux-python-2.8/audit2allow/test.log -@@ -34,3 +34,4 @@ node=mary.example.com type=AVC msg=audit(1166023021.373:910): avc: denied { re - node=lilly.example.com type=AVC_PATH msg=audit(1164783469.561:109): path="/linuxtest/LVT/lvt/log.current" - node=lilly.example.com type=SYSCALL msg=audit(1164783469.561:109): arch=14 syscall=11 success=yes exit=0 a0=10120520 a1=10120a78 a2=10120970 a3=118 items=0 ppid=8310 pid=8311 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="smbd" exe="/usr/sbin/smbd" subj=root:system_r:smbd_t:s0 key=(null) - node=lilly.example.com type=AVC msg=audit(1164783469.561:109): avc: denied { append } for pid=8311 comm="smbd" name="log.current" dev=dm-0 ino=130930 scontext=root:system_r:smbd_t:s0 tcontext=root:object_r:default_t:s0 tclass=dir -+node=lilly.example.com type=AVC msg=audit(1164783469.561:109): avc: denied { ioctl } for pid=8311 comm="smbd" name="log.current" ioctlcmd=0x2a scontext=root:system_r:smbd_t:s0 tcontext=root:object_r:default_t:s0 tclass=tcp_socket -diff --git selinux-python-2.8/audit2allow/test_audit2allow.py selinux-python-2.8/audit2allow/test_audit2allow.py -index a826a9f..87e5504 100644 ---- selinux-python-2.8/audit2allow/test_audit2allow.py -+++ selinux-python-2.8/audit2allow/test_audit2allow.py -@@ -1,6 +1,7 @@ - import unittest - import os --import shutil -+import os.path -+import sys - from tempfile import mkdtemp - from subprocess import Popen, PIPE - -@@ -25,15 +26,22 @@ class Audit2allowTests(unittest.TestCase): - - def test_sepolgen_ifgen(self): - "Verify sepolgen-ifgen works" -- p = Popen(['sudo', 'sepolgen-ifgen'], stdout=PIPE) -+ temp_directory = mkdtemp(suffix='audit2allow_test') -+ output_file = os.path.join(temp_directory, 'interface_info') -+ p = Popen([ -+ sys.executable, './sepolgen-ifgen', '-p', 'test_dummy_policy', '-o', output_file, -+ '--attr-helper', './sepolgen-ifgen-attr-helper' -+ ], stdout=PIPE) - out, err = p.communicate() - if err: - print(out, err) - self.assertSuccess("sepolgen-ifgen", p.returncode, err) -+ os.unlink(output_file) -+ os.rmdir(temp_directory) - - def test_audit2allow(self): - "Verify audit2allow works" -- p = Popen(['python', './audit2allow', "-i", "test.log"], stdout=PIPE) -+ p = Popen([sys.executable, './audit2allow', '-p', 'test_dummy_policy', '-i', 'test.log'], stdout=PIPE) - out, err = p.communicate() - if err: - print(out, err) -@@ -41,11 +49,21 @@ class Audit2allowTests(unittest.TestCase): - - def test_audit2why(self): - "Verify audit2why works" -- p = Popen(['python', './audit2why', "-i", "test.log"], stdout=PIPE) -+ p = Popen([sys.executable, './audit2why', '-p', 'test_dummy_policy', '-i', 'test.log'], stdout=PIPE) - out, err = p.communicate() - if err: - print(out, err) - self.assertSuccess("audit2why", p.returncode, err) - -+ def test_xperms(self): -+ "Verify that xperms generation works" -+ p = Popen([sys.executable, './audit2allow', '-x', '-p', 'test_dummy_policy', '-i', 'test.log'], stdout=PIPE) -+ out, err = p.communicate() -+ if err: -+ print(out, err) -+ self.assertTrue(b"allowxperm" in out) -+ self.assertSuccess("xperms", p.returncode, err) -+ -+ - if __name__ == "__main__": - unittest.main() -diff --git selinux-python-2.8/audit2allow/test_dummy_policy.cil selinux-python-2.8/audit2allow/test_dummy_policy.cil -new file mode 100644 -index 0000000..795fedc ---- /dev/null -+++ selinux-python-2.8/audit2allow/test_dummy_policy.cil -@@ -0,0 +1,75 @@ -+; This is a dummy policy which main aim is to be compatible with test.log -+ -+; Define one category and one sensitivity in order to make things work -+(mls true) -+(category c0) -+(categoryorder (c0)) -+(sensitivity s0) -+(sensitivityorder (s0)) -+(sensitivitycategory s0 (c0)) -+ -+; Define some users and roles -+(user system_u) -+(user root) -+(user unconfined_u) -+(role system_r) -+(role unconfined_r) -+(userrole root system_r) -+(userrole system_u system_r) -+(userrole unconfined_u unconfined_r) -+(userlevel system_u (s0)) -+(userlevel root (s0)) -+(userlevel unconfined_u (s0)) -+(userrange system_u ((s0)(s0 (c0)))) -+(userrange root ((s0)(s0 (c0)))) -+(userrange unconfined_u ((s0)(s0 (c0)))) -+ -+; Define domain types -+(type automount_t) -+(type ftpd_t) -+(type httpd_t) -+(type kernel_t) -+(type nsplugin_t) -+(type postfix_local_t) -+(type qemu_t) -+(type smbd_t) -+ -+(roletype system_r automount_t) -+(roletype system_r ftpd_t) -+(roletype system_r httpd_t) -+(roletype system_r kernel_t) -+(roletype system_r postfix_local_t) -+(roletype system_r qemu_t) -+(roletype system_r smbd_t) -+(roletype unconfined_r nsplugin_t) -+ -+; Define file types -+(type automount_lock_t) -+(type default_t) -+(type fixed_disk_device_t) -+(type home_root_t) -+(type httpd_sys_content_t) -+(type httpd_sys_script_exec_t) -+(type mail_spool_t) -+(type ssh_home_t) -+(type usr_t) -+(type var_t) -+ -+; Define port types -+(type mysqld_port_t) -+(type reserved_port_t) -+ -+; Define initial SID -+(sid kernel) -+(sidorder (kernel)) -+(sidcontext kernel (system_u system_r kernel_t ((s0) (s0)))) -+ -+; Define classes -+(class blk_file (getattr open read write)) -+(class dir (append open search)) -+(class file (execute execute_no_trans getattr open read write)) -+(class tcp_socket (ioctl name_bind name_connect)) -+(classorder (blk_file file dir tcp_socket)) -+ -+; The policy compiler requires at least one rule -+(allow kernel_t default_t (file (open read write))) -diff --git selinux-python-2.8/chcat/chcat selinux-python-2.8/chcat/chcat -index 4bd9fc6..27c537e 100755 ---- selinux-python-2.8/chcat/chcat -+++ selinux-python-2.8/chcat/chcat -@@ -4,7 +4,7 @@ - # - # chcat is a script that allows you modify the Security label on a file - # --#` Author: Daniel Walsh -+# Author: Daniel Walsh - # - # This program is free software; you can redistribute it and/or - # modify it under the terms of the GNU General Public License as -@@ -22,19 +22,15 @@ - # 02111-1307 USA - # - # --try: -- from subprocess import getstatusoutput --except ImportError: -- from commands import getstatusoutput -+import subprocess - import sys - import os - import pwd --import string - import getopt +diff --git selinux-python-2.9-rc1/chcat/chcat selinux-python-2.9-rc1/chcat/chcat +index 5bef007..27c537e 100755 +--- selinux-python-2.9-rc1/chcat/chcat ++++ selinux-python-2.9-rc1/chcat/chcat +@@ -30,7 +30,7 @@ import getopt import selinux import seobject @@ -354,195 +21,11 @@ index 4bd9fc6..27c537e 100755 try: import gettext kwargs = {} -@@ -44,7 +40,7 @@ try: - localedir="/usr/share/locale", - codeset='utf-8', - **kwargs) --except: -+except ImportError: - try: - import builtins - builtins.__dict__['_'] = str -@@ -86,8 +82,7 @@ def chcat_user_add(newcat, users): - if len(serange) > 1: - top = serange[1].split(":") - if len(top) > 1: -- cats.append(top[1]) -- cats = expandCats(cats) -+ cats = expandCats(top[1].split(',')) - - for i in newcat[1:]: - if i not in cats: -@@ -99,12 +94,12 @@ def chcat_user_add(newcat, users): - new_serange = "%s-%s" % (serange[0], top[0]) - - if add_ind: -- cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u) -+ cmd = ["semanage", "login", "-a", "-r", new_serange, "-s", user[0], u] - else: -- cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u) -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ cmd = ["semanage", "login", "-m", "-r", new_serange, "-s", user[0], u] -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 - - return errors -@@ -140,10 +135,11 @@ def chcat_add(orig, newcat, objects, login_ind): - cat_string = "%s,%s" % (cat_string, c) - else: - cat_string = cat -- cmd = 'chcon -l %s:%s %s' % (sensitivity, cat_string, f) -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ -+ cmd = ["chcon", "-l", "%s:%s" % (sensitivity, cat_string), f] -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 - return errors - -@@ -166,8 +162,7 @@ def chcat_user_remove(newcat, users): - if len(serange) > 1: - top = serange[1].split(":") - if len(top) > 1: -- cats.append(top[1]) -- cats = expandCats(cats) -+ cats = expandCats(top[1].split(',')) - - for i in newcat[1:]: - if i in cats: -@@ -179,13 +174,15 @@ def chcat_user_remove(newcat, users): - new_serange = "%s-%s" % (serange[0], top[0]) - - if add_ind: -- cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u) -+ cmd = ["semanage", "login", "-a", "-r", new_serange, "-s", user[0], u] - else: -- cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u) -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ cmd = ["semanage", "login", "-m", "-r", new_serange, "-s", user[0], u] -+ -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 -+ - return errors - - -@@ -224,12 +221,14 @@ def chcat_remove(orig, newcat, objects, login_ind): - continue - - if len(cat) == 0: -- cmd = 'chcon -l %s %s' % (sensitivity, f) -+ new_serange = sensitivity - else: -- cmd = 'chcon -l %s:%s %s' % (sensitivity, cat, f) -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ new_serange = '%s:%s' % (sensitivity, cat) -+ -+ cmd = ["chcon", "-l", new_serange, f] -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 - return errors - -@@ -247,17 +246,17 @@ def chcat_user_replace(newcat, users): - add_ind = 1 - user = seusers["__default__"] - serange = user[1].split("-") -- new_serange = "%s-%s:%s" % (serange[0], newcat[0], string.join(newcat[1:], ",")) -+ new_serange = "%s-%s:%s" % (serange[0], newcat[0], ",".join(newcat[1:])) - if new_serange[-1:] == ":": - new_serange = new_serange[:-1] - - if add_ind: -- cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u) -+ cmd = ["semanage", "login", "-a", "-r", new_serange, "-s", user[0], u] - else: -- cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u) -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ cmd = ["semanage", "login", "-m", "-r", new_serange, "-s", user[0], u] -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 - return errors - -@@ -266,21 +265,18 @@ def chcat_replace(newcat, objects, login_ind): - if login_ind == 1: - return chcat_user_replace(newcat, objects) - errors = 0 -+ # newcat[0] is the sensitivity level, newcat[1:] are the categories - if len(newcat) == 1: -- sensitivity = newcat[0] -- cmd = 'chcon -l %s ' % newcat[0] -+ new_serange = newcat[0] - else: -- sensitivity = newcat[0] -- cmd = 'chcon -l %s:%s' % (sensitivity, newcat[1]) -+ new_serange = "%s:%s" % (newcat[0], newcat[1]) - for cat in newcat[2:]: -- cmd = '%s,%s' % (cmd, cat) -- -- for f in objects: -- cmd = "%s %s" % (cmd, f) -+ new_serange = '%s,%s' % (new_serange, cat) - -- rc = getstatusoutput(cmd) -- if rc[0] != 0: -- print(rc[1]) -+ cmd = ["chcon", "-l", new_serange] + objects -+ try: -+ subprocess.check_call(cmd, stderr=subprocess.STDOUT, shell=False) -+ except subprocess.CalledProcessError: - errors += 1 - - return errors -@@ -384,7 +380,7 @@ def listusercats(users): - if len(users) == 0: - try: - users.append(os.getlogin()) -- except: -+ except OSError: - users.append(pwd.getpwuid(os.getuid()).pw_name) - - verify_users(users) -@@ -401,6 +397,7 @@ def error(msg): - print("%s: %s" % (sys.argv[0], msg)) - sys.exit(1) - -+ - if __name__ == '__main__': - if selinux.is_selinux_mls_enabled() != 1: - error("Requires a mls enabled system") -@@ -435,7 +432,7 @@ if __name__ == '__main__': - except getopt.error as error: - errorExit(_("Options Error %s ") % error.msg) - -- except ValueError as e: -+ except ValueError: - usage() - - if delete_ind: -diff --git selinux-python-2.8/po/Makefile selinux-python-2.8/po/Makefile +diff --git selinux-python-2.9-rc1/po/Makefile selinux-python-2.9-rc1/po/Makefile new file mode 100644 index 0000000..4e052d5 --- /dev/null -+++ selinux-python-2.8/po/Makefile ++++ selinux-python-2.9-rc1/po/Makefile @@ -0,0 +1,83 @@ +# +# Makefile for the PO files (translation) catalog @@ -627,11 +110,11 @@ index 0000000..4e052d5 +.PHONY: missing depend + +relabel: -diff --git selinux-python-2.8/po/POTFILES selinux-python-2.8/po/POTFILES +diff --git selinux-python-2.9-rc1/po/POTFILES selinux-python-2.9-rc1/po/POTFILES new file mode 100644 index 0000000..128eb87 --- /dev/null -+++ selinux-python-2.8/po/POTFILES ++++ selinux-python-2.9-rc1/po/POTFILES @@ -0,0 +1,10 @@ +../audit2allow/audit2allow +../chcat/chcat @@ -643,10 +126,10 @@ index 0000000..128eb87 +../sepolicy/sepolicy/__init__.py +../sepolicy/sepolicy/interface.py +../sepolicy/sepolicy.py -diff --git selinux-python-2.8/semanage/semanage selinux-python-2.8/semanage/semanage -index 8d8a086..18f4a6a 100644 ---- selinux-python-2.8/semanage/semanage -+++ selinux-python-2.8/semanage/semanage +diff --git selinux-python-2.9-rc1/semanage/semanage selinux-python-2.9-rc1/semanage/semanage +index 49add51..18f4a6a 100644 +--- selinux-python-2.9-rc1/semanage/semanage ++++ selinux-python-2.9-rc1/semanage/semanage @@ -27,7 +27,7 @@ import traceback import argparse import seobject @@ -656,57 +139,7 @@ index 8d8a086..18f4a6a 100644 try: import gettext kwargs = {} -@@ -53,7 +53,7 @@ usage_fcontext = "semanage fcontext [-h] [-n] [-N] [-S STORE] [" - usage_fcontext_dict = {' --add': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC',), ' --delete': ('(', '-t TYPE', '-f FTYPE', '|', '-e EQUAL', ')', 'FILE_SPEC',), ' --modify': ('(', '-t TYPE', '-f FTYPE', '-r RANGE', '-s SEUSER', '|', '-e EQUAL', ')', 'FILE_SPEC',), ' --list': ('[-C]',), ' --extract': ('',), ' --deleteall': ('',)} - - usage_user = "semanage user [-h] [-n] [-N] [-S STORE] [" --usage_user_dict = {' --add': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name'')'), ' --delete': ('selinux_name',), ' --modify': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'selinux_name', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} -+usage_user_dict = {' --add': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', 'SEUSER', ')'), ' --delete': ('SEUSER',), ' --modify': ('(', '-L LEVEL', '-R ROLES', '-r RANGE', '-s SEUSER', 'SEUSER', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} - - usage_port = "semanage port [-h] [-n] [-N] [-S STORE] [" - usage_port_dict = {' --add': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --modify': ('-t TYPE', '-p PROTOCOL', '-r RANGE', '(', 'port_name', '|', 'port_range', ')'), ' --delete': ('-p PROTOCOL', '(', 'port_name', '|', 'port_range', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} -@@ -62,7 +62,7 @@ usage_ibpkey = "semanage ibpkey [-h] [-n] [-N] [-s STORE] [" - usage_ibpkey_dict = {' --add': ('-t TYPE', '-x SUBNET_PREFIX', '-r RANGE', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --modify': ('-t TYPE', '-x SUBNET_PREFIX', '-r RANGE', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --delete': ('-x SUBNET_PREFIX', '(', 'ibpkey_name', '|', 'pkey_range', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} - - usage_ibendport = "semanage ibendport [-h] [-n] [-N] [-s STORE] [" --usage_ibendport_dict = {' --add': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --modify': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --delete': ('-z IBDEV_NAME', '-r RANGE''(', 'port', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} -+usage_ibendport_dict = {' --add': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --modify': ('-t TYPE', '-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --delete': ('-z IBDEV_NAME', '-r RANGE', '(', 'port', ')'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} - - usage_node = "semanage node [-h] [-n] [-N] [-S STORE] [" - usage_node_dict = {' --add': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --modify': ('-M NETMASK', '-p PROTOCOL', '-t TYPE', '-r RANGE', 'node'), ' --delete': ('-M NETMASK', '-p PROTOCOL', 'node'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} -@@ -73,7 +73,7 @@ usage_interface_dict = {' --add': ('-t TYPE', '-r RANGE', 'interface'), ' --modi - usage_boolean = "semanage boolean [-h] [-n] [-N] [-S STORE] [" - usage_boolean_dict = {' --modify': ('(', '--on', '|', '--off', ')', 'boolean'), ' --list': ('-C',), ' --extract': ('',), ' --deleteall': ('',)} - --import sepolicy -+ - - - class CheckRole(argparse.Action): -@@ -82,7 +82,12 @@ class CheckRole(argparse.Action): - newval = getattr(namespace, self.dest) - if not newval: - newval = [] -- roles = sepolicy.get_all_roles() -+ try: -+ # sepolicy tries to load the SELinux policy and raises ValueError if it fails. -+ import sepolicy -+ roles = sepolicy.get_all_roles() -+ except ValueError: -+ roles = [] - for v in value.split(): - if v not in roles: - raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (v, ", ".join(roles))) -@@ -421,7 +426,7 @@ def setupUserParser(subparsers): - userParser.add_argument('-R', '--roles', default=[], - action=CheckRole, - help=_(''' --SELinux Roles. You must enclose multiple roles within quotes, separate by spaces. Or specify -R multiple times. -+SELinux Roles. You must enclose multiple roles within quotes, separate by spaces. Or specify -R multiple times. - ''')) - userParser.add_argument('-P', '--prefix', default="user", help=argparse.SUPPRESS) - userParser.add_argument('selinux_name', nargs='?', default=None, help=_('selinux_name')) -@@ -604,19 +609,19 @@ def setupInterfaceParser(subparsers): +@@ -609,19 +609,19 @@ def setupInterfaceParser(subparsers): def handleModule(args): OBJECT = seobject.moduleRecords(args) @@ -736,7 +169,7 @@ index 8d8a086..18f4a6a 100644 for i in OBJECT.customized(): print("module %s" % str(i)) -@@ -630,14 +635,13 @@ def setupModuleParser(subparsers): +@@ -635,14 +635,13 @@ def setupModuleParser(subparsers): parser_add_priority(moduleParser, "module") mgroup = moduleParser.add_mutually_exclusive_group(required=True) @@ -755,7 +188,7 @@ index 8d8a086..18f4a6a 100644 moduleParser.set_defaults(func=handleModule) -@@ -739,9 +743,7 @@ def handlePermissive(args): +@@ -744,9 +743,7 @@ def handlePermissive(args): if args.action is "delete": OBJECT.delete(args.type) else: @@ -766,32 +199,10 @@ index 8d8a086..18f4a6a 100644 def setupPermissiveParser(subparsers): -@@ -776,7 +778,7 @@ def setupDontauditParser(subparsers): - - - def handleExport(args): -- manageditems = ["boolean", "login", "interface", "user", "port", "node", "fcontext", "module"] -+ manageditems = ["boolean", "login", "interface", "user", "port", "node", "fcontext", "module", "ibendport", "ibpkey"] - for i in manageditems: - print("%s -D" % i) - for i in manageditems: -diff --git selinux-python-2.8/semanage/semanage-user.8 selinux-python-2.8/semanage/semanage-user.8 -index 30bc670..23fec69 100644 ---- selinux-python-2.8/semanage/semanage-user.8 -+++ selinux-python-2.8/semanage/semanage-user.8 -@@ -2,7 +2,7 @@ - .SH "NAME" - .B semanage\-user \- SELinux Policy Management SELinux User mapping tool - .SH "SYNOPSIS" --.B semanage user [\-h] [\-n] [\-N] [\-S STORE] [ \-\-add ( \-L LEVEL \-R ROLES \-r RANGE \-s SEUSER selinux_name) | \-\-delete selinux_name | \-\-deleteall | \-\-extract | \-\-list [\-C] | \-\-modify ( \-L LEVEL \-R ROLES \-r RANGE \-s SEUSER selinux_name ) ] -+.B semanage user [\-h] [\-n] [\-N] [\-S STORE] [ \-\-add ( \-L LEVEL \-R ROLES \-r RANGE SEUSER) | \-\-delete SEUSER | \-\-deleteall | \-\-extract | \-\-list [\-C] | \-\-modify ( \-L LEVEL \-R ROLES \-r RANGE SEUSER ) ] - - .SH "DESCRIPTION" - semanage is used to configure certain elements of -diff --git selinux-python-2.8/semanage/semanage.8 selinux-python-2.8/semanage/semanage.8 +diff --git selinux-python-2.9-rc1/semanage/semanage.8 selinux-python-2.9-rc1/semanage/semanage.8 index 0bdb90f..0cdcfcc 100644 ---- selinux-python-2.8/semanage/semanage.8 -+++ selinux-python-2.8/semanage/semanage.8 +--- selinux-python-2.9-rc1/semanage/semanage.8 ++++ selinux-python-2.9-rc1/semanage/semanage.8 @@ -57,9 +57,8 @@ to SELinux user identities (which controls the initial security context assigned to Linux users when they login and bounds their authorized role set) as well as security context mappings for various kinds of objects, such @@ -804,10 +215,10 @@ index 0bdb90f..0cdcfcc 100644 while the semanage user command deals with the mapping from SELinux user identities to authorized role sets. In most cases, only the former mapping needs to be adjusted by the administrator; the latter -diff --git selinux-python-2.8/semanage/seobject.py selinux-python-2.8/semanage/seobject.py -index c76dce8..ffd3e14 100644 ---- selinux-python-2.8/semanage/seobject.py -+++ selinux-python-2.8/semanage/seobject.py +diff --git selinux-python-2.9-rc1/semanage/seobject.py selinux-python-2.9-rc1/semanage/seobject.py +index 556d3ba..c9aaebe 100644 +--- selinux-python-2.9-rc1/semanage/seobject.py ++++ selinux-python-2.9-rc1/semanage/seobject.py @@ -30,10 +30,10 @@ import sys import stat import socket @@ -821,34 +232,7 @@ index c76dce8..ffd3e14 100644 try: import gettext -@@ -101,6 +101,8 @@ ftype_to_audit = {"": "any", - - try: - import audit -+ #test if audit module is enabled -+ audit.audit_close(audit.audit_open()) - - class logger: - -@@ -138,7 +140,7 @@ try: - - self.log_list = [] - self.log_change_list = [] --except: -+except (OSError, ImportError): - class logger: - - def __init__(self): -@@ -258,6 +260,8 @@ class semanageRecords: - if self.store == "" or self.store == localstore: - self.mylog = logger() - else: -+ sepolicy.load_store_policy(self.store) -+ selinux.selinux_set_policy_root("%s%s" % (selinux.selinux_path(), self.store)) - self.mylog = nulllogger() - - def set_reload(self, load): -@@ -397,6 +401,8 @@ class moduleRecords(semanageRecords): +@@ -401,6 +401,8 @@ class moduleRecords(semanageRecords): print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled)) def add(self, file, priority): @@ -857,7 +241,7 @@ index c76dce8..ffd3e14 100644 if not os.path.exists(file): raise ValueError(_("Module does not exist: %s ") % file) -@@ -409,7 +415,9 @@ class moduleRecords(semanageRecords): +@@ -413,7 +415,9 @@ class moduleRecords(semanageRecords): self.commit() def set_enabled(self, module, enable): @@ -868,7 +252,7 @@ index c76dce8..ffd3e14 100644 rc, key = semanage_module_key_create(self.sh) if rc < 0: raise ValueError(_("Could not create module key")) -@@ -431,7 +439,9 @@ class moduleRecords(semanageRecords): +@@ -435,7 +439,9 @@ class moduleRecords(semanageRecords): if rc < 0: raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority) @@ -879,268 +263,7 @@ index c76dce8..ffd3e14 100644 rc = semanage_module_remove(self.sh, m) if rc < 0 and rc != -2: raise ValueError(_("Could not remove module %s (remove failed)") % m) -@@ -593,7 +603,6 @@ class loginRecords(semanageRecords): - - semanage_seuser_key_free(k) - semanage_seuser_free(u) -- self.mylog.log("login", name, sename=sename, serange=serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange) - - def add(self, name, sename, serange): - try: -@@ -601,7 +610,6 @@ class loginRecords(semanageRecords): - self.__add(name, sename, serange) - self.commit() - except ValueError as error: -- self.mylog.commit(0) - raise error - - def __modify(self, name, sename="", serange=""): -@@ -653,7 +661,6 @@ class loginRecords(semanageRecords): - - semanage_seuser_key_free(k) - semanage_seuser_free(u) -- self.mylog.log("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange) - - def modify(self, name, sename="", serange=""): - try: -@@ -661,7 +668,6 @@ class loginRecords(semanageRecords): - self.__modify(name, sename, serange) - self.commit() - except ValueError as error: -- self.mylog.commit(0) - raise error - - def __delete(self, name): -@@ -694,8 +700,6 @@ class loginRecords(semanageRecords): - rec, self.sename, self.serange = selinux.getseuserbyname("__default__") - range, (rc, serole) = userrec.get(self.sename) - -- self.mylog.log_remove("login", name, sename=self.sename, serange=self.serange, serole=",".join(serole), oldserole=",".join(oldserole), oldsename=self.oldsename, oldserange=self.oldserange) -- - def delete(self, name): - try: - self.begin() -@@ -703,7 +707,6 @@ class loginRecords(semanageRecords): - self.commit() - - except ValueError as error: -- self.mylog.commit(0) - raise error - - def deleteall(self): -@@ -717,7 +720,6 @@ class loginRecords(semanageRecords): - self.__delete(semanage_seuser_get_name(u)) - self.commit() - except ValueError as error: -- self.mylog.commit(0) - raise error - - def get_all_logins(self): -@@ -753,7 +755,10 @@ class loginRecords(semanageRecords): - l = [] - ddict = self.get_all(True) - for k in sorted(ddict.keys()): -- l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) -+ if ddict[k][1]: -+ l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k)) -+ else: -+ l.append("-a -s %s %s" % (ddict[k][0], k)) - return l - - def list(self, heading=1, locallist=0): -@@ -1020,7 +1025,10 @@ class seluserRecords(semanageRecords): - l = [] - ddict = self.get_all(True) - for k in sorted(ddict.keys()): -- l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) -+ if ddict[k][1] or ddict[k][2]: -+ l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k)) -+ else: -+ l.append("-a -R '%s' %s" % (ddict[k][3], k)) - return l - - def list(self, heading=1, locallist=0): -@@ -1043,13 +1051,15 @@ class seluserRecords(semanageRecords): - - - class portRecords(semanageRecords): -- try: -- valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "port_type"))[0]["types"]) -- except RuntimeError: -- valid_types = [] -+ -+ valid_types = [] - - def __init__(self, args = None): - semanageRecords.__init__(self, args) -+ try: -+ self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "port_type"))[0]["types"]) -+ except RuntimeError: -+ pass - - def __genkey(self, port, proto): - if proto == "tcp": -@@ -1087,6 +1097,8 @@ class portRecords(semanageRecords): - if type == "": - raise ValueError(_("Type is required")) - -+ type = sepolicy.get_real_type_name(type) -+ - if type not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a port type") % type) - -@@ -1151,6 +1163,7 @@ class portRecords(semanageRecords): - else: - raise ValueError(_("Requires setype")) - -+ setype = sepolicy.get_real_type_name(setype) - if setype and setype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a port type") % setype) - -@@ -1295,10 +1308,11 @@ class portRecords(semanageRecords): - l = [] - ddict = self.get_all(True) - for k in sorted(ddict.keys()): -- if k[0] == k[1]: -- l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0])) -+ port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1]) -+ if ddict[k][1]: -+ l.append("-a -t %s -r '%s' -p %s %s" % (ddict[k][0], ddict[k][1], k[2], port)) - else: -- l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1])) -+ l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], port)) - return l - - def list(self, heading=1, locallist=0): -@@ -1317,14 +1331,16 @@ class portRecords(semanageRecords): - print(rec) - - class ibpkeyRecords(semanageRecords): -- try: -- q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_installed_policy()), attrs=["ibpkey_type"]) -- valid_types = sorted(str(t) for t in q.results()) -- except: -- valid_types = [] -+ -+ valid_types = [] - - def __init__(self, args = None): - semanageRecords.__init__(self, args) -+ try: -+ q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibpkey_type"]) -+ self.valid_types = sorted(str(t) for t in q.results()) -+ except: -+ pass - - def __genkey(self, pkey, subnet_prefix): - if subnet_prefix == "": -@@ -1355,6 +1371,8 @@ class ibpkeyRecords(semanageRecords): - if type == "": - raise ValueError(_("Type is required")) - -+ type = sepolicy.get_real_type_name(type) -+ - if type not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a ibpkey type") % type) - -@@ -1417,6 +1435,8 @@ class ibpkeyRecords(semanageRecords): - else: - raise ValueError(_("Requires setype")) - -+ setype = sepolicy.get_real_type_name(setype) -+ - if setype and setype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a ibpkey type") % setype) - -@@ -1548,10 +1568,11 @@ class ibpkeyRecords(semanageRecords): - ddict = self.get_all(True) - - for k in sorted(ddict.keys()): -- if k[0] == k[1]: -- l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], k[0])) -+ port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1]) -+ if ddict[k][1]: -+ l.append("-a -t %s -r '%s' -x %s %s" % (ddict[k][0], ddict[k][1], k[2], port)) - else: -- l.append("-a -t %s -x %s %s-%s" % (ddict[k][0], k[2], k[0], k[1])) -+ l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], port)) - return l - - def list(self, heading=1, locallist=0): -@@ -1570,14 +1591,16 @@ class ibpkeyRecords(semanageRecords): - print(rec) - - class ibendportRecords(semanageRecords): -- try: -- q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_installed_policy()), attrs=["ibendport_type"]) -- valid_types = set(str(t) for t in q.results()) -- except: -- valid_types = [] -+ -+ valid_types = [] - - def __init__(self, args = None): - semanageRecords.__init__(self, args) -+ try: -+ q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibendport_type"]) -+ self.valid_types = set(str(t) for t in q.results()) -+ except: -+ pass - - def __genkey(self, ibendport, ibdev_name): - if ibdev_name == "": -@@ -1603,6 +1626,8 @@ class ibendportRecords(semanageRecords): - if type == "": - raise ValueError(_("Type is required")) - -+ type = sepolicy.get_real_type_name(type) -+ - if type not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be an ibendport type") % type) - (k, ibendport, port) = self.__genkey(ibendport, ibdev_name) -@@ -1664,6 +1689,8 @@ class ibendportRecords(semanageRecords): - else: - raise ValueError(_("Requires setype")) - -+ setype = sepolicy.get_real_type_name(setype) -+ - if setype and setype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be an ibendport type") % setype) - -@@ -1788,7 +1815,10 @@ class ibendportRecords(semanageRecords): - ddict = self.get_all(True) - - for k in sorted(ddict.keys()): -- l.append("-a -t %s -r %s -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0])) -+ if ddict[k][1]: -+ l.append("-a -t %s -r '%s' -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0])) -+ else: -+ l.append("-a -t %s -z %s %s" % (ddict[k][0], k[1], k[0])) - return l - - def list(self, heading=1, locallist=0): -@@ -1807,14 +1837,16 @@ class ibendportRecords(semanageRecords): - print(rec) - - class nodeRecords(semanageRecords): -- try: -- valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "node_type"))[0]["types"]) -- except RuntimeError: -- valid_types = [] -+ -+ valid_types = [] - - def __init__(self, args = None): - semanageRecords.__init__(self, args) - self.protocol = ["ipv4", "ipv6"] -+ try: -+ self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "node_type"))[0]["types"]) -+ except RuntimeError: -+ pass - - def validate(self, addr, mask, protocol): - newaddr = addr -@@ -1826,13 +1858,13 @@ class nodeRecords(semanageRecords): +@@ -1852,13 +1858,13 @@ class nodeRecords(semanageRecords): # verify valid comination if len(mask) == 0 or mask[0] == "/": @@ -1159,625 +282,10 @@ index c76dce8..ffd3e14 100644 try: newprotocol = self.protocol.index(protocol) -@@ -1853,6 +1885,8 @@ class nodeRecords(semanageRecords): - if ctype == "": - raise ValueError(_("SELinux node type is required")) - -+ ctype = sepolicy.get_real_type_name(ctype) -+ - if ctype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a node type") % ctype) - -@@ -1922,6 +1956,8 @@ class nodeRecords(semanageRecords): - if serange == "" and setype == "": - raise ValueError(_("Requires setype or serange")) - -+ setype = sepolicy.get_real_type_name(setype) -+ - if setype and setype not in self.valid_types: - raise ValueError(_("Type %s is invalid, must be a node type") % setype) - -@@ -2024,7 +2060,10 @@ class nodeRecords(semanageRecords): - l = [] - ddict = self.get_all(True) - for k in sorted(ddict.keys()): -- l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0])) -+ if ddict[k][3]: -+ l.append("-a -M %s -p %s -t %s -r '%s' %s" % (k[1], k[2], ddict[k][2], ddict[k][3], k[0])) -+ else: -+ l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0])) - return l - - def list(self, heading=1, locallist=0): -@@ -2218,7 +2257,10 @@ class interfaceRecords(semanageRecords): - l = [] - ddict = self.get_all(True) - for k in sorted(ddict.keys()): -- l.append("-a -t %s %s" % (ddict[k][2], k)) -+ if ddict[k][3]: -+ l.append("-a -t %s -r '%s' %s" % (ddict[k][2], ddict[k][3], k)) -+ else: -+ l.append("-a -t %s %s" % (ddict[k][2], k)) - return l - - def list(self, heading=1, locallist=0): -@@ -2238,15 +2280,17 @@ class interfaceRecords(semanageRecords): - - - class fcontextRecords(semanageRecords): -- try: -- valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "file_type"))[0]["types"]) -- valid_types += list(list(sepolicy.info(sepolicy.ATTRIBUTE, "device_node"))[0]["types"]) -- valid_types.append("<>") -- except RuntimeError: -- valid_types = [] -+ -+ valid_types = [] - - def __init__(self, args = None): - semanageRecords.__init__(self, args) -+ try: -+ self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "file_type"))[0]["types"]) -+ self.valid_types += list(list(sepolicy.info(sepolicy.ATTRIBUTE, "device_node"))[0]["types"]) -+ except RuntimeError: -+ pass -+ - self.equiv = {} - self.equiv_dist = {} - self.equal_ind = False -@@ -2369,8 +2413,10 @@ class fcontextRecords(semanageRecords): - if type == "": - raise ValueError(_("SELinux Type is required")) - -- if type not in self.valid_types: -- raise ValueError(_("Type %s is invalid, must be a file or device type") % type) -+ if type != "<>": -+ type = sepolicy.get_real_type_name(type) -+ if type not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a file or device type") % type) - - (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) - if rc < 0: -@@ -2432,8 +2478,10 @@ class fcontextRecords(semanageRecords): - def __modify(self, target, setype, ftype, serange, seuser): - if serange == "" and setype == "" and seuser == "": - raise ValueError(_("Requires setype, serange or seuser")) -- if setype and setype not in self.valid_types: -- raise ValueError(_("Type %s is invalid, must be a file or device type") % setype) -+ if setype not in ["", "<>"]: -+ setype = sepolicy.get_real_type_name(setype) -+ if setype not in self.valid_types: -+ raise ValueError(_("Type %s is invalid, must be a file or device type") % setype) - - self.validate(target) - -@@ -2597,7 +2645,10 @@ class fcontextRecords(semanageRecords): - fcon_dict = self.get_all(True) - for k in sorted(fcon_dict.keys()): - if fcon_dict[k]: -- l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) -+ if fcon_dict[k][3]: -+ l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0])) -+ else: -+ l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0])) - - if len(self.equiv): - for target in self.equiv.keys(): -diff --git selinux-python-2.8/sepolgen/src/sepolgen/access.py selinux-python-2.8/sepolgen/src/sepolgen/access.py -index a5d8698..ba80f93 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/access.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/access.py -@@ -78,6 +78,7 @@ class AccessVector(util.Comparison): - .obj_class - The object class to which access is allowed. [String or None] - .perms - The permissions allowed to the object class. [IdSet] - .audit_msgs - The audit messages that generated this access vector [List of strings] -+ .xperms - Extended permissions attached to the AV. [Dictionary {operation: xperm set}] - """ - def __init__(self, init_list=None): - if init_list: -@@ -87,9 +88,11 @@ class AccessVector(util.Comparison): - self.tgt_type = None - self.obj_class = None - self.perms = refpolicy.IdSet() -- self.audit_msgs = [] -- self.type = audit2why.TERULE -- self.data = [] -+ -+ self.audit_msgs = [] -+ self.type = audit2why.TERULE -+ self.data = [] -+ self.xperms = {} - # when implementing __eq__ also __hash__ is needed on py2 - # if object is muttable __hash__ should be None - self.__hash__ = None -@@ -131,6 +134,15 @@ class AccessVector(util.Comparison): - l.extend(sorted(self.perms)) - return l - -+ def merge(self, av): -+ """Add permissions and extended permissions from AV""" -+ self.perms.update(av.perms) -+ -+ for op in av.xperms: -+ if op not in self.xperms: -+ self.xperms[op] = refpolicy.XpermSet() -+ self.xperms[op].extend(av.xperms[op]) -+ - def __str__(self): - return self.to_string() - -@@ -260,28 +272,28 @@ class AccessVectorSet: - def add(self, src_type, tgt_type, obj_class, perms, audit_msg=None, avc_type=audit2why.TERULE, data=[]): - """Add an access vector to the set. - """ -- tgt = self.src.setdefault(src_type, { }) -- cls = tgt.setdefault(tgt_type, { }) -- -- if (obj_class, avc_type) in cls: -- access = cls[obj_class, avc_type] -- else: -- access = AccessVector() -- access.src_type = src_type -- access.tgt_type = tgt_type -- access.obj_class = obj_class -- access.data = data -- access.type = avc_type -- cls[obj_class, avc_type] = access -- -- access.perms.update(perms) -- if audit_msg: -- access.audit_msgs.append(audit_msg) -+ av = AccessVector() -+ av.src_type = src_type -+ av.tgt_type = tgt_type -+ av.obj_class = obj_class -+ av.perms = perms -+ av.data = data -+ av.type = avc_type -+ -+ self.add_av(av, audit_msg) - - def add_av(self, av, audit_msg=None): - """Add an access vector to the set.""" -- self.add(av.src_type, av.tgt_type, av.obj_class, av.perms) -+ tgt = self.src.setdefault(av.src_type, { }) -+ cls = tgt.setdefault(av.tgt_type, { }) - -+ if (av.obj_class, av.type) in cls: -+ cls[av.obj_class, av.type].merge(av) -+ else: -+ cls[av.obj_class, av.type] = av -+ -+ if audit_msg: -+ cls[av.obj_class, av.type].audit_msgs.append(audit_msg) - - def avs_extract_types(avs): - types = refpolicy.IdSet() -diff --git selinux-python-2.8/sepolgen/src/sepolgen/audit.py selinux-python-2.8/sepolgen/src/sepolgen/audit.py -index 26ce6c9..daed58c 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/audit.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/audit.py -@@ -152,6 +152,7 @@ class AVCMessage(AuditMessage): - access - list of accesses that were allowed or denied - denial - boolean indicating whether this was a denial (True) or granted - (False) message. -+ ioctlcmd - ioctl 'request' parameter - - An example audit message generated from the audit daemon looks like (line breaks - added): -@@ -178,6 +179,7 @@ class AVCMessage(AuditMessage): - self.name = "" - self.accesses = [] - self.denial = True -+ self.ioctlcmd = None - self.type = audit2why.TERULE - - def __parse_access(self, recs, start): -@@ -237,6 +239,11 @@ class AVCMessage(AuditMessage): - self.exe = fields[1][1:-1] - elif fields[0] == "name": - self.name = fields[1][1:-1] -+ elif fields[0] == "ioctlcmd": -+ try: -+ self.ioctlcmd = int(fields[1], 16) -+ except ValueError: -+ pass - - if not found_src or not found_tgt or not found_class or not found_access: - raise ValueError("AVC message in invalid format [%s]\n" % self.message) -@@ -522,13 +529,20 @@ class AuditParser: - for avc in self.avc_msgs: - if avc.denial != True and only_denials: - continue -- if avc_filter: -- if avc_filter.filter(avc): -- av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, -- avc.accesses, avc, avc_type=avc.type, data=avc.data) -- else: -- av_set.add(avc.scontext.type, avc.tcontext.type, avc.tclass, -- avc.accesses, avc, avc_type=avc.type, data=avc.data) -+ -+ if not avc_filter or avc_filter.filter(avc): -+ av = access.AccessVector([avc.scontext.type, avc.tcontext.type, -+ avc.tclass] + avc.accesses) -+ av.data = avc.data -+ av.type = avc.type -+ -+ if avc.ioctlcmd: -+ xperm_set = refpolicy.XpermSet() -+ xperm_set.add(avc.ioctlcmd) -+ av.xperms["ioctl"] = xperm_set -+ -+ av_set.add_av(av, audit_msg=avc) -+ - return av_set - - class AVCTypeFilter: -diff --git selinux-python-2.8/sepolgen/src/sepolgen/defaults.py selinux-python-2.8/sepolgen/src/sepolgen/defaults.py -index 9591063..e8d7b6a 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/defaults.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/defaults.py -@@ -32,12 +32,13 @@ class PathChoooser(object): - self.config_pathname = pathname - ignore = re.compile(r"^\s*(?:#.+)?$") - consider = re.compile(r"^\s*(\w+)\s*=\s*(.+?)\s*$") -- for lineno, line in enumerate(open(pathname)): -- if ignore.match(line): continue -- mo = consider.match(line) -- if not mo: -- raise ValueError("%s:%d: line is not in key = value format" % (pathname, lineno+1)) -- self.config[mo.group(1)] = mo.group(2) -+ with open(pathname, "r") as fd: -+ for lineno, line in enumerate(fd): -+ if ignore.match(line): continue -+ mo = consider.match(line) -+ if not mo: -+ raise ValueError("%s:%d: line is not in key = value format" % (pathname, lineno+1)) -+ self.config[mo.group(1)] = mo.group(2) - - # We're only exporting one useful function, so why not be a function - def __call__(self, testfilename, pathset="SELINUX_DEVEL_PATH"): -diff --git selinux-python-2.8/sepolgen/src/sepolgen/policygen.py selinux-python-2.8/sepolgen/src/sepolgen/policygen.py -index ee664fb..319da15 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/policygen.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/policygen.py -@@ -50,10 +50,11 @@ class PolicyGenerator: - in the form of access vectors. - - It generates allow rules and optionally module require -- statements and reference policy interfaces. By default -- only allow rules are generated. The methods .set_gen_refpol -- and .set_gen_requires turns on interface generation and -- requires generation respectively. -+ statements, reference policy interfaces, and extended -+ permission access vector rules. By default only allow rules -+ are generated. The methods .set_gen_refpol, .set_gen_requires -+ and .set_gen_xperms turns on interface generation, -+ requires generation, and xperms rules genration respectively. - - PolicyGenerator can also optionally add comments explaining - why a particular access was allowed based on the audit -@@ -82,6 +83,7 @@ class PolicyGenerator: - self.module = refpolicy.Module() - - self.dontaudit = False -+ self.xperms = False - - self.domains = None - def set_gen_refpol(self, if_set=None, perm_maps=None): -@@ -120,6 +122,12 @@ class PolicyGenerator: - def set_gen_dontaudit(self, dontaudit): - self.dontaudit = dontaudit - -+ def set_gen_xperms(self, xperms): -+ """Set whether extended permission access vector rules -+ are generated. -+ """ -+ self.xperms = xperms -+ - def __set_module_style(self): - if self.ifgen: - refpolicy = True -@@ -153,51 +161,69 @@ class PolicyGenerator: - """Return the generated module""" - return self.module - -- def __add_allow_rules(self, avs): -- for av in avs: -- rule = refpolicy.AVRule(av) -+ def __add_av_rule(self, av): -+ """Add access vector rule. -+ """ -+ rule = refpolicy.AVRule(av) -+ -+ if self.dontaudit: -+ rule.rule_type = rule.DONTAUDIT -+ rule.comment = "" -+ if self.explain: -+ rule.comment = str(refpolicy.Comment(explain_access(av, verbosity=self.explain))) -+ -+ if av.type == audit2why.ALLOW: -+ rule.comment += "\n#!!!! This avc is allowed in the current policy" -+ -+ if av.xperms: -+ rule.comment += "\n#!!!! This av rule may have been overridden by an extended permission av rule" -+ -+ if av.type == audit2why.DONTAUDIT: -+ rule.comment += "\n#!!!! This avc has a dontaudit rule in the current policy" -+ -+ if av.type == audit2why.BOOLEAN: -+ if len(av.data) > 1: -+ rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n# %s" % ", ".join([x[0] for x in av.data]) -+ else: -+ rule.comment += "\n#!!!! This avc can be allowed using the boolean '%s'" % av.data[0][0] -+ -+ if av.type == audit2why.CONSTRAINT: -+ rule.comment += "\n#!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access." -+ rule.comment += "\n#Constraint rule: " -+ rule.comment += "\n#\t" + av.data[0] -+ for reason in av.data[1:]: -+ rule.comment += "\n#\tPossible cause is the source %s and target %s are different." % reason -+ -+ try: -+ if ( av.type == audit2why.TERULE and -+ "write" in av.perms and -+ ( "dir" in av.obj_class or "open" in av.perms )): -+ if not self.domains: -+ self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"] -+ types=[] -+ -+ for i in [x[TCONTEXT] for x in sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})]: -+ if i not in self.domains: -+ types.append(i) -+ if len(types) == 1: -+ rule.comment += "\n#!!!! The source type '%s' can write to a '%s' of the following type:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types)) -+ elif len(types) >= 1: -+ rule.comment += "\n#!!!! The source type '%s' can write to a '%s' of the following types:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types)) -+ except: -+ pass -+ -+ self.module.children.append(rule) -+ -+ def __add_ext_av_rules(self, av): -+ """Add extended permission access vector rules. -+ """ -+ for op in av.xperms.keys(): -+ extrule = refpolicy.AVExtRule(av, op) -+ - if self.dontaudit: -- rule.rule_type = rule.DONTAUDIT -- rule.comment = "" -- if self.explain: -- rule.comment = str(refpolicy.Comment(explain_access(av, verbosity=self.explain))) -- if av.type == audit2why.ALLOW: -- rule.comment += "\n#!!!! This avc is allowed in the current policy" -- if av.type == audit2why.DONTAUDIT: -- rule.comment += "\n#!!!! This avc has a dontaudit rule in the current policy" -- -- if av.type == audit2why.BOOLEAN: -- if len(av.data) > 1: -- rule.comment += "\n#!!!! This avc can be allowed using one of the these booleans:\n# %s" % ", ".join([x[0] for x in av.data]) -- else: -- rule.comment += "\n#!!!! This avc can be allowed using the boolean '%s'" % av.data[0][0] -- -- if av.type == audit2why.CONSTRAINT: -- rule.comment += "\n#!!!! This avc is a constraint violation. You would need to modify the attributes of either the source or target types to allow this access." -- rule.comment += "\n#Constraint rule: " -- rule.comment += "\n#\t" + av.data[0] -- for reason in av.data[1:]: -- rule.comment += "\n#\tPossible cause is the source %s and target %s are different." % reason -- -- try: -- if ( av.type == audit2why.TERULE and -- "write" in av.perms and -- ( "dir" in av.obj_class or "open" in av.perms )): -- if not self.domains: -- self.domains = seinfo(ATTRIBUTE, name="domain")[0]["types"] -- types=[] -- -- for i in [x[TCONTEXT] for x in sesearch([ALLOW], {SCONTEXT: av.src_type, CLASS: av.obj_class, PERMS: av.perms})]: -- if i not in self.domains: -- types.append(i) -- if len(types) == 1: -- rule.comment += "\n#!!!! The source type '%s' can write to a '%s' of the following type:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types)) -- elif len(types) >= 1: -- rule.comment += "\n#!!!! The source type '%s' can write to a '%s' of the following types:\n# %s\n" % ( av.src_type, av.obj_class, ", ".join(types)) -- except: -- pass -- self.module.children.append(rule) -+ extrule.rule_type = extrule.DONTAUDITXPERM - -+ self.module.children.append(extrule) - - def add_access(self, av_set): - """Add the access from the access vector set to this -@@ -215,7 +241,10 @@ class PolicyGenerator: - raw_allow = av_set - - # Generate the raw allow rules from the filtered list -- self.__add_allow_rules(raw_allow) -+ for av in raw_allow: -+ self.__add_av_rule(av) -+ if self.xperms and av.xperms: -+ self.__add_ext_av_rules(av) - - def add_role_types(self, role_type_set): - for role_type in role_type_set: -diff --git selinux-python-2.8/sepolgen/src/sepolgen/refparser.py selinux-python-2.8/sepolgen/src/sepolgen/refparser.py -index 2cef8e8..3415aff 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/refparser.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/refparser.py -@@ -786,7 +786,7 @@ def p_role_allow(p): - - def p_permissive(p): - 'permissive : PERMISSIVE names SEMI' -- t.skip(1) -+ pass - - def p_avrule_def(p): - '''avrule_def : ALLOW names names COLON names names SEMI -diff --git selinux-python-2.8/sepolgen/src/sepolgen/refpolicy.py selinux-python-2.8/sepolgen/src/sepolgen/refpolicy.py -index 352b187..c30a8c7 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/refpolicy.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/refpolicy.py -@@ -109,6 +109,9 @@ class Node(PolicyBase): - def avrules(self): - return filter(lambda x: isinstance(x, AVRule), walktree(self)) - -+ def avextrules(self): -+ return filter(lambda x: isinstance(x, AVExtRule), walktree(self)) -+ - def typerules(self): - return filter(lambda x: isinstance(x, TypeRule), walktree(self)) - -@@ -352,6 +355,65 @@ class ObjectClass(Leaf): - self.name = name - self.perms = IdSet() - -+class XpermSet(): -+ """Extended permission set. -+ -+ This class represents one or more extended permissions -+ represented by numeric values or ranges of values. The -+ .complement attribute is used to specify all permission -+ except those specified. -+ -+ Two xperm set can be merged using the .extend() method. -+ """ -+ def __init__(self, complement=False): -+ self.complement = complement -+ self.ranges = [] -+ -+ def __normalize_ranges(self): -+ """Ensure that ranges are not overlapping. -+ """ -+ self.ranges.sort() -+ -+ i = 0 -+ while i < len(self.ranges): -+ while i + 1 < len(self.ranges): -+ if self.ranges[i + 1][0] <= self.ranges[i][1] + 1: -+ self.ranges[i] = (self.ranges[i][0], max(self.ranges[i][1], -+ self.ranges[i + 1][1])) -+ del self.ranges[i + 1] -+ else: -+ break -+ i += 1 -+ -+ def extend(self, s): -+ """Add ranges from an xperm set -+ """ -+ self.ranges.extend(s.ranges) -+ self.__normalize_ranges() -+ -+ def add(self, minimum, maximum=None): -+ """Add value of range of values to the xperm set. -+ """ -+ if maximum is None: -+ maximum = minimum -+ self.ranges.append((minimum, maximum)) -+ self.__normalize_ranges() -+ -+ def to_string(self): -+ if not self.ranges: -+ return "" -+ -+ compl = "~ " if self.complement else "" -+ -+ # print single value without braces -+ if len(self.ranges) == 1 and self.ranges[0][0] == self.ranges[0][1]: -+ return compl + str(self.ranges[0][0]) -+ -+ vals = map(lambda x: str(x[0]) if x[0] == x[1] else "%s-%s" % x, -+ self.ranges) -+ -+ return "%s{ %s }" % (compl, " ".join(vals)) -+ - # Basic statements - - class TypeAttribute(Leaf): -@@ -472,8 +534,10 @@ class AVRule(Leaf): - return "allow" - elif self.rule_type == self.DONTAUDIT: - return "dontaudit" -- else: -+ elif self.rule_type == self.AUDITALLOW: - return "auditallow" -+ elif self.rule_type == self.NEVERALLOW: -+ return "neverallow" - - def from_av(self, av): - """Add the access from an access vector to this allow -@@ -497,6 +561,65 @@ class AVRule(Leaf): - self.tgt_types.to_space_str(), - self.obj_classes.to_space_str(), - self.perms.to_space_str()) -+ -+class AVExtRule(Leaf): -+ """Extended permission access vector rule. -+ -+ The AVExtRule class represents allowxperm, dontauditxperm, -+ auditallowxperm, and neverallowxperm rules. -+ -+ The source and target types, and object classes are represented -+ by sets containing strings. The operation is a single string, -+ e.g. 'ioctl'. Extended permissions are represented by an XpermSet. -+ """ -+ ALLOWXPERM = 0 -+ DONTAUDITXPERM = 1 -+ AUDITALLOWXPERM = 2 -+ NEVERALLOWXPERM = 3 -+ -+ def __init__(self, av=None, op=None, parent=None): -+ Leaf.__init__(self, parent) -+ self.src_types = IdSet() -+ self.tgt_types = IdSet() -+ self.obj_classes = IdSet() -+ self.rule_type = self.ALLOWXPERM -+ self.xperms = XpermSet() -+ self.operation = op -+ if av: -+ self.from_av(av, op) -+ -+ def __rule_type_str(self): -+ if self.rule_type == self.ALLOWXPERM: -+ return "allowxperm" -+ elif self.rule_type == self.DONTAUDITXPERM: -+ return "dontauditxperm" -+ elif self.rule_type == self.AUDITALLOWXPERM: -+ return "auditallowxperm" -+ elif self.rule_type == self.NEVERALLOWXPERM: -+ return "neverallowxperm" -+ -+ def from_av(self, av, op): -+ self.src_types.add(av.src_type) -+ if av.src_type == av.tgt_type: -+ self.tgt_types.add("self") -+ else: -+ self.tgt_types.add(av.tgt_type) -+ self.obj_classes.add(av.obj_class) -+ self.operation = op -+ self.xperms = av.xperms[op] -+ -+ def to_string(self): -+ """Return a string representation of the rule that is -+ a valid policy language representation (assuming that -+ the types, object class, etc. are valid). -+ """ -+ return "%s %s %s:%s %s %s;" % (self.__rule_type_str(), -+ self.src_types.to_space_str(), -+ self.tgt_types.to_space_str(), -+ self.obj_classes.to_space_str(), -+ self.operation, -+ self.xperms.to_string()) -+ - class TypeRule(Leaf): - """SELinux type rules. - -diff --git selinux-python-2.8/sepolgen/src/sepolgen/sepolgeni18n.py selinux-python-2.8/sepolgen/src/sepolgen/sepolgeni18n.py +diff --git selinux-python-2.9-rc1/sepolgen/src/sepolgen/sepolgeni18n.py selinux-python-2.9-rc1/sepolgen/src/sepolgen/sepolgeni18n.py index 998c435..56ebd80 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/sepolgeni18n.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/sepolgeni18n.py +--- selinux-python-2.9-rc1/sepolgen/src/sepolgen/sepolgeni18n.py ++++ selinux-python-2.9-rc1/sepolgen/src/sepolgen/sepolgeni18n.py @@ -19,7 +19,7 @@ try: @@ -1787,553 +295,10 @@ index 998c435..56ebd80 100644 _ = t.gettext except: def _(str): -diff --git selinux-python-2.8/sepolgen/src/sepolgen/util.py selinux-python-2.8/sepolgen/src/sepolgen/util.py -index 1fca971..b3d2616 100644 ---- selinux-python-2.8/sepolgen/src/sepolgen/util.py -+++ selinux-python-2.8/sepolgen/src/sepolgen/util.py -@@ -125,7 +125,7 @@ class Comparison(): - _compare function within your class.""" - - def _compare(self, other, method): -- raise NotImplemented -+ return NotImplemented - - def __eq__(self, other): - return self._compare(other, lambda a, b: a == b) -diff --git selinux-python-2.8/sepolgen/tests/test_access.py selinux-python-2.8/sepolgen/tests/test_access.py -index d45a823..73a5407 100644 ---- selinux-python-2.8/sepolgen/tests/test_access.py -+++ selinux-python-2.8/sepolgen/tests/test_access.py -@@ -32,6 +32,7 @@ class TestAccessVector(unittest.TestCase): - self.assertEqual(a.obj_class, None) - self.assertTrue(isinstance(a.perms, refpolicy.IdSet)) - self.assertTrue(isinstance(a.audit_msgs, type([]))) -+ self.assertTrue(isinstance(a.xperms, type({}))) - self.assertEqual(len(a.audit_msgs), 0) - - # Construction from a list -@@ -61,6 +62,10 @@ class TestAccessVector(unittest.TestCase): - self.assertEqual(a.obj_class, l.obj_class) - self.assertEqual(a.perms, l.perms) - -+ l2 = access.AccessVector() -+ with self.assertRaises(ValueError): -+ l2.from_list(['foo', 'bar', 'file']) -+ - def test_to_list(self): - a = access.AccessVector() - a.src_type = "foo" -@@ -145,7 +150,80 @@ class TestAccessVector(unittest.TestCase): - - b.perms = refpolicy.IdSet(["read", "append"]) - self.assertNotEqual(a, b) -+ -+ def test_merge_noxperm(self): -+ """Test merging two AVs without xperms""" -+ a = access.AccessVector(["foo", "bar", "file", "read", "write"]) -+ b = access.AccessVector(["foo", "bar", "file", "append"]) -+ -+ a.merge(b) -+ self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) -+ -+ def text_merge_xperm1(self): -+ """Test merging AV that contains xperms with AV that does not""" -+ a = access.AccessVector(["foo", "bar", "file", "read"]) -+ b = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp = refpolicy.XpermSet() -+ xp.add(42) -+ xp.add(12345) -+ b.xperms = {"ioctl": xp} -+ -+ a.merge(b) -+ self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) -+ self.assertEqual(list(a.xperms.keys()), ["ioctl"]) -+ self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") -+ -+ def text_merge_xperm2(self): -+ """Test merging AV that does not contain xperms with AV that does""" -+ a = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp = refpolicy.XpermSet() -+ xp.add(42) -+ xp.add(12345) -+ a.xperms = {"ioctl": xp} -+ b = access.AccessVector(["foo", "bar", "file", "read"]) -+ -+ a.merge(b) -+ self.assertEqual(sorted(list(a.perms)), ["append", "read", "write"]) -+ self.assertEqual(list(a.xperms.keys()), ["ioctl"]) -+ self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") -+ -+ def test_merge_xperm_diff_op(self): -+ """Test merging two AVs that contain xperms with different operation""" -+ a = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp1 = refpolicy.XpermSet() -+ xp1.add(23) -+ a.xperms = {"asdf": xp1} -+ -+ b = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp2 = refpolicy.XpermSet() -+ xp2.add(42) -+ xp2.add(12345) -+ b.xperms = {"ioctl": xp2} -+ -+ a.merge(b) -+ self.assertEqual(list(a.perms), ["read"]) -+ self.assertEqual(sorted(list(a.xperms.keys())), ["asdf", "ioctl"]) -+ self.assertEqual(a.xperms["asdf"].to_string(), "23") -+ self.assertEqual(a.xperms["ioctl"].to_string(), "{ 42 12345 }") - -+ def test_merge_xperm_same_op(self): -+ """Test merging two AVs that contain xperms with same operation""" -+ a = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp1 = refpolicy.XpermSet() -+ xp1.add(23) -+ a.xperms = {"ioctl": xp1} -+ -+ b = access.AccessVector(["foo", "bar", "file", "read"]) -+ xp2 = refpolicy.XpermSet() -+ xp2.add(42) -+ xp2.add(12345) -+ b.xperms = {"ioctl": xp2} -+ -+ a.merge(b) -+ self.assertEqual(list(a.perms), ["read"]) -+ self.assertEqual(list(a.xperms.keys()), ["ioctl"]) -+ self.assertEqual(a.xperms["ioctl"].to_string(), "{ 23 42 12345 }") -+ - class TestUtilFunctions(unittest.TestCase): - def test_is_idparam(self): - self.assertTrue(access.is_idparam("$1")) -@@ -260,3 +338,53 @@ class TestAccessVectorSet(unittest.TestCase): - b = access.AccessVectorSet() - b.from_list(avl) - self.assertEqual(len(b), 3) -+ -+ def test_add_av_first(self): -+ """Test adding first AV to the AV set""" -+ avs = access.AccessVectorSet() -+ av = access.AccessVector(['foo', 'bar', 'file', 'read']) -+ -+ avs.add_av(av) -+ -+ self.assertEqual(avs.to_list(), [['foo', 'bar', 'file', 'read']]) -+ -+ def test_add_av_second(self): -+ """Test adding second AV to the AV set with same source and target -+ context and class""" -+ avs = access.AccessVectorSet() -+ av1 = access.AccessVector(['foo', 'bar', 'file', 'read']) -+ av2 = access.AccessVector(['foo', 'bar', 'file', 'write']) -+ -+ avs.add_av(av1) -+ avs.add_av(av2) -+ -+ self.assertEqual(avs.to_list(), [['foo', 'bar', 'file', 'read', -+ 'write']]) -+ -+ def test_add_av_with_msg(self): -+ """Test adding audit message""" -+ avs = access.AccessVectorSet() -+ av = access.AccessVector(['foo', 'bar', 'file', 'read']) -+ -+ avs.add_av(av, 'test message') -+ -+ self.assertEqual(avs.src['foo']['bar']['file', av.type].audit_msgs, -+ ['test message']) -+ -+ def test_add(self): -+ """Test adding AV to the set""" -+ s = access.AccessVectorSet() -+ -+ def test_add_av(av, audit_msg=None): -+ self.assertEqual(av.src_type, 'foo') -+ self.assertEqual(av.tgt_type, 'bar') -+ self.assertEqual(av.obj_class, 'file') -+ self.assertEqual(list(av.perms), ['read']) -+ self.assertEqual(av.data, 'test data') -+ self.assertEqual(av.type, 42) -+ self.assertEqual(audit_msg, 'test message') -+ -+ s.add_av = test_add_av -+ -+ s.add("foo", "bar", "file", refpolicy.IdSet(["read"]), -+ audit_msg='test message', avc_type=42, data='test data') -diff --git selinux-python-2.8/sepolgen/tests/test_audit.py selinux-python-2.8/sepolgen/tests/test_audit.py -index 6379954..dbe6be2 100644 ---- selinux-python-2.8/sepolgen/tests/test_audit.py -+++ selinux-python-2.8/sepolgen/tests/test_audit.py -@@ -56,6 +56,18 @@ type=SYSCALL msg=audit(1162852201.019:1225): arch=40000003 syscall=11 success=ye - type=AVC msg=audit(1162852201.019:1225): avc: denied { execute_no_trans } for pid=6974 comm="sh" name="sa1" dev=dm-0 ino=13061698 scontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lib_t:s0 tclass=file - type=AVC msg=audit(1162852201.019:1225): avc: denied { execute } for pid=6974 comm="sh" name="sa1" dev=dm-0 ino=13061698 scontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lib_t:s0 tclass=file""" - -+xperms1 = """type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 ioctlcmd=0x42 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+""" -+xperms2 = """type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 ioctlcmd=0x42 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 ioctlcmd=0x1234 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 ioctlcmd=0xdead scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+type=AVC msg=audit(1516626657.910:4461): avc: denied { getattr } for pid=4310 comm="test" path="/root/test" ino=8619937 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=dir permissive=0 -+""" -+xperms_invalid = """type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 ioctlcmd=asdf scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+""" -+xperms_without = """type=AVC msg=audit(1516626657.910:4461): avc: denied { ioctl } for pid=4310 comm="test" path="/root/test" ino=8619937 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:test_file_t:s0 tclass=file permissive=0 -+""" -+ - class TestAVCMessage(unittest.TestCase): - def test_defs(self): - avc = sepolgen.audit.AVCMessage(audit1) -@@ -64,6 +76,7 @@ class TestAVCMessage(unittest.TestCase): - self.assertEqual(avc.tcontext, sc) - self.assertEqual(avc.tclass, "") - self.assertEqual(avc.accesses, []) -+ self.assertEqual(avc.ioctlcmd, None) - - def test_granted(self): - avc = sepolgen.audit.AVCMessage(granted1) -@@ -84,6 +97,29 @@ class TestAVCMessage(unittest.TestCase): - - self.assertEqual(avc.denial, False) - -+ def test_xperms(self): -+ """Test that the ioctlcmd field is parsed""" -+ avc = sepolgen.audit.AVCMessage(xperms1) -+ recs = xperms1.split() -+ avc.from_split_string(recs) -+ -+ self.assertEqual(avc.ioctlcmd, 66) -+ -+ def test_xperms_invalid(self): -+ """Test message with invalid value in the ioctlcmd field""" -+ avc = sepolgen.audit.AVCMessage(xperms_invalid) -+ recs = xperms_invalid.split() -+ avc.from_split_string(recs) -+ -+ self.assertIsNone(avc.ioctlcmd) -+ -+ def test_xperms_without(self): -+ """Test message without the ioctlcmd field""" -+ avc = sepolgen.audit.AVCMessage(xperms_without) -+ recs = xperms_without.split() -+ avc.from_split_string(recs) -+ -+ self.assertIsNone(avc.ioctlcmd) - - def test_from_split_string(self): - # syslog message -@@ -172,6 +208,20 @@ class TestAuditParser(unittest.TestCase): - self.assertEqual(len(a.invalid_msgs), 0) - self.assertEqual(len(a.policy_load_msgs), 0) - -+ def test_parse_xperms(self): -+ """ Test that correct access vectors are generated from a set of AVC -+ denial messages. """ -+ a = sepolgen.audit.AuditParser() -+ a.parse_string(xperms2) -+ av_set = a.to_access() -+ -+ self.assertEqual(len(av_set), 2) -+ av_list = list(sorted(av_set)) -+ self.assertEqual(av_list[0].xperms, {}) -+ self.assertEqual(list(av_list[1].xperms), ["ioctl"]) -+ self.assertEqual(av_list[1].xperms["ioctl"].ranges, [(66,66), -+ (4660,4660), (57005,57005)]) -+ - class TestGeneration(unittest.TestCase): - def test_generation(self): - parser = sepolgen.audit.AuditParser() -diff --git selinux-python-2.8/sepolgen/tests/test_policygen.py selinux-python-2.8/sepolgen/tests/test_policygen.py -index 58d1adf..59496e8 100644 ---- selinux-python-2.8/sepolgen/tests/test_policygen.py -+++ selinux-python-2.8/sepolgen/tests/test_policygen.py -@@ -19,13 +19,117 @@ - - import unittest - import sepolgen.policygen as policygen -+import sepolgen.access as access -+import sepolgen.refpolicy as refpolicy - --class PolicyGenerator(unittest.TestCase): -- def __init__(self): -- g = policygen.PolicyGenerator() -- -+class TestPolicyGenerator(unittest.TestCase): -+ def setUp(self): -+ self.g = policygen.PolicyGenerator() - -+ def test_init(self): -+ """ Test that extended permission AV rules are not generated by -+ default. """ -+ self.assertFalse(self.g.xperms) - -+ def test_set_gen_xperms(self): -+ """ Test turning on and off generating of extended permission -+ AV rules. """ -+ self.g.set_gen_xperms(True) -+ self.assertTrue(self.g.xperms) -+ self.g.set_gen_xperms(False) -+ self.assertFalse(self.g.xperms) - -+ def test_av_rules(self): -+ """ Test generating of AV rules from access vectors. """ -+ av1 = access.AccessVector(["test_src_t", "test_tgt_t", "file", "ioctl"]) -+ av2 = access.AccessVector(["test_src_t", "test_tgt_t", "file", "open"]) -+ av3 = access.AccessVector(["test_src_t", "test_tgt_t", "file", "read"]) - -+ avs = access.AccessVectorSet() -+ avs.add_av(av1) -+ avs.add_av(av2) -+ avs.add_av(av3) -+ -+ self.g.add_access(avs) -+ -+ self.assertEqual(len(self.g.module.children), 1) -+ r = self.g.module.children[0] -+ self.assertIsInstance(r, refpolicy.AVRule) -+ self.assertEqual(r.to_string(), -+ "allow test_src_t test_tgt_t:file { ioctl open read };") -+ -+ def test_ext_av_rules(self): -+ """ Test generating of extended permission AV rules from access -+ vectors. """ -+ self.g.set_gen_xperms(True) -+ -+ av1 = access.AccessVector(["test_src_t", "test_tgt_t", "file", "ioctl"]) -+ av1.xperms['ioctl'] = refpolicy.XpermSet() -+ av1.xperms['ioctl'].add(42) -+ av2 = access.AccessVector(["test_src_t", "test_tgt_t", "file", "ioctl"]) -+ av2.xperms['ioctl'] = refpolicy.XpermSet() -+ av2.xperms['ioctl'].add(1234) -+ av3 = access.AccessVector(["test_src_t", "test_tgt_t", "dir", "ioctl"]) -+ av3.xperms['ioctl'] = refpolicy.XpermSet() -+ av3.xperms['ioctl'].add(2345) -+ -+ avs = access.AccessVectorSet() -+ avs.add_av(av1) -+ avs.add_av(av2) -+ avs.add_av(av3) -+ -+ self.g.add_access(avs) -+ -+ self.assertEqual(len(self.g.module.children), 4) -+ -+ # we cannot sort the rules, so find all rules manually -+ av_rule1 = av_rule2 = av_ext_rule1 = av_ext_rule2 = None -+ -+ for r in self.g.module.children: -+ if isinstance(r, refpolicy.AVRule): -+ if 'file' in r.obj_classes: -+ av_rule1 = r -+ else: -+ av_rule2 = r -+ elif isinstance(r, refpolicy.AVExtRule): -+ if 'file' in r.obj_classes: -+ av_ext_rule1 = r -+ else: -+ av_ext_rule2 = r -+ else: -+ self.fail("Unexpected rule type '%s'" % type(r)) -+ -+ # check that all rules are present -+ self.assertNotIn(None, (av_rule1, av_rule2, av_ext_rule1, av_ext_rule2)) -+ -+ self.assertEqual(av_rule1.rule_type, av_rule1.ALLOW) -+ self.assertEqual(av_rule1.src_types, {"test_src_t"}) -+ self.assertEqual(av_rule1.tgt_types, {"test_tgt_t"}) -+ self.assertEqual(av_rule1.obj_classes, {"file"}) -+ self.assertEqual(av_rule1.perms, {"ioctl"}) -+ -+ self.assertEqual(av_ext_rule1.rule_type, av_ext_rule1.ALLOWXPERM) -+ self.assertEqual(av_ext_rule1.src_types, {"test_src_t"}) -+ self.assertEqual(av_ext_rule1.tgt_types, {"test_tgt_t"}) -+ self.assertEqual(av_ext_rule1.obj_classes, {"file"}) -+ self.assertEqual(av_ext_rule1.operation, "ioctl") -+ xp1 = refpolicy.XpermSet() -+ xp1.add(42) -+ xp1.add(1234) -+ self.assertEqual(av_ext_rule1.xperms.ranges, xp1.ranges) -+ -+ self.assertEqual(av_rule2.rule_type, av_rule2.ALLOW) -+ self.assertEqual(av_rule2.src_types, {"test_src_t"}) -+ self.assertEqual(av_rule2.tgt_types, {"test_tgt_t"}) -+ self.assertEqual(av_rule2.obj_classes, {"dir"}) -+ self.assertEqual(av_rule2.perms, {"ioctl"}) -+ -+ self.assertEqual(av_ext_rule2.rule_type, av_ext_rule2.ALLOWXPERM) -+ self.assertEqual(av_ext_rule2.src_types, {"test_src_t"}) -+ self.assertEqual(av_ext_rule2.tgt_types, {"test_tgt_t"}) -+ self.assertEqual(av_ext_rule2.obj_classes, {"dir"}) -+ self.assertEqual(av_ext_rule2.operation, "ioctl") -+ xp2 = refpolicy.XpermSet() -+ xp2.add(2345) -+ self.assertEqual(av_ext_rule2.xperms.ranges, xp2.ranges) - -diff --git selinux-python-2.8/sepolgen/tests/test_refpolicy.py selinux-python-2.8/sepolgen/tests/test_refpolicy.py -index 16e6680..64c48df 100644 ---- selinux-python-2.8/sepolgen/tests/test_refpolicy.py -+++ selinux-python-2.8/sepolgen/tests/test_refpolicy.py -@@ -19,6 +19,7 @@ - - import unittest - import sepolgen.refpolicy as refpolicy -+import sepolgen.access as access - import selinux - - class TestIdSet(unittest.TestCase): -@@ -33,6 +34,74 @@ class TestIdSet(unittest.TestCase): - s.add("read") - self.assertEqual(s.to_space_str(), "read") - -+class TestXpermSet(unittest.TestCase): -+ def test_init(self): -+ """ Test that all atttributes are correctly initialized. """ -+ s1 = refpolicy.XpermSet() -+ self.assertEqual(s1.complement, False) -+ self.assertEqual(s1.ranges, []) -+ -+ s2 = refpolicy.XpermSet(True) -+ self.assertEqual(s2.complement, True) -+ self.assertEqual(s2.ranges, []) -+ -+ def test_normalize_ranges(self): -+ """ Test that ranges that are overlapping or neighboring are correctly -+ merged into one range. """ -+ s = refpolicy.XpermSet() -+ s.ranges = [(1, 7), (5, 10), (100, 110), (102, 107), (200, 205), -+ (205, 210), (300, 305), (306, 310), (400, 405), (407, 410), -+ (500, 502), (504, 508), (500, 510)] -+ s._XpermSet__normalize_ranges() -+ -+ i = 0 -+ r = list(sorted(s.ranges)) -+ while i < len(r) - 1: -+ # check that range low bound is less than equal than the upper bound -+ self.assertLessEqual(r[i][0], r[i][1]) -+ # check that two ranges are not overlapping or neighboring -+ self.assertGreater(r[i + 1][0] - r[i][1], 1) -+ i += 1 -+ -+ def test_add(self): -+ """ Test adding new values or ranges to the set. """ -+ s = refpolicy.XpermSet() -+ s.add(1, 7) -+ s.add(5, 10) -+ s.add(42) -+ self.assertEqual(s.ranges, [(1,10), (42,42)]) -+ -+ def test_extend(self): -+ """ Test adding ranges from another XpermSet object. """ -+ a = refpolicy.XpermSet() -+ a.add(1, 7) -+ -+ b = refpolicy.XpermSet() -+ b.add(5, 10) -+ -+ a.extend(b) -+ self.assertEqual(a.ranges, [(1,10)]) -+ -+ def test_to_string(self): -+ """ Test printing the values to a string. """ -+ a = refpolicy.XpermSet() -+ a.complement = False -+ self.assertEqual(a.to_string(), "") -+ a.complement = True -+ self.assertEqual(a.to_string(), "") -+ a.add(1234) -+ self.assertEqual(a.to_string(), "~ 1234") -+ a.complement = False -+ self.assertEqual(a.to_string(), "1234") -+ a.add(2345) -+ self.assertEqual(a.to_string(), "{ 1234 2345 }") -+ a.complement = True -+ self.assertEqual(a.to_string(), "~ { 1234 2345 }") -+ a.add(42,64) -+ self.assertEqual(a.to_string(), "~ { 42-64 1234 2345 }") -+ a.complement = False -+ self.assertEqual(a.to_string(), "{ 42-64 1234 2345 }") -+ - class TestSecurityContext(unittest.TestCase): - def test_init(self): - sc = refpolicy.SecurityContext() -@@ -110,6 +179,76 @@ class TestAVRule(unittest.TestCase): - b.sort() - self.assertEqual(a, b) - -+class TestAVExtRule(unittest.TestCase): -+ def test_init(self): -+ """ Test initialization of attributes """ -+ a = refpolicy.AVExtRule() -+ self.assertEqual(a.rule_type, a.ALLOWXPERM) -+ self.assertIsInstance(a.src_types, set) -+ self.assertIsInstance(a.tgt_types, set) -+ self.assertIsInstance(a.obj_classes, set) -+ self.assertIsNone(a.operation) -+ self.assertIsInstance(a.xperms, refpolicy.XpermSet) -+ -+ def test_rule_type_str(self): -+ """ Test strings returned by __rule_type_str() """ -+ a = refpolicy.AVExtRule() -+ self.assertEqual(a._AVExtRule__rule_type_str(), "allowxperm") -+ a.rule_type = a.ALLOWXPERM -+ self.assertEqual(a._AVExtRule__rule_type_str(), "allowxperm") -+ a.rule_type = a.DONTAUDITXPERM -+ self.assertEqual(a._AVExtRule__rule_type_str(), "dontauditxperm") -+ a.rule_type = a.NEVERALLOWXPERM -+ self.assertEqual(a._AVExtRule__rule_type_str(), "neverallowxperm") -+ a.rule_type = a.AUDITALLOWXPERM -+ self.assertEqual(a._AVExtRule__rule_type_str(), "auditallowxperm") -+ a.rule_type = 42 -+ self.assertIsNone(a._AVExtRule__rule_type_str()) -+ -+ def test_from_av(self): -+ """ Test creating the rule from an access vector. """ -+ av = access.AccessVector(["foo", "bar", "file", "ioctl"]) -+ xp = refpolicy.XpermSet() -+ av.xperms = { "ioctl": xp } -+ -+ a = refpolicy.AVExtRule() -+ -+ a.from_av(av, "ioctl") -+ self.assertEqual(a.src_types, {"foo"}) -+ self.assertEqual(a.tgt_types, {"bar"}) -+ self.assertEqual(a.obj_classes, {"file"}) -+ self.assertEqual(a.operation, "ioctl") -+ self.assertIs(a.xperms, xp) -+ -+ def test_from_av_self(self): -+ """ Test creating the rule from an access vector that has same -+ source and target context. """ -+ av = access.AccessVector(["foo", "foo", "file", "ioctl"]) -+ xp = refpolicy.XpermSet() -+ av.xperms = { "ioctl": xp } -+ -+ a = refpolicy.AVExtRule() -+ -+ a.from_av(av, "ioctl") -+ self.assertEqual(a.src_types, {"foo"}) -+ self.assertEqual(a.tgt_types, {"self"}) -+ self.assertEqual(a.obj_classes, {"file"}) -+ self.assertEqual(a.operation, "ioctl") -+ self.assertIs(a.xperms, xp) -+ -+ def test_to_string(self): -+ """ Test printing the rule to a string. """ -+ a = refpolicy.AVExtRule() -+ a._AVExtRule__rule_type_str = lambda: "first" -+ a.src_types.to_space_str = lambda: "second" -+ a.tgt_types.to_space_str = lambda: "third" -+ a.obj_classes.to_space_str = lambda: "fourth" -+ a.operation = "fifth" -+ a.xperms.to_string = lambda: "seventh" -+ -+ self.assertEqual(a.to_string(), -+ "first second third:fourth fifth seventh;") -+ - class TestTypeRule(unittest.TestCase): - def test_init(self): - a = refpolicy.TypeRule() -diff --git selinux-python-2.8/sepolicy/sepolicy.py selinux-python-2.8/sepolicy/sepolicy.py -index 141f64e..5880176 100755 ---- selinux-python-2.8/sepolicy/sepolicy.py -+++ selinux-python-2.8/sepolicy/sepolicy.py +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy.py selinux-python-2.9-rc1/sepolicy/sepolicy.py +index 8cc7e8c..759f43e 100755 +--- selinux-python-2.9-rc1/sepolicy/sepolicy.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy.py @@ -27,7 +27,7 @@ import selinux import sepolicy from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text @@ -2343,48 +308,10 @@ index 141f64e..5880176 100755 try: import gettext kwargs = {} -@@ -60,8 +60,6 @@ class CheckPath(argparse.Action): - class CheckType(argparse.Action): - - def __call__(self, parser, namespace, values, option_string=None): -- domains = sepolicy.get_all_domains() -- - if isinstance(values, str): - setattr(namespace, self.dest, values) - else: -@@ -103,6 +101,7 @@ class CheckDomain(argparse.Action): - domains = sepolicy.get_all_domains() - - if isinstance(values, str): -+ values = sepolicy.get_real_type_name(values) - if values not in domains: - raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains))) - setattr(namespace, self.dest, values) -@@ -112,6 +111,7 @@ class CheckDomain(argparse.Action): - newval = [] - - for v in values: -+ v = sepolicy.get_real_type_name(v) - if v not in domains: - raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(domains))) - newval.append(v) -@@ -167,10 +167,11 @@ class CheckPortType(argparse.Action): - if not newval: - newval = [] - for v in values: -+ v = sepolicy.get_real_type_name(v) - if v not in port_types: - raise ValueError("%s must be an SELinux port type:\nValid port types: %s" % (v, ", ".join(port_types))) - newval.append(v) -- setattr(namespace, self.dest, values) -+ setattr(namespace, self.dest, newval) - - - class LoadPolicy(argparse.Action): -diff --git selinux-python-2.8/sepolicy/sepolicy/__init__.py selinux-python-2.8/sepolicy/sepolicy/__init__.py -index 89346ab..1b116f6 100644 ---- selinux-python-2.8/sepolicy/sepolicy/__init__.py -+++ selinux-python-2.8/sepolicy/sepolicy/__init__.py +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy/__init__.py selinux-python-2.9-rc1/sepolicy/sepolicy/__init__.py +index 6f72947..1b116f6 100644 +--- selinux-python-2.9-rc1/sepolicy/sepolicy/__init__.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy/__init__.py @@ -15,7 +15,7 @@ import os import re import gzip @@ -2394,167 +321,7 @@ index 89346ab..1b116f6 100644 try: import gettext kwargs = {} -@@ -119,16 +119,34 @@ all_allow_rules = None - all_transitions = None - - -+def policy_sortkey(policy_path): -+ # Parse the extension of a policy path which looks like .../policy/policy.31 -+ extension = policy_path.rsplit('/policy.', 1)[1] -+ try: -+ return int(extension), policy_path -+ except ValueError: -+ # Fallback with sorting on the full path -+ return 0, policy_path -+ - def get_installed_policy(root="/"): - try: - path = root + selinux.selinux_binary_policy_path() - policies = glob.glob("%s.*" % path) -- policies.sort() -+ policies.sort(key=policy_sortkey) - return policies[-1] - except: - pass - raise ValueError(_("No SELinux Policy installed")) - -+def get_store_policy(store): -+ """Get the path to the policy file located in the given store name""" -+ policies = glob.glob("%s%s/policy/policy.*" % -+ (selinux.selinux_path(), store)) -+ if not policies: -+ return None -+ # Return the policy with the higher version number -+ policies.sort(key=policy_sortkey) -+ return policies[-1] - - def policy(policy_file): - global all_domains -@@ -156,6 +174,11 @@ def policy(policy_file): - except: - raise ValueError(_("Failed to read %s policy file") % policy_file) - -+def load_store_policy(store): -+ policy_file = get_store_policy(store) -+ if not policy_file: -+ return None -+ policy(policy_file) - - try: - policy_file = get_installed_policy() -@@ -168,15 +191,21 @@ except ValueError as e: - def info(setype, name=None): - if setype == TYPE: - q = setools.TypeQuery(_pol) -- if name: -- q.name = name -+ q.name = name -+ results = list(q.results()) -+ -+ if name and len(results) < 1: -+ # type not found, try alias -+ q.name = None -+ q.alias = name -+ results = list(q.results()) - - return ({ - 'aliases': list(map(str, x.aliases())), - 'name': str(x), - 'permissive': bool(x.ispermissive), - 'attributes': list(map(str, x.attributes())) -- } for x in q.results()) -+ } for x in results) - - elif setype == ROLE: - q = setools.RoleQuery(_pol) -@@ -272,34 +301,38 @@ def _setools_rule_to_dict(rule): - 'class': str(rule.tclass), - } - -+ # Evaluate boolean expression associated with given rule (if there is any) - try: -- enabled = bool(rule.qpol_symbol.is_enabled(rule.policy)) -+ # Get state of all booleans in the conditional expression -+ boolstate = {} -+ for boolean in rule.conditional.booleans: -+ boolstate[str(boolean)] = boolean.state -+ # evaluate if the rule is enabled -+ enabled = rule.conditional.evaluate(**boolstate) == rule.conditional_block - except AttributeError: -+ # non-conditional rules are always enabled - enabled = True - -- if isinstance(rule, setools.policyrep.terule.AVRule): -- d['enabled'] = enabled -+ d['enabled'] = enabled - - try: - d['permlist'] = list(map(str, rule.perms)) -- except setools.policyrep.exception.RuleUseError: -+ except AttributeError: - pass - - try: - d['transtype'] = str(rule.default) -- except setools.policyrep.exception.RuleUseError: -+ except AttributeError: - pass - - try: - d['boolean'] = [(str(rule.conditional), enabled)] -- except (AttributeError, setools.policyrep.exception.RuleNotConditional): -+ except AttributeError: - pass - - try: - d['filename'] = rule.filename -- except (AttributeError, -- setools.policyrep.exception.RuleNotConditional, -- setools.policyrep.exception.TERuleNoFilename): -+ except AttributeError: - pass - - return d -@@ -334,6 +367,8 @@ def search(types, seinfo=None): - tertypes.append(NEVERALLOW) - if AUDITALLOW in types: - tertypes.append(AUDITALLOW) -+ if DONTAUDIT in types: -+ tertypes.append(DONTAUDIT) - - if len(tertypes) > 0: - q = setools.TERuleQuery(_pol, -@@ -437,6 +472,20 @@ def get_file_types(setype): - return mpaths - - -+def get_real_type_name(name): -+ """Return the real name of a type -+ -+ * If 'name' refers to a type alias, return the corresponding type name. -+ * Otherwise return the original name (even if the type does not exist). -+ """ -+ if not name: -+ return name -+ -+ try: -+ return next(info(TYPE, name))["name"] -+ except (RuntimeError, StopIteration): -+ return name -+ - def get_writable_files(setype): - file_types = get_all_file_types() - all_writes = [] -@@ -1048,6 +1097,8 @@ def _dict_has_perms(dict, perms): - def gen_short_name(setype): - all_domains = get_all_domains() - if setype.endswith("_t"): -+ # replace aliases with corresponding types -+ setype = get_real_type_name(setype) - domainname = setype[:-2] - else: - domainname = setype -@@ -1160,27 +1211,14 @@ def boolean_desc(boolean): +@@ -1211,27 +1211,14 @@ def boolean_desc(boolean): def get_os_version(): @@ -2588,11 +355,11 @@ index 89346ab..1b116f6 100644 def reinit(): -diff --git selinux-python-2.8/sepolicy/sepolicy/generate.py selinux-python-2.8/sepolicy/sepolicy/generate.py -index f814e27..8e53033 100644 ---- selinux-python-2.8/sepolicy/sepolicy/generate.py -+++ selinux-python-2.8/sepolicy/sepolicy/generate.py -@@ -52,7 +52,7 @@ import sepolgen.defaults as defaults +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy/generate.py selinux-python-2.9-rc1/sepolicy/sepolicy/generate.py +index 37ddfc7..a25a749 100644 +--- selinux-python-2.9-rc1/sepolicy/sepolicy/generate.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy/generate.py +@@ -51,7 +51,7 @@ import sepolgen.defaults as defaults ## ## I18N ## @@ -2601,7 +368,7 @@ index f814e27..8e53033 100644 try: import gettext kwargs = {} -@@ -103,7 +103,9 @@ def get_all_ports(): +@@ -102,7 +102,9 @@ def get_all_ports(): for p in sepolicy.info(sepolicy.PORT): if p['type'] == "reserved_port_t" or \ p['type'] == "port_t" or \ @@ -2612,10 +379,10 @@ index f814e27..8e53033 100644 continue dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p.get('range')) return dict -diff --git selinux-python-2.8/sepolicy/sepolicy/gui.py selinux-python-2.8/sepolicy/sepolicy/gui.py -index 537d516..1e3c3f3 100644 ---- selinux-python-2.8/sepolicy/sepolicy/gui.py -+++ selinux-python-2.8/sepolicy/sepolicy/gui.py +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy/gui.py selinux-python-2.9-rc1/sepolicy/sepolicy/gui.py +index fde233a..fe9e630 100644 +--- selinux-python-2.9-rc1/sepolicy/sepolicy/gui.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy/gui.py @@ -43,7 +43,7 @@ import os import re import unicodedata @@ -2625,18 +392,10 @@ index 537d516..1e3c3f3 100644 try: import gettext kwargs = {} -@@ -149,6 +149,7 @@ class SELinuxGui(): - self.clear_entry = True - self.files_add = False - self.network_add = False -+ self.mislabeled_files = False - - self.all_domains = [] - self.installed_list = [] -diff --git selinux-python-2.8/sepolicy/sepolicy/interface.py selinux-python-2.8/sepolicy/sepolicy/interface.py +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy/interface.py selinux-python-2.9-rc1/sepolicy/sepolicy/interface.py index 18374dc..ca0122d 100644 ---- selinux-python-2.8/sepolicy/sepolicy/interface.py -+++ selinux-python-2.8/sepolicy/sepolicy/interface.py +--- selinux-python-2.9-rc1/sepolicy/sepolicy/interface.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy/interface.py @@ -32,7 +32,7 @@ __all__ = ['get_all_interfaces', 'get_interfaces_from_xml', 'get_admin', 'get_us ## ## I18N @@ -2646,10 +405,10 @@ index 18374dc..ca0122d 100644 try: import gettext kwargs = {} -diff --git selinux-python-2.8/sepolicy/sepolicy/manpage.py selinux-python-2.8/sepolicy/sepolicy/manpage.py -index ed8cb71..8121e5c 100755 ---- selinux-python-2.8/sepolicy/sepolicy/manpage.py -+++ selinux-python-2.8/sepolicy/sepolicy/manpage.py +diff --git selinux-python-2.9-rc1/sepolicy/sepolicy/manpage.py selinux-python-2.9-rc1/sepolicy/sepolicy/manpage.py +index cfcb7c3..2cb3c7e 100755 +--- selinux-python-2.9-rc1/sepolicy/sepolicy/manpage.py ++++ selinux-python-2.9-rc1/sepolicy/sepolicy/manpage.py @@ -126,8 +126,33 @@ def gen_domains(): domains.sort() return domains diff --git a/selinux-sandbox-fedora.patch b/selinux-sandbox-fedora.patch index 4986b98..dd72984 100644 --- a/selinux-sandbox-fedora.patch +++ b/selinux-sandbox-fedora.patch @@ -1,7 +1,7 @@ -diff --git selinux-sandbox-2.8/Makefile selinux-sandbox-2.8/Makefile +diff --git selinux-sandbox-2.9-rc1/Makefile selinux-sandbox-2.9-rc1/Makefile index 49c1d3f..9e45329 100644 ---- selinux-sandbox-2.8/Makefile -+++ selinux-sandbox-2.8/Makefile +--- selinux-sandbox-2.9-rc1/Makefile ++++ selinux-sandbox-2.9-rc1/Makefile @@ -12,6 +12,7 @@ override LDLIBS += -lselinux -lcap-ng SEUNSHARE_OBJS = seunshare.o @@ -18,11 +18,11 @@ index 49c1d3f..9e45329 100644 test: @$(PYTHON) test_sandbox.py -v -diff --git selinux-sandbox-2.8/po/Makefile selinux-sandbox-2.8/po/Makefile +diff --git selinux-sandbox-2.9-rc1/po/Makefile selinux-sandbox-2.9-rc1/po/Makefile new file mode 100644 index 0000000..0556bbe --- /dev/null -+++ selinux-sandbox-2.8/po/Makefile ++++ selinux-sandbox-2.9-rc1/po/Makefile @@ -0,0 +1,82 @@ +# +# Makefile for the PO files (translation) catalog @@ -106,17 +106,17 @@ index 0000000..0556bbe +.PHONY: missing depend + +relabel: -diff --git selinux-sandbox-2.8/po/POTFILES selinux-sandbox-2.8/po/POTFILES +diff --git selinux-sandbox-2.9-rc1/po/POTFILES selinux-sandbox-2.9-rc1/po/POTFILES new file mode 100644 index 0000000..deff3f2 --- /dev/null -+++ selinux-sandbox-2.8/po/POTFILES ++++ selinux-sandbox-2.9-rc1/po/POTFILES @@ -0,0 +1 @@ +../sandbox -diff --git selinux-sandbox-2.8/sandbox selinux-sandbox-2.8/sandbox +diff --git selinux-sandbox-2.9-rc1/sandbox selinux-sandbox-2.9-rc1/sandbox index c07a1d8..948496d 100644 ---- selinux-sandbox-2.8/sandbox -+++ selinux-sandbox-2.8/sandbox +--- selinux-sandbox-2.9-rc1/sandbox ++++ selinux-sandbox-2.9-rc1/sandbox @@ -37,7 +37,7 @@ import sepolicy SEUNSHARE = "/usr/sbin/seunshare" @@ -144,10 +144,10 @@ index c07a1d8..948496d 100644 help=_("alternate window manager")) parser.add_option("-l", "--level", dest="level", -diff --git selinux-sandbox-2.8/sandbox.8 selinux-sandbox-2.8/sandbox.8 +diff --git selinux-sandbox-2.9-rc1/sandbox.8 selinux-sandbox-2.9-rc1/sandbox.8 index d83fee7..90ef495 100644 ---- selinux-sandbox-2.8/sandbox.8 -+++ selinux-sandbox-2.8/sandbox.8 +--- selinux-sandbox-2.9-rc1/sandbox.8 ++++ selinux-sandbox-2.9-rc1/sandbox.8 @@ -77,7 +77,7 @@ Specifies the windowsize when creating an X based Sandbox. The default windowsiz \fB\-W\fR \fB\-\-windowmanager\fR Select alternative window manager to run within @@ -157,10 +157,10 @@ index d83fee7..90ef495 100644 .TP \fB\-X\fR Create an X based Sandbox for gui apps, temporary files for -diff --git selinux-sandbox-2.8/sandboxX.sh selinux-sandbox-2.8/sandboxX.sh +diff --git selinux-sandbox-2.9-rc1/sandboxX.sh selinux-sandbox-2.9-rc1/sandboxX.sh index eaa500d..c211ebc 100644 ---- selinux-sandbox-2.8/sandboxX.sh -+++ selinux-sandbox-2.8/sandboxX.sh +--- selinux-sandbox-2.9-rc1/sandboxX.sh ++++ selinux-sandbox-2.9-rc1/sandboxX.sh @@ -6,21 +6,7 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8 [ -z $2 ] && export DPI="96" || export DPI="$2" trap "exit 0" HUP diff --git a/semodule-utils-fedora.patch b/semodule-utils-fedora.patch index cde0b2d..324cec0 100644 --- a/semodule-utils-fedora.patch +++ b/semodule-utils-fedora.patch @@ -1,7 +1,7 @@ -diff --git semodule-utils-2.8/semodule_package/semodule_package.c semodule-utils-2.8/semodule_package/semodule_package.c +diff --git semodule-utils-2.9-rc1/semodule_package/semodule_package.c semodule-utils-2.9-rc1/semodule_package/semodule_package.c index 3515234..7b75b3f 100644 ---- semodule-utils-2.8/semodule_package/semodule_package.c -+++ semodule-utils-2.8/semodule_package/semodule_package.c +--- semodule-utils-2.9-rc1/semodule_package/semodule_package.c ++++ semodule-utils-2.9-rc1/semodule_package/semodule_package.c @@ -74,6 +74,7 @@ static int file_to_data(const char *path, char **data, size_t * len) } if (!sb.st_size) { diff --git a/sources b/sources index 71ca0ec..cfc1042 100644 --- a/sources +++ b/sources @@ -1,11 +1,11 @@ +SHA512 (policycoreutils-2.9-rc1.tar.gz) = 6a3a7d4652b44e54c287b327ad691dd0575c6a45fbf1f4676b8182e05760defc37dfa6aaf2e6ab5a77e124d76d1f699c4859c0595a3f9e8ade04ff5ad186fb32 +SHA512 (selinux-python-2.9-rc1.tar.gz) = afd7686ed21c55aa3fc45934d252da1a7d8a44651ef210bf54d4feeedcb72b9092be2d3becc9ff9c8caba53088d33ad97824e0655e04a47c122b45ea6c3e6455 +SHA512 (selinux-gui-2.9-rc1.tar.gz) = 611e3a2cf55c5def9ec60a1ffd59ab30c3c394a8bf20fa6c83b84af5672813c435b3469c8490ff5f75a5ae75fec9ac3014c0aacb4a9fadecc90f683fb61e5722 +SHA512 (selinux-sandbox-2.9-rc1.tar.gz) = 324b0448aa2656e401f2aeebb162626844f5b43f65c305e05c64284964d18ee4e38e98bb9e767e7f4fbf405fd8475fa70a9c5aa0c60d43880036adea0c146779 +SHA512 (selinux-dbus-2.9-rc1.tar.gz) = f20357788250fe3e6ad3985d093877abdc09deda485a0a69f6563f6540c28c7ad61402bde09f53086d1f73fdc174c959bae50a223962eea3ffa6f4db09cdcec4 +SHA512 (semodule-utils-2.9-rc1.tar.gz) = 2e03dd8c23ad1b2f2492194ccd4a6fc39d4ee2d513778264b794011121c3b6eb896dab4a2236cf3934d1e200ad1f86ba6223bb6ac7aa81b1fd4c2a700dc7081a +SHA512 (restorecond-2.9-rc1.tar.gz) = 6d0b0e3e36dfe567cf5349801078bc6ff9c6a7e7f2afc13f7ae775c9ae1d74fddfce14f3c83933f386e110ae5b4836c633d8307c9c4bce2000a3230bfcdb64eb SHA512 (policycoreutils_man_ru2.tar.bz2) = 7272801da169b8d7dd3f8b7e368a63a4fbb7ae94599f9384bc450d142e6b2a3805ab542d650cbe9c8978c2d8e5c56ef4c11f361abfefeaf184ec3a4b0d2afb4c -SHA512 (policycoreutils-2.8.tar.gz) = 2b4a70836fd8727a16b8f8d4afcc39c9461ab6f5bc1ba5ce5833d41150da921ebb3c9bdbd1cfa7dd31fd382ba18b5433ca9b63bce58bd290db81fa9bedfe29f3 -SHA512 (restorecond-2.8.tar.gz) = 5d72336782c3ad095746f8e6fa67e36448e5e76ca29586d8fe4962c64e505fa95c1458e8fc8f7d5bd589fff71b4be3758fb0cee3dacd2ccd0bc8476423e2540e -SHA512 (selinux-dbus-2.8.tar.gz) = 241b308a4754fdc618466fc0f60234c1a80583eaeca22fab96f2d2779ac91ae03437cdfa8320fcfe5f142cdab543f025425c90eded5ff55d06960f55704a99f2 -SHA512 (selinux-gui-2.8.tar.gz) = 616323d0516cda80cdc13b8e66890b2c872695c276587304dd88a0948420011f5967ef46053f769f39863a9a9194f6e203102308c89f938ed66331f37c8a8d25 -SHA512 (selinux-python-2.8.tar.gz) = e695c11122f7f8105b75d1ef98355fd2b82b40d93c2fd9e733dcd95d4d7c392f60b646df81203c43ad2a0e8447f9901083007e1572b78e17368ad2764ffa1aad -SHA512 (selinux-sandbox-2.8.tar.gz) = d86582639d1afc532998c2e94e0cc1fe9f7ce1daaa912a39b1b5dddf52c33965c063abe0cdcbcbe4017d5cbcabe351dcd9861323753dffc755de355b87c821b2 -SHA512 (semodule-utils-2.8.tar.gz) = 13d79a22115f5448dafc5202dc3dec66b9ad826051d61d7c126defe823407959511db35713d97c7dfe9e79de96193fec91a10b98c13743e06a1213f5734f4ae7 SHA512 (gui-po.tgz) = 8b4a2ed5f246ea3d6086e2f8b7df37b0e43318b1a1d4dc5aae7cfa32ee6b4e0a39fc0b8f08ff062fd776d54a4c9b88f641d3109f7d8b5ec11b44383c902fefa5 SHA512 (policycoreutils-po.tgz) = 8dd151bc67345106fec5daae1a133e74202484509357883e21e1eaccb8283098dc153a8f77e2d4dd0e899995eb07dedf0f7fca68507df35593a7f95482a4cb28 SHA512 (python-po.tgz) = c9d88b9523f41b13f53403c0a98fe2fd6ba67afa51d41b56a856340e387eee00d6bd5416cd595a4bf657eaa02797ac3fe25a2a5de17b5f6bb6a2566d14c6c63f