diff --git a/.gitignore b/.gitignore index 8c0ce04..f56ffaf 100644 --- a/.gitignore +++ b/.gitignore @@ -369,3 +369,5 @@ policycoreutils-2.0.83.tgz /selinux-3.9.tar.gz.asc /selinux-3.10.tar.gz /selinux-3.10.tar.gz.asc +/selinux-3.11.tar.gz +/selinux-3.11.tar.gz.asc diff --git a/0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch b/0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch index 0000842..7c75a87 100644 --- a/0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch +++ b/0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch @@ -1,14 +1,15 @@ -From 966537fe43b84f19153592ad946384b80deda37e Mon Sep 17 00:00:00 2001 +From e559f98a6d73a623ff735cab43d45b5c98403970 Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Fri, 14 Feb 2014 12:32:12 -0500 Subject: [PATCH] Don't be verbose if you are not on a tty +Content-type: text/plain --- policycoreutils/scripts/fixfiles | 1 + 1 file changed, 1 insertion(+) diff --git a/policycoreutils/scripts/fixfiles b/policycoreutils/scripts/fixfiles -index b7cd765c..f2518e96 100755 +index b7cd765c15e4..f2518e96e34c 100755 --- a/policycoreutils/scripts/fixfiles +++ b/policycoreutils/scripts/fixfiles @@ -108,6 +108,7 @@ exclude_dirs_from_relabelling() { @@ -20,5 +21,5 @@ index b7cd765c..f2518e96 100755 THREADS="" RPMFILES="" -- -2.52.0 +2.54.0 diff --git a/0002-sepolicy-generate-Handle-more-reserved-port-types.patch b/0002-sepolicy-generate-Handle-more-reserved-port-types.patch index 28c0f59..12678fd 100644 --- a/0002-sepolicy-generate-Handle-more-reserved-port-types.patch +++ b/0002-sepolicy-generate-Handle-more-reserved-port-types.patch @@ -1,7 +1,8 @@ -From 3bdc320b86f6694e3716941899a6fca0aff8f9ae Mon Sep 17 00:00:00 2001 +From 6be99263017c169d0f0bc1ed247e22a696583bad Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Thu, 14 Dec 2017 15:57:58 +0900 Subject: [PATCH] sepolicy-generate: Handle more reserved port types +Content-type: text/plain Currently only reserved_port_t, port_t and hi_reserved_port_t are handled as special when making a ports-dictionary. However, as fas as @@ -52,7 +53,7 @@ https://lore.kernel.org/selinux/20150610.190635.1866127952891120915.yamato@redha 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py -index 780a56b2..cde6a840 100644 +index 0edda54ad5a1..02d9066c8a42 100644 --- a/python/sepolicy/sepolicy/generate.py +++ b/python/sepolicy/sepolicy/generate.py @@ -100,7 +100,9 @@ def get_all_ports(): @@ -67,5 +68,5 @@ index 780a56b2..cde6a840 100644 dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p.get('range')) return dict -- -2.52.0 +2.54.0 diff --git a/0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch b/0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch index f11af14..4842166 100644 --- a/0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch +++ b/0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch @@ -1,7 +1,8 @@ -From d1b75aa6f0cd9c45f025bb619821183446ebfe28 Mon Sep 17 00:00:00 2001 +From 211d44c2e7b629f3ac073147a4c31449bcbe4478 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Wed, 18 Jul 2018 09:09:35 +0200 Subject: [PATCH] sandbox: Use matchbox-window-manager instead of openbox +Content-type: text/plain --- sandbox/sandbox | 4 ++-- @@ -10,10 +11,10 @@ Subject: [PATCH] sandbox: Use matchbox-window-manager instead of openbox 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/sandbox/sandbox b/sandbox/sandbox -index e3fd6119..e01425f0 100644 +index 4e7d56fdedfd..5f79c5367bda 100644 --- a/sandbox/sandbox +++ b/sandbox/sandbox -@@ -270,7 +270,7 @@ class Sandbox: +@@ -266,7 +266,7 @@ class Sandbox: copyfile(f, "/tmp", self.__tmpdir) copyfile(f, "/var/tmp", self.__tmpdir) @@ -22,7 +23,7 @@ index e3fd6119..e01425f0 100644 execfile = self.__homedir + "/.sandboxrc" fd = open(execfile, "w+") if self.__options.session: -@@ -370,7 +370,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [- +@@ -366,7 +366,7 @@ sandbox [-h] [-l level ] [-[X|M] [-H homedir] [-T tempdir]] [-I includefile ] [- parser.add_option("-W", "--windowmanager", dest="wm", type="string", @@ -32,7 +33,7 @@ index e3fd6119..e01425f0 100644 parser.add_option("-l", "--level", dest="level", diff --git a/sandbox/sandbox.8 b/sandbox/sandbox.8 -index 095b9e27..1c187019 100644 +index 095b9e27042d..1c1870190e51 100644 --- a/sandbox/sandbox.8 +++ b/sandbox/sandbox.8 @@ -80,7 +80,7 @@ Specifies the windowsize when creating an X based Sandbox. The default windowsiz @@ -45,7 +46,7 @@ index 095b9e27..1c187019 100644 \fB\-X\fR Create an X based Sandbox for gui apps, temporary files for diff --git a/sandbox/sandboxX.sh b/sandbox/sandboxX.sh -index 28169182..e2a7ad9b 100644 +index 28169182ce42..e2a7ad9b2ac7 100644 --- a/sandbox/sandboxX.sh +++ b/sandbox/sandboxX.sh @@ -7,20 +7,6 @@ export TITLE="Sandbox $context -- `grep ^#TITLE: ~/.sandboxrc | /usr/bin/cut -b8 @@ -70,5 +71,5 @@ index 28169182..e2a7ad9b 100644 if [ -z "$WAYLAND_DISPLAY" ]; then DISPLAY_COMMAND='/usr/bin/Xephyr -resizeable -title "$TITLE" -terminate -screen $SCREENSIZE -dpi $DPI -nolisten tcp -displayfd 5 5>&1 2>/dev/null' -- -2.52.0 +2.54.0 diff --git a/0004-Use-SHA-2-instead-of-SHA-1.patch b/0004-Use-SHA-2-instead-of-SHA-1.patch index 72f56e3..9013a73 100644 --- a/0004-Use-SHA-2-instead-of-SHA-1.patch +++ b/0004-Use-SHA-2-instead-of-SHA-1.patch @@ -1,7 +1,8 @@ -From 74f566f16de93662e022d37d616a2f5f47f27f45 Mon Sep 17 00:00:00 2001 +From cbaf1040c655bd544eedca3b8e070720dfc3b2be Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Fri, 30 Jul 2021 14:14:37 +0200 Subject: [PATCH] Use SHA-2 instead of SHA-1 +Content-type: text/plain The use of SHA-1 in RHEL9 is deprecated --- @@ -12,7 +13,7 @@ The use of SHA-1 in RHEL9 is deprecated 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/policycoreutils/setfiles/restorecon.8 b/policycoreutils/setfiles/restorecon.8 -index b7ff9715..66b9c800 100644 +index b7ff9715a49b..66b9c800dc73 100644 --- a/policycoreutils/setfiles/restorecon.8 +++ b/policycoreutils/setfiles/restorecon.8 @@ -103,14 +103,14 @@ display usage information and exit. @@ -52,7 +53,7 @@ index b7ff9715..66b9c800 100644 and provided the .B \-n diff --git a/policycoreutils/setfiles/restorecon_xattr.8 b/policycoreutils/setfiles/restorecon_xattr.8 -index 51d12a4d..09bfd8c4 100644 +index 51d12a4dbb80..09bfd8c40ab4 100644 --- a/policycoreutils/setfiles/restorecon_xattr.8 +++ b/policycoreutils/setfiles/restorecon_xattr.8 @@ -23,7 +23,7 @@ or @@ -89,7 +90,7 @@ index 51d12a4d..09bfd8c4 100644 .I security.sehash directory digest entries, and is shown for reference only). diff --git a/policycoreutils/setfiles/restorecon_xattr.c b/policycoreutils/setfiles/restorecon_xattr.c -index 31fb82fd..bc22d3fd 100644 +index e8604ec63c29..738319edb4a4 100644 --- a/policycoreutils/setfiles/restorecon_xattr.c +++ b/policycoreutils/setfiles/restorecon_xattr.c @@ -38,7 +38,7 @@ int main(int argc, char **argv) @@ -101,7 +102,7 @@ index 31fb82fd..bc22d3fd 100644 unsigned char *fc_digest = NULL; size_t i, fc_digest_len = 0, num_specfiles; -@@ -133,8 +133,8 @@ int main(int argc, char **argv) +@@ -134,8 +134,8 @@ int main(int argc, char **argv) exit(-1); } @@ -109,9 +110,9 @@ index 31fb82fd..bc22d3fd 100644 - if (!sha1_buf) { + sha256_buf = malloc(fc_digest_len * 2 + 1); + if (!sha256_buf) { - fprintf(stderr, - "Error allocating digest buffer: %s\n", - strerror(errno)); + fprintf(stderr, "Error allocating digest buffer: %s\n", + strerror(errno)); + selabel_close(hnd); @@ -143,16 +143,16 @@ int main(int argc, char **argv) } @@ -133,7 +134,7 @@ index 31fb82fd..bc22d3fd 100644 } diff --git a/policycoreutils/setfiles/setfiles.8 b/policycoreutils/setfiles/setfiles.8 -index d43e4ad2..458f3f9f 100644 +index d43e4ad20f54..458f3f9f1693 100644 --- a/policycoreutils/setfiles/setfiles.8 +++ b/policycoreutils/setfiles/setfiles.8 @@ -105,14 +105,14 @@ display usage information and exit. @@ -173,5 +174,5 @@ index d43e4ad2..458f3f9f 100644 and provided the .B \-n -- -2.52.0 +2.54.0 diff --git a/0005-python-sepolicy-Fix-spec-file-dependencies.patch b/0005-python-sepolicy-Fix-spec-file-dependencies.patch index 3077f2c..5128d5b 100644 --- a/0005-python-sepolicy-Fix-spec-file-dependencies.patch +++ b/0005-python-sepolicy-Fix-spec-file-dependencies.patch @@ -1,7 +1,8 @@ -From 4d7b6cd22b09eec515e73bc26a640d888a222a9c Mon Sep 17 00:00:00 2001 +From 33b90b3f2e7904c37003e525cb0a5459dea3db38 Mon Sep 17 00:00:00 2001 From: Vit Mojzis Date: Tue, 30 May 2023 09:07:28 +0200 Subject: [PATCH] python/sepolicy: Fix spec file dependencies +Content-type: text/plain semanage is part of policycoreutils-python-utils package, selinuxenabled is part of libselinux-utils (required by ^^^) and restorecon/load_policy @@ -13,7 +14,7 @@ Signed-off-by: Vit Mojzis 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/python/sepolicy/sepolicy/templates/spec.py b/python/sepolicy/sepolicy/templates/spec.py -index 433c298a..a6d4508b 100644 +index 433c298a17e0..a6d4508bb670 100644 --- a/python/sepolicy/sepolicy/templates/spec.py +++ b/python/sepolicy/sepolicy/templates/spec.py @@ -11,18 +11,20 @@ Version: 1.0 @@ -43,5 +44,5 @@ index 433c298a..a6d4508b 100644 mid_section="""\ -- -2.52.0 +2.54.0 diff --git a/0006-sepolicy-Fix-detection-of-writeable-locations.patch b/0006-sepolicy-Fix-detection-of-writeable-locations.patch index 502d5a7..1a8cc9c 100644 --- a/0006-sepolicy-Fix-detection-of-writeable-locations.patch +++ b/0006-sepolicy-Fix-detection-of-writeable-locations.patch @@ -1,7 +1,8 @@ -From 7bc3e35c8c8e158e8cba30f7dd42e6a68a8378b3 Mon Sep 17 00:00:00 2001 +From b5d8719fdcaa7a7209bacb6e0d2f57f0f428706d Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Mon, 5 May 2025 18:28:40 +0200 Subject: [PATCH] sepolicy: Fix detection of writeable locations +Content-type: text/plain - update substitutions from /etc/dnf/var @@ -25,17 +26,20 @@ Fixes: Signed-off-by: Petr Lautrbach --- - python/sepolicy/sepolicy/generate.py | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) + python/sepolicy/sepolicy/generate.py | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/python/sepolicy/sepolicy/generate.py b/python/sepolicy/sepolicy/generate.py -index cde6a840..9b360e96 100644 +index 02d9066c8a42..9b360e96c9d1 100644 --- a/python/sepolicy/sepolicy/generate.py +++ b/python/sepolicy/sepolicy/generate.py -@@ -1324,15 +1324,15 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1324,18 +1324,15 @@ allow %s_t %s_t:%s_socket name_%s; import dnf with dnf.Base() as base: +- if base.conf.substitutions.get('releasever') is None: +- base.conf.substitutions['releasever'] = '' +- + base.conf.substitutions.update_from_etc('/') base.read_all_repos() base.fill_sack(load_system_repo=True) @@ -51,7 +55,7 @@ index cde6a840..9b360e96 100644 self.rpms.append(pkg.name) for fname in pkg.files: for b in self.DEFAULT_DIRS: -@@ -1345,7 +1345,7 @@ allow %s_t %s_t:%s_socket name_%s; +@@ -1348,7 +1345,7 @@ allow %s_t %s_t:%s_socket name_%s; self.add_dir(fname) sq = query.available() sq = sq.filter(provides=pkg.source_name) @@ -61,5 +65,5 @@ index cde6a840..9b360e96 100644 for b in self.DEFAULT_DIRS: if b == "/etc": -- -2.52.0 +2.54.0 diff --git a/0007-Revert-libselinux-python-Use-system-Python3-build-mo.patch b/0007-Revert-libselinux-python-Use-system-Python3-build-mo.patch new file mode 100644 index 0000000..631b82f --- /dev/null +++ b/0007-Revert-libselinux-python-Use-system-Python3-build-mo.patch @@ -0,0 +1,27 @@ +From eeb5dbe746492dd4722745c5cf7ba2b46ac0a805 Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Fri, 10 Jul 2026 13:20:24 +0200 +Subject: [PATCH] Revert "libselinux,python: Use system Python3 build module" + +This reverts commit e11e59675f6981e8b7cf990478887c9147b2b20a. + +python3-build is not available in RHEL-10 +--- + python/sepolicy/Makefile | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/python/sepolicy/Makefile b/python/sepolicy/Makefile +index 51812980..4a4a3512 100644 +--- a/python/sepolicy/Makefile ++++ b/python/sepolicy/Makefile +@@ -14,6 +14,7 @@ BASHCOMPLETIONS=sepolicy-bash-completion.sh + all: python-build + + python-build: ++ $(PYTHON) -m pip install build wheel setuptools + $(PYTHON) -m build --no-isolation --wheel . + + clean: +-- +2.53.0 + diff --git a/0007-restorecond-Add-F-for-run-in-foreground.patch b/0007-restorecond-Add-F-for-run-in-foreground.patch deleted file mode 100644 index 09502b8..0000000 --- a/0007-restorecond-Add-F-for-run-in-foreground.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 8f63d68747c38b2d2301afbdaeca88c1cf020552 Mon Sep 17 00:00:00 2001 -From: Petr Lautrbach -Date: Thu, 2 Apr 2026 17:17:12 +0200 -Subject: [PATCH] restorecond: Add -F for run in foreground -Content-type: text/plain - -Signed-off-by: Petr Lautrbach ---- - restorecond/restorecond.8 | 5 ++++- - restorecond/restorecond.c | 13 ++++++++----- - 2 files changed, 12 insertions(+), 6 deletions(-) - -diff --git a/restorecond/restorecond.8 b/restorecond/restorecond.8 -index bf8ec87562f8..bb99b24a2d69 100644 ---- a/restorecond/restorecond.8 -+++ b/restorecond/restorecond.8 -@@ -3,7 +3,7 @@ - restorecond \- daemon that watches for file creation and then sets the default SELinux file context - - .SH "SYNOPSIS" --.B restorecond [\-d] [-h] [\-f restorecond_file ] [\-u] [\-v] -+.B restorecond [\-d] [-h] [\-f restorecond_file ] [\-F] [\-u] [\-v] - .P - - .SH "DESCRIPTION" -@@ -26,6 +26,9 @@ Print usage statement. - .B \-f restorecond_file - Use alternative restorecond.conf file. - .TP -+.B \-F -+Run in foreground, do not become a daemon. -+.TP - .B \-u - Turns on user mode. Runs restorecond in the user session and reads /etc/selinux/restorecond_user.conf. Uses dbus to make sure only one restorecond is running per user session. - .TP -diff --git a/restorecond/restorecond.c b/restorecond/restorecond.c -index d5f70fc2e2c1..36f82ae5e9cb 100644 ---- a/restorecond/restorecond.c -+++ b/restorecond/restorecond.c -@@ -76,6 +76,7 @@ int debug_mode = 0; - int terminate = 0; - int master_wd = -1; - int run_as_user = 0; -+int foreground_mode = 0; - - static void done(void) { - watch_list_free(master_fd); -@@ -124,7 +125,7 @@ static void term_handler(int s __attribute__ ((unused))) - - static void usage(char *program) - { -- printf("%s [-d] [-f restorecond_file ] [-u] [-v] \n", program); -+ printf("%s [-d] [-f restorecond_file ] [-F] [-n] [-u] [-v] \n", program); - } - - void exitApp(const char *msg) -@@ -165,7 +166,7 @@ int main(int argc, char **argv) - sigaction(SIGTERM, &sa, NULL); - - atexit( done ); -- while ((opt = getopt(argc, argv, "hdf:uv")) > 0) { -+ while ((opt = getopt(argc, argv, "hdf:Fuv")) > 0) { - switch (opt) { - case 'd': - debug_mode = 1; -@@ -173,6 +174,9 @@ int main(int argc, char **argv) - case 'f': - watch_file = optarg; - break; -+ case 'F': -+ foreground_mode = 1; -+ break; - case 'u': - run_as_user = 1; - break; -@@ -209,13 +213,12 @@ int main(int argc, char **argv) - - read_config(master_fd, watch_file); - -- if (!debug_mode) { -+ if (!debug_mode && !foreground_mode) { - if (daemon(0, 0) < 0) - exitApp("daemon"); -+ write_pid_file(); - } - -- write_pid_file(); -- - while (watch(master_fd, watch_file) == 0) { - } - --- -2.53.0 - diff --git a/0008-Revert-python-sepolicy-update-for-modern-python-buil.patch b/0008-Revert-python-sepolicy-update-for-modern-python-buil.patch new file mode 100644 index 0000000..4cfaf4a --- /dev/null +++ b/0008-Revert-python-sepolicy-update-for-modern-python-buil.patch @@ -0,0 +1,56 @@ +From 11d3ceaac388023652935bae245b19d490350472 Mon Sep 17 00:00:00 2001 +From: Vit Mojzis +Date: Fri, 10 Jul 2026 13:28:31 +0200 +Subject: [PATCH] Revert "python/sepolicy: update for modern python builds" + +This reverts commit 3aac92b7250ed57fd4ab674ffcf03d9c499b3188. + +'pip install build' fails on systems without network and python3-build +is not available in RHEL-10. +--- + python/sepolicy/.gitignore | 1 - + python/sepolicy/Makefile | 10 +++++----- + 2 files changed, 5 insertions(+), 6 deletions(-) + +diff --git a/python/sepolicy/.gitignore b/python/sepolicy/.gitignore +index 80824997..32fb47f9 100644 +--- a/python/sepolicy/.gitignore ++++ b/python/sepolicy/.gitignore +@@ -2,4 +2,3 @@ build + tmp + *.bak + sepolicy.egg-info/ +-dist/ +diff --git a/python/sepolicy/Makefile b/python/sepolicy/Makefile +index 4a4a3512..ccb22fe7 100644 +--- a/python/sepolicy/Makefile ++++ b/python/sepolicy/Makefile +@@ -14,11 +14,11 @@ BASHCOMPLETIONS=sepolicy-bash-completion.sh + all: python-build + + python-build: +- $(PYTHON) -m pip install build wheel setuptools +- $(PYTHON) -m build --no-isolation --wheel . ++ $(PYTHON) setup.py build + + clean: +- -rm -rf build dist *.egg-info *~ \#* *pyc .#* ++ $(PYTHON) setup.py clean ++ -rm -rf build *~ \#* *pyc .#* sepolicy.egg-info/ + + sepolgen: + ln -sf sepolicy sepolgen +@@ -26,8 +26,8 @@ sepolgen: + test: + @$(PYTHON) test_sepolicy.py -v + +-install: python-build +- $(PYTHON) -m pip install --no-build-isolation --force-reinstall --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR) --ignore-installed --no-deps` dist/*.whl ++install: ++ $(PYTHON) -m pip install --no-build-isolation --prefix=$(PREFIX) `test -n "$(DESTDIR)" && echo --root $(DESTDIR) --ignore-installed --no-deps` $(PYTHON_SETUP_ARGS) . + [ -d $(DESTDIR)$(BINDIR) ] || mkdir -p $(DESTDIR)$(BINDIR) + install -m 755 sepolicy.py $(DESTDIR)$(BINDIR)/sepolicy + (cd $(DESTDIR)$(BINDIR); ln -sf sepolicy sepolgen) +-- +2.53.0 + diff --git a/0008-restorecond.service-Use-Type-simple.patch b/0008-restorecond.service-Use-Type-simple.patch deleted file mode 100644 index 1beb348..0000000 --- a/0008-restorecond.service-Use-Type-simple.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 9a2d20910e4f6f35a76513627b68bfbfda7f6fd0 Mon Sep 17 00:00:00 2001 -From: Petr Lautrbach -Date: Thu, 2 Apr 2026 17:19:05 +0200 -Subject: [PATCH] restorecond.service: Use Type=simple -Content-type: text/plain - -There's a race condition when daemon() in parent process immediately -exits while pid file is not created or updated. Using Type=forking it -can confuse systemd which tries to open non-existing pid file. It's -better to run restocond in foreground and use Type=simple - -Fixes: - - openat(80, "restorecond.pid", O_RDONLY|O_NOFOLLOW|O_CLOEXEC|O_PATH) = -1 ENOENT (No such file or directory) <0.000006> - -Signed-off-by: Petr Lautrbach ---- - restorecond/restorecond.service | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/restorecond/restorecond.service b/restorecond/restorecond.service -index 0e4ea72d08ae..56f970707d93 100644 ---- a/restorecond/restorecond.service -+++ b/restorecond/restorecond.service -@@ -5,9 +5,8 @@ ConditionPathExists=/etc/selinux/restorecond.conf - ConditionSecurity=selinux - - [Service] --Type=forking --ExecStart=/usr/sbin/restorecond --PIDFile=/run/restorecond.pid -+Type=simple -+ExecStart=/usr/sbin/restorecond -F - - [Install] - WantedBy=multi-user.target --- -2.53.0 - diff --git a/0009-seunshare-guard-fallible-function-calls-by-checking-.patch b/0009-seunshare-guard-fallible-function-calls-by-checking-.patch deleted file mode 100644 index 028d2bd..0000000 --- a/0009-seunshare-guard-fallible-function-calls-by-checking-.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0edfc7cd42fdded9c697370d6932eecad2aa7449 Mon Sep 17 00:00:00 2001 -From: Rahul Sandhu -Date: Tue, 14 Apr 2026 18:40:00 +0000 -Subject: [PATCH] seunshare: guard fallible function calls by checking retval -Content-type: text/plain - -seunshare currently segfaults is passed --kill and an invalid context -via -Z. - -Signed-off-by: Rahul Sandhu -Acked-by: Stephen Smalley ---- - sandbox/seunshare.c | 26 +++++++++++++++++++------- - 1 file changed, 19 insertions(+), 7 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 2512a18c7b52..e89a9fecf9f6 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -679,9 +679,19 @@ killall (const char *execcon) - return -1; - } - pids = 0; -- context_t con; -- con = context_new(execcon); -- const char *mcs = context_range_get(con); -+ context_t con = context_new(execcon); -+ if (!con) { -+ free(pid_table); -+ (void)closedir(dir); -+ return -1; -+ } -+ const char *const mcs = context_range_get(con); -+ if (!mcs) { -+ context_free(con); -+ free(pid_table); -+ (void)closedir(dir); -+ return -1; -+ } - printf("mcs=%s\n", mcs); - while ((de = readdir (dir)) != NULL) { - if (!(pid = (pid_t)atoi(de->d_name)) || pid == self) -@@ -708,11 +718,13 @@ killall (const char *execcon) - if (getpidcon(id, &scon) == 0) { - - context_t pidcon = context_new(scon); -- /* Attempt to kill remaining processes */ -- if (strcmp(context_range_get(pidcon), mcs) == 0) -- kill(id, SIGKILL); -+ if (pidcon) { -+ /* Attempt to kill remaining processes */ -+ if (strcmp(context_range_get(pidcon), mcs) == 0) -+ kill(id, SIGKILL); - -- context_free(pidcon); -+ context_free(pidcon); -+ } - freecon(scon); - } - running++; --- -2.54.0 - diff --git a/0010-sandbox-seunshare-pass-O_NOFOLLOW-to-openat.patch b/0010-sandbox-seunshare-pass-O_NOFOLLOW-to-openat.patch deleted file mode 100644 index 2191dec..0000000 --- a/0010-sandbox-seunshare-pass-O_NOFOLLOW-to-openat.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8d2c7360f5749b3ccacd348c495399f24318d7b4 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Tue, 12 May 2026 14:34:02 -0400 -Subject: [PATCH] sandbox/seunshare: pass O_NOFOLLOW to openat() -Content-type: text/plain - -We do not want to follow symlinks here. - -Acked-by: James Carter -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index e89a9fecf9f6..a1900eaa7600 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -428,7 +428,7 @@ static bool rm_rf(int targetfd, const char *path) { - } - - if (S_ISDIR(statbuf.st_mode)) { -- const int newfd = openat(targetfd, path, O_RDONLY | O_DIRECTORY | O_CLOEXEC); -+ const int newfd = openat(targetfd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (newfd < 0) { - perror("openat"); - return false; --- -2.54.0 - diff --git a/0011-sandbox-seunshare-switch-seunshare_mount_file-to-use.patch b/0011-sandbox-seunshare-switch-seunshare_mount_file-to-use.patch deleted file mode 100644 index b437195..0000000 --- a/0011-sandbox-seunshare-switch-seunshare_mount_file-to-use.patch +++ /dev/null @@ -1,52 +0,0 @@ -From e964a574c2ca8ec1bcd3172dc185ada8044dceee Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Tue, 12 May 2026 15:26:31 -0400 -Subject: [PATCH] sandbox/seunshare: switch seunshare_mount_file() to use - open() -Content-type: text/plain - -seunshare_mount_file() currently uses fopen() to create the dst -if it doesn't already exist. Switch to using open() with -explicitly specified flags including O_NOFOLLOW and an explicitly -specified mode for the new file. - -Signed-off-by: Stephen Smalley -Acked-by: Petr Lautrbach ---- - sandbox/seunshare.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index a1900eaa7600..17a727e78b5f 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -304,18 +304,20 @@ static int seunshare_mount(const char *src, const char *dst, struct stat *src_st - */ - static int seunshare_mount_file(const char *src, const char *dst) - { -- int flags = 0; -- - if (verbose) - printf(_("Mounting %s on %s\n"), src, dst); - - if (access(dst, F_OK) == -1) { -- FILE *fptr; -- fptr = fopen(dst, "w"); -- fclose(fptr); -+ int fd = open(dst, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, 0600); -+ if (fd < 0) { -+ fprintf(stderr, _("Failed to create mount point %s: %m\n"), dst); -+ return -1; -+ } -+ close(fd); - } -+ - /* mount file */ -- if (mount(src, dst, NULL, MS_BIND | flags, NULL) < 0) { -+ if (mount(src, dst, NULL, MS_BIND, NULL) < 0) { - fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno)); - return -1; - } --- -2.54.0 - diff --git a/0012-sandbox-seunshare-fix-error-checking-for-setfsuid.patch b/0012-sandbox-seunshare-fix-error-checking-for-setfsuid.patch deleted file mode 100644 index 02d93e0..0000000 --- a/0012-sandbox-seunshare-fix-error-checking-for-setfsuid.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9c5320c6d4a1eb91b57e4e12737882ef131c2faa Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Tue, 12 May 2026 15:35:53 -0400 -Subject: [PATCH] sandbox/seunshare: fix error checking for setfsuid() -Content-type: text/plain - -setfsuid() doesn't reliably set errno or return anything indicating -an error. - -Signed-off-by: Stephen Smalley -Acked-by: Petr Lautrbach ---- - sandbox/seunshare.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 17a727e78b5f..b9c85bf20f85 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -858,8 +858,8 @@ int main(int argc, char **argv) { - /* Changing fsuid is usually required when user-specified directory is - * on an NFS mount. It's also desired to avoid leaking info about - * existence of the files not accessible to the user. */ -- if (((uid_t)setfsuid(uid) != 0) && (errno != 0)) { -- fprintf(stderr, _("Error: unable to setfsuid %m\n")); -+ if ((uid_t)setfsuid(uid) != 0) { -+ fprintf(stderr, _("Error: unable to setfsuid\n")); - - return -1; - } --- -2.54.0 - diff --git a/0013-sandbox-seunshare-remount-tmp-and-var-tmp-with-the-p.patch b/0013-sandbox-seunshare-remount-tmp-and-var-tmp-with-the-p.patch deleted file mode 100644 index ade7f30..0000000 --- a/0013-sandbox-seunshare-remount-tmp-and-var-tmp-with-the-p.patch +++ /dev/null @@ -1,86 +0,0 @@ -From f78708ea5d6d3d6da4fa20527b459fa55075d8a6 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Tue, 12 May 2026 16:06:05 -0400 -Subject: [PATCH] sandbox/seunshare: remount /tmp and /var/tmp with the proper - flags -Content-type: text/plain - -mount(2) with MS_BIND ignores any nosuid/nodev/noexec flags, so -seunshare_mount() was never setting those on the /tmp and -/var/tmp mounts. Fix seunshare_mount() to remount them -with those flags after the bind mount, which does -set them properly. - -Test: -mkdir tmp -seunshare -t tmp /bin/bash -cp /bin/bash /tmp -/tmp/bash - -Signed-off-by: Stephen Smalley -Acked-by: Petr Lautrbach ---- - sandbox/seunshare.c | 21 ++++++++++++++++----- - 1 file changed, 16 insertions(+), 5 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index b9c85bf20f85..985e0cfba199 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -260,26 +260,32 @@ static int verify_shell(const char *shell_name) - */ - static int seunshare_mount(const char *src, const char *dst, struct stat *src_st) - { -- int flags = 0; -+ int bind_flags = MS_BIND; -+ int sec_flags = 0; - int is_tmp = 0; - - if (verbose) - printf(_("Mounting %s on %s\n"), src, dst); - - if (strcmp("/tmp", dst) == 0) { -- flags = flags | MS_NODEV | MS_NOSUID | MS_NOEXEC; -+ sec_flags = MS_NODEV | MS_NOSUID | MS_NOEXEC; - is_tmp = 1; - } - - if (strncmp("/run/user", dst, 9) == 0) { -- flags = flags | MS_REC; -+ bind_flags |= MS_REC; - } - - /* mount directory */ -- if (mount(src, dst, NULL, MS_BIND | flags, NULL) < 0) { -+ if (mount(src, dst, NULL, bind_flags, NULL) < 0) { - fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno)); - return -1; - } -+ /* remount with security flags, ignored on original bind mount */ -+ if (sec_flags && mount(NULL, dst, NULL, MS_BIND | MS_REMOUNT | sec_flags, NULL) < 0) { -+ fprintf(stderr, _("Failed to remount %s: %m\n"), dst); -+ return -1; -+ } - - /* verify whether we mounted what we expected to mount */ - if (verify_directory(dst, src_st, NULL) < 0) return -1; -@@ -289,10 +295,15 @@ static int seunshare_mount(const char *src, const char *dst, struct stat *src_st - if (verbose) - printf(_("Mounting /tmp on /var/tmp\n")); - -- if (mount("/tmp", "/var/tmp", NULL, MS_BIND | flags, NULL) < 0) { -+ if (mount("/tmp", "/var/tmp", NULL, MS_BIND, NULL) < 0) { - fprintf(stderr, _("Failed to mount /tmp on /var/tmp: %s\n"), strerror(errno)); - return -1; - } -+ /* remount with security flags, ignored on original bind mount */ -+ if (mount(NULL, "/var/tmp", NULL, MS_BIND | MS_REMOUNT | sec_flags, NULL) < 0) { -+ fprintf(stderr, _("Failed to remount /var/tmp: %m\n")); -+ return -1; -+ } - } - - return 0; --- -2.54.0 - diff --git a/0014-sandbox-seunshare-prevent-rsync-from-interpreting-pa.patch b/0014-sandbox-seunshare-prevent-rsync-from-interpreting-pa.patch deleted file mode 100644 index cffb736..0000000 --- a/0014-sandbox-seunshare-prevent-rsync-from-interpreting-pa.patch +++ /dev/null @@ -1,75 +0,0 @@ -From dd620e8af44e1cb59d70837e80a5d55a8d3e789f Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 09:47:50 -0400 -Subject: [PATCH] sandbox/seunshare: prevent rsync from interpreting paths as - options -Content-type: text/plain - -Insert a "--" after all legitimate options before any glob or -pathnames to prevent rsync from interpreting them as options. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 985e0cfba199..a48c88036088 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -391,8 +391,8 @@ static int rsynccmd(const char * src, const char *dst, char ***cmd) { - - free(buf); buf = NULL; - -- /* rsync -trlHDq + + dst + NULL */ -- *cmd = calloc(2 + fglob.gl_pathc + 2, sizeof(char *)); -+ /* rsync -trlHDq -- dst NULL */ -+ *cmd = calloc(3 + fglob.gl_pathc + 2, sizeof(char *)); - if (! *cmd) { - fprintf(stderr, _("Out of memory\n")); - return -1; -@@ -401,8 +401,9 @@ static int rsynccmd(const char * src, const char *dst, char ***cmd) { - args = *cmd; - strdup_or_err(args, 0, "/usr/bin/rsync"); - strdup_or_err(args, 1, "-trlHDq"); -+ strdup_or_err(args, 2, "--"); - -- for ( i=0, index = 2; i < fglob.gl_pathc; i++) { -+ for ( i=0, index = 3; i < fglob.gl_pathc; i++) { - const char *path = fglob.gl_pathv[i]; - if (bad_path(path)) continue; - strdup_or_err(args, index, path); -@@ -495,7 +496,7 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src, - - /* rsync files back */ - if (copy_content) { -- args = calloc(7, sizeof(char *)); -+ args = calloc(8, sizeof(char *)); - if (! args) { - fprintf(stderr, _("Out of memory\n")); - return 1; -@@ -505,17 +506,18 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src, - strdup_or_err(args, 1, "--exclude=.X11-unix"); - strdup_or_err(args, 2, "-utrlHDq"); - strdup_or_err(args, 3, "--delete"); -- if (asprintf(&args[4], "%s/", tmpdir) == -1) { -+ strdup_or_err(args, 4, "--"); -+ if (asprintf(&args[5], "%s/", tmpdir) == -1) { - fprintf(stderr, _("Out of memory\n")); - free_args(args); - return 1; - } -- if (asprintf(&args[5], "%s/", src) == -1) { -+ if (asprintf(&args[6], "%s/", src) == -1) { - fprintf(stderr, _("Out of memory\n")); - free_args(args); - return 1; - } -- args[6] = NULL; -+ args[7] = NULL; - - if (spawn_command(args, pwd->pw_uid) != 0) { - fprintf(stderr, _("Failed to copy files from the runtime temporary directory\n")); --- -2.54.0 - diff --git a/0015-sandbox-seunshare-fix-getopt-flags.patch b/0015-sandbox-seunshare-fix-getopt-flags.patch deleted file mode 100644 index 93e5a23..0000000 --- a/0015-sandbox-seunshare-fix-getopt-flags.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 9c29653dc6b0f4e9a74cd119d60a84ed8c4a6ec6 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 09:59:08 -0400 -Subject: [PATCH] sandbox/seunshare: fix getopt flags -Content-type: text/plain - --k, -v, and -C do NOT accept an argument, and the optstring -was not correct. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index a48c88036088..0dfc5cb2b820 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -776,10 +776,10 @@ int main(int argc, char **argv) { - {"homedir", 1, 0, 'h'}, - {"tmpdir", 1, 0, 't'}, - {"runuserdir", 1, 0, 'r'}, -- {"kill", 1, 0, 'k'}, -- {"verbose", 1, 0, 'v'}, -+ {"kill", 0, 0, 'k'}, -+ {"verbose", 0, 0, 'v'}, - {"context", 1, 0, 'Z'}, -- {"capabilities", 1, 0, 'C'}, -+ {"capabilities", 0, 0, 'C'}, - {"wayland", 1, 0, 'W'}, - {"pipewire", 1, 0, 'P'}, - {NULL, 0, 0, 0} -@@ -811,7 +811,7 @@ int main(int argc, char **argv) { - } - - while (1) { -- clflag = getopt_long(argc, argv, "Ccvh:r:t:W:Z:", long_options, NULL); -+ clflag = getopt_long(argc, argv, "Ckvh:r:t:W:P:Z:", long_options, NULL); - if (clflag == -1) - break; - --- -2.54.0 - diff --git a/0016-sandbox-seunshare-prevent-path-traversal-via-W-P.patch b/0016-sandbox-seunshare-prevent-path-traversal-via-W-P.patch deleted file mode 100644 index 94c6a72..0000000 --- a/0016-sandbox-seunshare-prevent-path-traversal-via-W-P.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 5da4d90480164c13a5bc8f8c820e701790499ecc Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 10:13:17 -0400 -Subject: [PATCH] sandbox/seunshare: prevent path traversal via -W/-P -Content-type: text/plain - -The -W/-P options specify the wayland or pipewire socket name respectively. -The option argument is then concatenated with the runuserdir to create -a pathname. We don't want to allow it to be used to construct arbitrary -paths outside of the runuserdir. Also, check and handle -errors when bind mounting the pipewire socket file. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 0dfc5cb2b820..945a3b21c1cc 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -849,6 +849,12 @@ int main(int argc, char **argv) { - } - } - -+ if ((wayland_display && (strchr(wayland_display, '/') || strstr(wayland_display, ".."))) || -+ (pipewire_socket && (strchr(pipewire_socket, '/') || strstr(pipewire_socket, "..")))) { -+ fprintf(stderr, _("Error: -W/-P must be a socket name, not a path\n")); -+ return -1; -+ } -+ - if (! homedir_s && ! tmpdir_s) { - fprintf(stderr, _("Error: tmpdir and/or homedir required\n %s\n"), USAGE_STRING); - return -1; -@@ -990,7 +996,8 @@ int main(int argc, char **argv) { - perror(_("Out of memory")); - goto childerr; - } -- seunshare_mount_file(pipewire_path, pipewire_path_s); -+ if (seunshare_mount_file(pipewire_path, pipewire_path_s) == -1) -+ goto childerr; - } - } - --- -2.54.0 - diff --git a/0017-sandbox-seunshare-verify-RUNTIME_DIR-before-use.patch b/0017-sandbox-seunshare-verify-RUNTIME_DIR-before-use.patch deleted file mode 100644 index ed46220..0000000 --- a/0017-sandbox-seunshare-verify-RUNTIME_DIR-before-use.patch +++ /dev/null @@ -1,38 +0,0 @@ -From cceeb1def62ef78fed802684e9500cfa1aefa6b3 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 10:30:20 -0400 -Subject: [PATCH] sandbox/seunshare: verify RUNTIME_DIR before use -Content-type: text/plain - -RUNTIME_DIR can be inherited from XDG_RUNTIME_DIR or set to a default -path. Regardless, we should verify it the same way as the other -user-supplied directories before first use. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 945a3b21c1cc..89180d0aa1ed 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -964,6 +964,15 @@ int main(int argc, char **argv) { - } - } - -+ if (runuserdir_s) { -+ struct stat sb; -+ -+ if (verify_directory(RUNTIME_DIR, NULL, &sb) < 0 || -+ check_owner_uid(uid, RUNTIME_DIR, &sb) < 0) -+ goto childerr; -+ -+ } -+ - if ((XDG_SESSION_TYPE = getenv("XDG_SESSION_TYPE")) != NULL) { - if ((XDG_SESSION_TYPE = strdup(XDG_SESSION_TYPE)) == NULL) { - perror(_("Out of memory")); --- -2.54.0 - diff --git a/0018-sandbox-seunshare-drop-unused-runuserdir_r.patch b/0018-sandbox-seunshare-drop-unused-runuserdir_r.patch deleted file mode 100644 index 507db08..0000000 --- a/0018-sandbox-seunshare-drop-unused-runuserdir_r.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c2f54aff134bcba8ae9701d26d7711530d72be76 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 10:37:56 -0400 -Subject: [PATCH] sandbox/seunshare: drop unused runuserdir_r -Content-type: text/plain - -runuserdir_r is created but never used nor deleted. Get rid of it. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 8 -------- - 1 file changed, 8 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 89180d0aa1ed..2eef0e2f800e 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -763,14 +763,12 @@ int main(int argc, char **argv) { - char *tmpdir_s = NULL; /* tmpdir spec'd by user in argv[] */ - char *tmpdir_r = NULL; /* tmpdir created by seunshare */ - char *runuserdir_s = NULL; /* /var/run/user/UID spec'd by user in argv[] */ -- char *runuserdir_r = NULL; /* /var/run/user/UID created by seunshare */ - - struct stat st_curhomedir; - struct stat st_homedir; - struct stat st_tmpdir_s; - struct stat st_tmpdir_r; - struct stat st_runuserdir_s; -- struct stat st_runuserdir_r; - - const struct option long_options[] = { - {"homedir", 1, 0, 'h'}, -@@ -902,12 +900,6 @@ int main(int argc, char **argv) { - fprintf(stderr, _("Failed to create runtime temporary directory\n")); - return -1; - } -- /* create runtime runuserdir */ -- if (runuserdir_s && (runuserdir_r = create_tmpdir(runuserdir_s, &st_runuserdir_s, -- &st_runuserdir_r, pwd, execcon)) == NULL) { -- fprintf(stderr, _("Failed to create runtime $XDG_RUNTIME_DIR directory\n")); -- return -1; -- } - - /* spawn child process */ - child = fork(); --- -2.54.0 - diff --git a/0019-sandbox-seunshare-fix-killall-realloc-and-missing-ty.patch b/0019-sandbox-seunshare-fix-killall-realloc-and-missing-ty.patch deleted file mode 100644 index aab56f7..0000000 --- a/0019-sandbox-seunshare-fix-killall-realloc-and-missing-ty.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 47a8bd5d29455f1b8496a2bc7ba95f3f535c2ba7 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Wed, 13 May 2026 12:21:47 -0400 -Subject: [PATCH] sandbox/seunshare: fix killall() realloc and missing type - comparison -Content-type: text/plain - -The killall() realloc() can produce an integer overflow. -Check and handle this correctly. - -The killall() logic also only compares the MCS category set when -deciding whether to kill the process. We should at least also compare -the type to avoid incorrectly killing an unrelated process with -the same category set (e.g. if multiple applications are independently -assigning category sets on the same system). Check the type as well. - -killall() still seems error prone and I couldn't find any actual users -of the -k/--kill option for seunshare. Can we just drop this? - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 26 +++++++++++++++++++------- - 1 file changed, 19 insertions(+), 7 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 2eef0e2f800e..e20c0f8723aa 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -680,8 +680,8 @@ killall (const char *execcon) - char *scon; - struct dirent *de; - pid_t *pid_table, pid, self; -- int i; -- int pids, max_pids; -+ unsigned int i; -+ unsigned int pids, max_pids; - int running = 0; - self = getpid(); - if (!(dir = opendir(PROC_BASE))) { -@@ -701,26 +701,34 @@ killall (const char *execcon) - return -1; - } - const char *const mcs = context_range_get(con); -- if (!mcs) { -+ const char *const type = context_type_get(con); -+ if (!mcs || !type) { - context_free(con); - free(pid_table); - (void)closedir(dir); - return -1; - } -- printf("mcs=%s\n", mcs); -+ if (verbose) -+ printf("mcs=%s type=%s\n", mcs, type); - while ((de = readdir (dir)) != NULL) { - if (!(pid = (pid_t)atoi(de->d_name)) || pid == self) - continue; - - if (pids == max_pids) { -- pid_t *new_pid_table = realloc(pid_table, 2*pids*sizeof(pid_t)); -+ max_pids *= 2; -+ if (max_pids <= pids) -+ { -+ free(pid_table); -+ (void)closedir(dir); -+ return -1; -+ } -+ pid_t *new_pid_table = reallocarray(pid_table, max_pids, sizeof(pid_t)); - if (!new_pid_table) { - free(pid_table); - (void)closedir(dir); - return -1; - } - pid_table = new_pid_table; -- max_pids *= 2; - } - pid_table[pids++] = pid; - } -@@ -734,8 +742,12 @@ killall (const char *execcon) - - context_t pidcon = context_new(scon); - if (pidcon) { -+ const char *const pmcs = context_range_get(pidcon); -+ const char *const ptype = context_type_get(pidcon); -+ - /* Attempt to kill remaining processes */ -- if (strcmp(context_range_get(pidcon), mcs) == 0) -+ if (pmcs && ptype && !strcmp(pmcs, mcs) && -+ !strcmp(ptype, type)) - kill(id, SIGKILL); - - context_free(pidcon); --- -2.54.0 - diff --git a/0020-sandbox-seunshare-rewrite-to-pin-directories-before-.patch b/0020-sandbox-seunshare-rewrite-to-pin-directories-before-.patch deleted file mode 100644 index 56b8e6d..0000000 --- a/0020-sandbox-seunshare-rewrite-to-pin-directories-before-.patch +++ /dev/null @@ -1,606 +0,0 @@ -From 9c44bb929a7937897a787790ece679464345c5d9 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Thu, 14 May 2026 10:32:13 -0400 -Subject: [PATCH] sandbox/seunshare: rewrite to pin directories before use -Content-type: text/plain - -To fully eliminate TOCTOU issues in seunshare, we need to pin the -directories and pass them via /proc/self/fd/N to mount(2). -This is complicated further by the unsharing of the mount namespace -in the child process and the need to remount in order to apply -nosuid/nodev/noexec flags. Do the best we can with the legacy -mount(2) API for compatibility on old kernels and revisit if/when -we make kernels with the new mount API the minimum required for -SELinux userspace. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 406 ++++++++++++++++++++++++++------------------ - 1 file changed, 241 insertions(+), 165 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index e20c0f8723aa..611bfe80d030 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -197,35 +197,33 @@ static int check_owner_gid(gid_t gid, const char *file, struct stat *st) { - return 0; - } - --#define equal_stats(one,two) \ -- ((one)->st_dev == (two)->st_dev && (one)->st_ino == (two)->st_ino && \ -- (one)->st_uid == (two)->st_uid && (one)->st_gid == (two)->st_gid && \ -- (one)->st_mode == (two)->st_mode) -- - /** -- * Sanity check specified directory. Store stat info for future comparison, or -- * compare with previously saved info to detect replaced directories. -- * Note: This function does not perform owner checks. -+ * Open directory with O_DIRECTORY|O_NOFOLLOW and return its fd -+ * and fstat() results. The returned fd and its /proc/self/fd/N -+ * path can be used for all subsequent operations on the directory. -+ * NB Any non-final components in the @dir pathname are resolved -+ * as usual but will be checked against the fsuid of the caller. - */ --static int verify_directory(const char *dir, struct stat *st_in, struct stat *st_out) { -+static int pin_dir(const char *dir, struct stat *st_out) -+{ -+ int fd; - struct stat sb; - -- if (st_out == NULL) st_out = &sb; -- -- if (lstat(dir, st_out) == -1) { -- fprintf(stderr, _("Failed to stat %s: %s\n"), dir, strerror(errno)); -+ fd = open(dir, O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); -+ if (fd < 0) { -+ fprintf(stderr, _("Failed to open %s: %m\n"), dir); - return -1; - } -- if (! S_ISDIR(st_out->st_mode)) { -- fprintf(stderr, _("Error: %s is not a directory: %s\n"), dir, strerror(errno)); -- return -1; -- } -- if (st_in && !equal_stats(st_in, st_out)) { -- fprintf(stderr, _("Error: %s was replaced by a different directory\n"), dir); -+ -+ if (fstat(fd, &sb) < 0) { -+ fprintf(stderr, _("Failed to stat %s: %m\n"), dir); -+ close(fd); - return -1; - } - -- return 0; -+ if (st_out) -+ *st_out = sb; -+ return fd; - } - - /** -@@ -256,85 +254,90 @@ static int verify_shell(const char *shell_name) - } - - /** -- * Mount directory and check that we mounted the right directory. -+ * Bind-mount directory @src (using @src_fd) on directory @dst (using @dst_fd), -+ * applying @bind_flags for the initial bind mount and @sec_flags if -+ * non-zero via remount. - */ --static int seunshare_mount(const char *src, const char *dst, struct stat *src_st) -+static int seunshare_mount(const char *src, int src_fd, -+ const char *dst, int dst_fd, -+ int bind_flags, int sec_flags) - { -- int bind_flags = MS_BIND; -- int sec_flags = 0; -- int is_tmp = 0; -+ char srcprocfd[32], dstprocfd[32]; -+ -+ bind_flags |= MS_BIND; - - if (verbose) - printf(_("Mounting %s on %s\n"), src, dst); - -- if (strcmp("/tmp", dst) == 0) { -- sec_flags = MS_NODEV | MS_NOSUID | MS_NOEXEC; -- is_tmp = 1; -- } -+ snprintf(srcprocfd, sizeof(srcprocfd), "/proc/self/fd/%d", src_fd); -+ snprintf(dstprocfd, sizeof(dstprocfd), "/proc/self/fd/%d", dst_fd); - -- if (strncmp("/run/user", dst, 9) == 0) { -- bind_flags |= MS_REC; -- } -- -- /* mount directory */ -- if (mount(src, dst, NULL, bind_flags, NULL) < 0) { -- fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno)); -+ /* bind mount directory */ -+ if (mount(srcprocfd, dstprocfd, NULL, bind_flags, NULL) < 0) { -+ fprintf(stderr, _("Failed to mount %s on %s: %m\n"), src, dst); - return -1; - } -- /* remount with security flags, ignored on original bind mount */ -- if (sec_flags && mount(NULL, dst, NULL, MS_BIND | MS_REMOUNT | sec_flags, NULL) < 0) { -+ -+ /* -+ * Remount with security flags set - requires use of dst path again. -+ * Revisit when we migrate to open_tree()/move_mount(). -+ */ -+ if (sec_flags && -+ mount(NULL, dst, NULL, MS_BIND | MS_REMOUNT | sec_flags, NULL) < 0) { - fprintf(stderr, _("Failed to remount %s: %m\n"), dst); - return -1; - } - -- /* verify whether we mounted what we expected to mount */ -- if (verify_directory(dst, src_st, NULL) < 0) return -1; -- -- /* bind mount /tmp on /var/tmp too */ -- if (is_tmp) { -- if (verbose) -- printf(_("Mounting /tmp on /var/tmp\n")); -- -- if (mount("/tmp", "/var/tmp", NULL, MS_BIND, NULL) < 0) { -- fprintf(stderr, _("Failed to mount /tmp on /var/tmp: %s\n"), strerror(errno)); -- return -1; -- } -- /* remount with security flags, ignored on original bind mount */ -- if (mount(NULL, "/var/tmp", NULL, MS_BIND | MS_REMOUNT | sec_flags, NULL) < 0) { -- fprintf(stderr, _("Failed to remount /var/tmp: %m\n")); -- return -1; -- } -- } -- - return 0; -- - } - - /** -- * Mount directory and check that we mounted the right directory. -+ * Bind-mount a file named @src_name in directory @src_dirfd on -+ * a file named @dst_name in directory @dst_dirfd, creating @dst_name -+ * if it doesn't already exist. - */ --static int seunshare_mount_file(const char *src, const char *dst) -+static int seunshare_mount_file(int src_dirfd, const char *src_name, -+ int dst_dirfd, const char *dst_name) - { -+ char srcprocfd[32], dstprocfd[32]; -+ int src_fd = -1, dst_fd = -1, rc = -1; -+ - if (verbose) -- printf(_("Mounting %s on %s\n"), src, dst); -+ printf(_("Mounting %s on %s\n"), src_name, dst_name); - -- if (access(dst, F_OK) == -1) { -- int fd = open(dst, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, 0600); -- if (fd < 0) { -- fprintf(stderr, _("Failed to create mount point %s: %m\n"), dst); -- return -1; -- } -- close(fd); -+ src_fd = openat(src_dirfd, src_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); -+ if (src_fd < 0) { -+ fprintf(stderr, _("Failed to open %s: %m\n"), src_name); -+ goto out; - } - -- /* mount file */ -- if (mount(src, dst, NULL, MS_BIND, NULL) < 0) { -- fprintf(stderr, _("Failed to mount %s on %s: %s\n"), src, dst, strerror(errno)); -- return -1; -+ dst_fd = openat(dst_dirfd, dst_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); -+ if (dst_fd < 0 && errno == ENOENT) -+ dst_fd = openat(dst_dirfd, dst_name, -+ O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW | -+ O_CLOEXEC, 0600); -+ if (dst_fd < 0) { -+ fprintf(stderr, _("Failed to open/create %s: %m\n"), dst_name); -+ goto out; - } - -- return 0; -+ snprintf(srcprocfd, sizeof(srcprocfd), "/proc/self/fd/%d", src_fd); -+ snprintf(dstprocfd, sizeof(dstprocfd), "/proc/self/fd/%d", dst_fd); - -+ /* mount file */ -+ if (mount(srcprocfd, dstprocfd, NULL, MS_BIND, NULL) < 0) { -+ fprintf(stderr, _("Failed to mount %s on %s: %m\n"), src_name, -+ dst_name); -+ goto out; -+ } -+ -+ rc = 0; -+out: -+ if (src_fd >= 0) -+ close(src_fd); -+ if (dst_fd >= 0) -+ close(dst_fd); -+ return rc; - } - - /* -@@ -556,7 +559,8 @@ err: - * to clean it up. - */ - static char *create_tmpdir(const char *src, struct stat *src_st, -- struct stat *out_st, struct passwd *pwd, const char *execcon) -+ struct stat *out_st, struct passwd *pwd, -+ const char *execcon) - { - char *tmpdir = NULL; - char **cmd = NULL; -@@ -564,29 +568,23 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - struct stat tmp_st; - char *con = NULL; - -- /* get selinux context */ -+ /* get selinux context of source directory */ - if (execcon) { - if ((uid_t)setfsuid(pwd->pw_uid) != 0) - goto err; -- -- if ((fd_s = open(src, O_RDONLY)) < 0) { -- fprintf(stderr, _("Failed to open directory %s: %s\n"), src, strerror(errno)); -- goto err; -- } -- if (fstat(fd_s, &tmp_st) == -1) { -- fprintf(stderr, _("Failed to stat directory %s: %s\n"), src, strerror(errno)); -+ if ((fd_s = pin_dir(src, &tmp_st)) < 0) - goto err; -- } -- if (!equal_stats(src_st, &tmp_st)) { -- fprintf(stderr, _("Error: %s was replaced by a different directory\n"), src); -+ if (tmp_st.st_dev != src_st->st_dev || -+ tmp_st.st_ino != src_st->st_ino) { -+ fprintf(stderr, -+ _("%s was replaced by a different directory\n"), -+ src); - goto err; - } - if (fgetfilecon(fd_s, &con) == -1) { -- fprintf(stderr, _("Failed to get context of the directory %s: %s\n"), src, strerror(errno)); -+ fprintf(stderr, _("Failed to get context of the directory %s: %m\n"), src); - goto err; - } -- -- /* ok to not reach this if there is an error */ - if ((uid_t)setfsuid(0) != pwd->pw_uid) - goto err; - } -@@ -602,9 +600,9 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - } - - /* temporary directory must be owned by root:user */ -- if (verify_directory(tmpdir, NULL, out_st) < 0) { -+ fd_t = pin_dir(tmpdir, out_st); -+ if (fd_t < 0) - goto err; -- } - - if (check_owner_uid(0, tmpdir, out_st) < 0) - goto err; -@@ -613,18 +611,6 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - goto err; - - /* change permissions of the temporary directory */ -- if ((fd_t = open(tmpdir, O_RDONLY)) < 0) { -- fprintf(stderr, _("Failed to open directory %s: %s\n"), tmpdir, strerror(errno)); -- goto err; -- } -- if (fstat(fd_t, &tmp_st) == -1) { -- fprintf(stderr, _("Failed to stat directory %s: %s\n"), tmpdir, strerror(errno)); -- goto err; -- } -- if (!equal_stats(out_st, &tmp_st)) { -- fprintf(stderr, _("Error: %s was replaced by a different directory\n"), tmpdir); -- goto err; -- } - if (fchmod(fd_t, 01770) == -1) { - fprintf(stderr, _("Unable to change mode on %s: %s\n"), tmpdir, strerror(errno)); - goto err; -@@ -664,10 +650,10 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - err: - free(tmpdir); tmpdir = NULL; - good: -- free_args(cmd); -- freecon(con); con = NULL; - if (fd_t >= 0) close(fd_t); - if (fd_s >= 0) close(fd_s); -+ free_args(cmd); -+ freecon(con); con = NULL; - return tmpdir; - } - -@@ -776,12 +762,13 @@ int main(int argc, char **argv) { - char *tmpdir_r = NULL; /* tmpdir created by seunshare */ - char *runuserdir_s = NULL; /* /var/run/user/UID spec'd by user in argv[] */ - -- struct stat st_curhomedir; - struct stat st_homedir; - struct stat st_tmpdir_s; - struct stat st_tmpdir_r; - struct stat st_runuserdir_s; - -+ int fd; -+ - const struct option long_options[] = { - {"homedir", 1, 0, 'h'}, - {"tmpdir", 1, 0, 't'}, -@@ -893,24 +880,49 @@ int main(int argc, char **argv) { - return -1; - } - -- /* verify homedir and tmpdir */ -- if (homedir_s && ( -- verify_directory(homedir_s, NULL, &st_homedir) < 0 || -- check_owner_uid(uid, homedir_s, &st_homedir))) return -1; -- if (tmpdir_s && ( -- verify_directory(tmpdir_s, NULL, &st_tmpdir_s) < 0 || -- check_owner_uid(uid, tmpdir_s, &st_tmpdir_s))) return -1; -- if (runuserdir_s && ( -- verify_directory(runuserdir_s, NULL, &st_runuserdir_s) < 0 || -- check_owner_uid(uid, runuserdir_s, &st_runuserdir_s))) return -1; -+ /* -+ * Perform early validation of the caller-provided directories so we -+ * can fail fast, but we unfortunately have to redo this after -+ * unsharing the mount namespace in the child so that it can use -+ * the descriptors for subsequent mount(2) calls. Otherwise, -+ * they end up with a different mount namespace and mount(2) fails -+ * with errno EINVAL. -+ */ -+ if (homedir_s) { -+ fd = pin_dir(homedir_s, &st_homedir); -+ if (fd < 0) -+ return -1; -+ if (check_owner_uid(uid, homedir_s, &st_homedir)) -+ return -1; -+ close(fd); -+ } -+ if (tmpdir_s) { -+ fd = pin_dir(tmpdir_s, &st_tmpdir_s); -+ if (fd < 0) -+ return -1; -+ if (check_owner_uid(uid, tmpdir_s, &st_tmpdir_s)) -+ return -1; -+ close(fd); -+ } -+ if (runuserdir_s) { -+ fd = pin_dir(runuserdir_s, &st_runuserdir_s); -+ if (fd < 0) -+ return -1; -+ if (check_owner_uid(uid, runuserdir_s, &st_runuserdir_s)) -+ return -1; -+ close(fd); -+ } - - if ((uid_t)setfsuid(0) != uid) return -1; - - /* create runtime tmpdir */ -- if (tmpdir_s && (tmpdir_r = create_tmpdir(tmpdir_s, &st_tmpdir_s, -- &st_tmpdir_r, pwd, execcon)) == NULL) { -- fprintf(stderr, _("Failed to create runtime temporary directory\n")); -- return -1; -+ if (tmpdir_s) { -+ tmpdir_r = create_tmpdir(tmpdir_s, &st_tmpdir_s, &st_tmpdir_r, -+ pwd, execcon); -+ if (!tmpdir_r) { -+ fprintf(stderr, _("Failed to create runtime temporary directory\n")); -+ return -1; -+ } - } - - /* spawn child process */ -@@ -927,11 +939,10 @@ int main(int argc, char **argv) { - char *XDG_SESSION_TYPE = NULL; - int rc = -1; - char *resolved_path = NULL; -- char *wayland_path_s = NULL; /* /tmp/.../wayland-0 */ -- char *wayland_path = NULL; /* /run/user/UID/wayland-0 */ -- char *pipewire_path_s = NULL; /* /tmp/.../pipewire-0 */ -- char *pipewire_path = NULL; /* /run/user/UID/pipewire-0 */ -- -+ int fd_homedir_s = -1, fd_curhomedir = -1; -+ int fd_runuserdir_s = -1, fd_runtime_dir = -1; -+ int fd_tmpdir_r = -1, fd_tmp = -1, fd_var_tmp = -1; -+ struct stat sb; - - if (unshare(CLONE_NEWNS) < 0) { - perror(_("Failed to unshare")); -@@ -941,19 +952,67 @@ int main(int argc, char **argv) { - /* Remount / as SLAVE so that nothing mounted in the namespace - shows up in the parent */ - if (mount("none", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) { -- perror(_("Failed to make / a SLAVE mountpoint\n")); -+ - goto childerr; - } - - /* assume fsuid==ruid after this point */ - if ((uid_t)setfsuid(uid) != 0) goto childerr; - -+ /* -+ * Now we can pin the source directories in this namespace -+ * for later use by mount(2). We recheck that each -+ * directory is the same inode and still has the -+ * expected ownership as the early validation. -+ */ -+ if (homedir_s) { -+ fd_homedir_s = pin_dir(homedir_s, &sb); -+ if (fd_homedir_s < 0) -+ goto childerr; -+ if (sb.st_dev != st_homedir.st_dev || -+ sb.st_ino != st_homedir.st_ino) -+ goto childerr; -+ if (check_owner_uid(uid, homedir_s, &sb)) -+ goto childerr; -+ } -+ /* -+ * NB We don't need to re-pin tmpdir_s, just tmpdir_r, -+ * since the child never uses tmpdir_s. -+ */ -+ if (tmpdir_r) { -+ fd_tmpdir_r = pin_dir(tmpdir_r, &sb); -+ if (fd < 0) -+ goto childerr; -+ /* -+ * tmpdir_r checks differ in that it is -+ * root-owned and we also want to validate -+ * that the mode is still correct. -+ */ -+ if (sb.st_dev != st_tmpdir_r.st_dev || -+ sb.st_ino != st_tmpdir_r.st_ino || -+ sb.st_mode != st_tmpdir_r.st_mode) -+ goto childerr; -+ if (check_owner_uid(0, tmpdir_r, &sb)) -+ goto childerr; -+ } -+ if (runuserdir_s) { -+ fd_runuserdir_s = pin_dir(runuserdir_s, &sb); -+ if (fd_runuserdir_s < 0) -+ goto childerr; -+ if (sb.st_dev != st_runuserdir_s.st_dev || -+ sb.st_ino != st_runuserdir_s.st_ino) -+ goto childerr; -+ if (check_owner_uid(uid, runuserdir_s, &sb)) -+ goto childerr; -+ } -+ - resolved_path = realpath(pwd->pw_dir,NULL); - if (! resolved_path) goto childerr; - -- if (verify_directory(resolved_path, NULL, &st_curhomedir) < 0) -+ fd_curhomedir = pin_dir(resolved_path, &sb); -+ if (fd_curhomedir < 0) - goto childerr; -- if (check_owner_uid(uid, resolved_path, &st_curhomedir) < 0) -+ if (check_owner_uid(uid, resolved_path, &sb) < 0) - goto childerr; - - if ((RUNTIME_DIR = getenv("XDG_RUNTIME_DIR")) != NULL) { -@@ -969,12 +1028,11 @@ int main(int argc, char **argv) { - } - - if (runuserdir_s) { -- struct stat sb; -- -- if (verify_directory(RUNTIME_DIR, NULL, &sb) < 0 || -- check_owner_uid(uid, RUNTIME_DIR, &sb) < 0) -+ fd_runtime_dir = pin_dir(RUNTIME_DIR, &sb); -+ if (fd_runtime_dir < 0) -+ goto childerr; -+ if (check_owner_uid(uid, RUNTIME_DIR, &sb) < 0) - goto childerr; -- - } - - if ((XDG_SESSION_TYPE = getenv("XDG_SESSION_TYPE")) != NULL) { -@@ -985,42 +1043,57 @@ int main(int argc, char **argv) { - } - - if (runuserdir_s && (wayland_display || pipewire_socket)) { -- if (wayland_display) { -- if (asprintf(&wayland_path_s, "%s/%s", runuserdir_s, wayland_display) == -1) { -- perror(_("Out of memory")); -+ if (wayland_display && -+ seunshare_mount_file(fd_runtime_dir, -+ wayland_display, -+ fd_runuserdir_s, -+ wayland_display) == -1) - goto childerr; -- } - -- if (asprintf(&wayland_path, "%s/%s", RUNTIME_DIR, wayland_display) == -1) { -- perror(_("Out of memory")); -- goto childerr; -- } -+ if (pipewire_socket && -+ seunshare_mount_file(fd_runtime_dir, -+ "pipewire-0", -+ fd_runuserdir_s, -+ pipewire_socket) == -1) -+ goto childerr; -+ } - -- if (seunshare_mount_file(wayland_path, wayland_path_s) == -1) -- goto childerr; -+ /* mount homedir, runuserdir and tmpdir, in this order */ -+ if (runuserdir_s && -+ seunshare_mount(runuserdir_s, fd_runuserdir_s, -+ RUNTIME_DIR, fd_runtime_dir, -+ MS_REC, 0) != 0) -+ goto childerr; -+ if (homedir_s && -+ seunshare_mount(homedir_s, fd_homedir_s, -+ resolved_path, fd_curhomedir, -+ 0, 0) != 0) -+ goto childerr; -+ if (tmpdir_s) { -+ fd_tmp = open("/tmp", O_RDONLY | O_DIRECTORY | -+ O_NOFOLLOW | O_CLOEXEC); -+ if (fd_tmp < 0) { -+ perror(_("Failed to open /tmp")); -+ goto childerr; - } - -- if (pipewire_socket) { -- if (asprintf(&pipewire_path_s, "%s/%s", runuserdir_s, pipewire_socket) == -1) { -- perror(_("Out of memory")); -- goto childerr; -- } -- if (asprintf(&pipewire_path, "%s/pipewire-0", RUNTIME_DIR) == -1) { -- perror(_("Out of memory")); -- goto childerr; -- } -- if (seunshare_mount_file(pipewire_path, pipewire_path_s) == -1) -- goto childerr; -+ if (seunshare_mount(tmpdir_r, fd_tmpdir_r, -+ "/tmp", fd_tmp, 0, -+ MS_NODEV|MS_NOSUID|MS_NOEXEC) < 0) -+ goto childerr; -+ -+ fd_var_tmp = open("/var/tmp", O_RDONLY | O_DIRECTORY | -+ O_NOFOLLOW | O_CLOEXEC); -+ if (fd_var_tmp < 0) { -+ perror(_("Failed to open /var/tmp")); -+ goto childerr; - } -- } - -- /* mount homedir, runuserdir and tmpdir, in this order */ -- if (runuserdir_s && seunshare_mount(runuserdir_s, RUNTIME_DIR, -- &st_runuserdir_s) != 0) goto childerr; -- if (homedir_s && seunshare_mount(homedir_s, resolved_path, -- &st_homedir) != 0) goto childerr; -- if (tmpdir_s && seunshare_mount(tmpdir_r, "/tmp", -- &st_tmpdir_r) != 0) goto childerr; -+ if (seunshare_mount("/tmp", fd_tmpdir_r, -+ "/var/tmp", fd_var_tmp, 0, -+ MS_NODEV|MS_NOSUID|MS_NOEXEC) < 0) -+ goto childerr; -+ } - - if (drop_privs(uid) != 0) goto childerr; - -@@ -1101,11 +1174,14 @@ int main(int argc, char **argv) { - execv(argv[optind], argv + optind); - fprintf(stderr, _("Failed to execute command %s: %s\n"), argv[optind], strerror(errno)); - childerr: -+ if (fd_homedir_s >= 0) close(fd_homedir_s); -+ if (fd_curhomedir >= 0) close(fd_curhomedir); -+ if (fd_runuserdir_s >= 0) close(fd_runuserdir_s); -+ if (fd_runtime_dir >= 0) close(fd_runtime_dir); -+ if (fd_tmpdir_r >= 0) close(fd_tmpdir_r); -+ if (fd_tmp >= 0) close(fd_tmp); -+ if (fd_var_tmp >= 0) close(fd_var_tmp); - free(resolved_path); -- free(wayland_path); -- free(wayland_path_s); -- free(pipewire_path); -- free(pipewire_path_s); - free(display); - free(LANG); - free(RUNTIME_DIR); --- -2.54.0 - diff --git a/0021-sandbox-seunshare-fully-check-setfsuid-calls.patch b/0021-sandbox-seunshare-fully-check-setfsuid-calls.patch deleted file mode 100644 index 2c7d50b..0000000 --- a/0021-sandbox-seunshare-fully-check-setfsuid-calls.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 59cfed3bf23511f792bde3085759ab44ed643a4a Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Thu, 14 May 2026 11:03:40 -0400 -Subject: [PATCH] sandbox/seunshare: fully check setfsuid() calls -Content-type: text/plain - -setfsuid() returns the old fsuid value and doesn't always -set errno. The existing code was checking that it did -successfully return the old fsuid value but not explicitly -checking that the new one was set, which can be done by -a second call to setfsuid() with -1 and checking its -return value. Add a wrapper for setfsuid() and use it -throughout to ensure complete checking. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 60 ++++++++++++++++++++++++++++++++++++--------- - 1 file changed, 48 insertions(+), 12 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 611bfe80d030..98fcef326853 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -486,6 +486,44 @@ static bool rm_rf(int targetfd, const char *path) { - return true; - } - -+/* -+ * setfsuid() returns the previous fsuid value, -+ * and does not reliably set errno on errors. -+ * Let's do better. -+ */ -+static int setfsuid_checked(uid_t old, uid_t new) -+{ -+ int rc; -+ -+ rc = setfsuid(new); -+ if ((uid_t)rc != old) { -+ int save_errno = errno; -+ fprintf(stderr, -+ "setfsuid(%u): Returned unexpected old uid %u\n", -+ new, (uid_t)rc); -+ if (save_errno) -+ errno = save_errno; -+ else -+ errno = EPERM; -+ return -1; -+ } -+ -+ rc = setfsuid(-1); -+ if ((uid_t)rc != new) { -+ int save_errno = errno; -+ fprintf(stderr, -+ "setfsuid(%u): Produced unexpected new uid %u\n", -+ new,(uid_t)rc); -+ if (save_errno) -+ errno = save_errno; -+ else -+ errno = EPERM; -+ return -1; -+ } -+ -+ return 0; -+} -+ - /** - * Clean up runtime temporary directory. Returns 0 if no problem was detected, - * >0 if some error was detected, but errors here are treated as non-fatal and -@@ -529,10 +567,8 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src, - free_args(args); - } - -- if ((uid_t)setfsuid(0) != 0) { -- /* setfsuid does not return error, but this check makes code checkers happy */ -+ if (setfsuid_checked(0, 0) < 0) - rc++; -- } - - /* Recursively remove the runtime temp directory. */ - if (!rm_rf(AT_FDCWD, tmpdir)) { -@@ -540,7 +576,7 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src, - rc++; - } - -- if ((uid_t)setfsuid(pwd->pw_uid) != 0) { -+ if (setfsuid_checked(0, pwd->pw_uid) < 0) { - fprintf(stderr, _("unable to switch back to user after clearing tmp dir\n")); - rc++; - } -@@ -570,7 +606,7 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - - /* get selinux context of source directory */ - if (execcon) { -- if ((uid_t)setfsuid(pwd->pw_uid) != 0) -+ if (setfsuid_checked(0, pwd->pw_uid)) - goto err; - if ((fd_s = pin_dir(src, &tmp_st)) < 0) - goto err; -@@ -585,7 +621,7 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - fprintf(stderr, _("Failed to get context of the directory %s: %m\n"), src); - goto err; - } -- if ((uid_t)setfsuid(0) != pwd->pw_uid) -+ if (setfsuid_checked(pwd->pw_uid, 0) < 0) - goto err; - } - -@@ -629,7 +665,7 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - } - } - -- if ((uid_t)setfsuid(pwd->pw_uid) != 0) -+ if (setfsuid_checked(0, pwd->pw_uid) < 0) - goto err; - - if (rsynccmd(src, tmpdir, &cmd) < 0) { -@@ -637,7 +673,7 @@ static char *create_tmpdir(const char *src, struct stat *src_st, - } - - /* ok to not reach this if there is an error */ -- if ((uid_t)setfsuid(0) != pwd->pw_uid) -+ if (setfsuid_checked(pwd->pw_uid, 0) < 0) - goto err; - - if (spawn_command(cmd, pwd->pw_uid) != 0) { -@@ -874,9 +910,8 @@ int main(int argc, char **argv) { - /* Changing fsuid is usually required when user-specified directory is - * on an NFS mount. It's also desired to avoid leaking info about - * existence of the files not accessible to the user. */ -- if ((uid_t)setfsuid(uid) != 0) { -+ if (setfsuid_checked(0, uid) < 0) { - fprintf(stderr, _("Error: unable to setfsuid\n")); -- - return -1; - } - -@@ -913,7 +948,8 @@ int main(int argc, char **argv) { - close(fd); - } - -- if ((uid_t)setfsuid(0) != uid) return -1; -+ if (setfsuid_checked(uid, 0) < 0) -+ return -1; - - /* create runtime tmpdir */ - if (tmpdir_s) { -@@ -957,7 +993,7 @@ int main(int argc, char **argv) { - } - - /* assume fsuid==ruid after this point */ -- if ((uid_t)setfsuid(uid) != 0) goto childerr; -+ if (setfsuid_checked(0, uid) < 0) goto childerr; - - /* - * Now we can pin the source directories in this namespace --- -2.54.0 - diff --git a/0022-sandbox-seunshare-check-owner-in-seunshare_mount_fil.patch b/0022-sandbox-seunshare-check-owner-in-seunshare_mount_fil.patch deleted file mode 100644 index 95aed7c..0000000 --- a/0022-sandbox-seunshare-check-owner-in-seunshare_mount_fil.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 8a3de70622d252f1ee070d6d9e9b019b9a6edd08 Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Fri, 15 May 2026 11:11:43 -0400 -Subject: [PATCH] sandbox/seunshare: check owner in seunshare_mount_file() -Content-type: text/plain - -We currently apply an owner check on directories prior to -calling seunshare_mount() on them. Do the same for -seunshare_mount_file(), but this has to be done inside -of the function since we do not open the source and -destination files until then. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 23 ++++++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 98fcef326853..3afe1554ae56 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -296,11 +296,12 @@ static int seunshare_mount(const char *src, int src_fd, - * a file named @dst_name in directory @dst_dirfd, creating @dst_name - * if it doesn't already exist. - */ --static int seunshare_mount_file(int src_dirfd, const char *src_name, -+static int seunshare_mount_file(uid_t uid, int src_dirfd, const char *src_name, - int dst_dirfd, const char *dst_name) - { - char srcprocfd[32], dstprocfd[32]; - int src_fd = -1, dst_fd = -1, rc = -1; -+ struct stat sb; - - if (verbose) - printf(_("Mounting %s on %s\n"), src_name, dst_name); -@@ -311,6 +312,14 @@ static int seunshare_mount_file(int src_dirfd, const char *src_name, - goto out; - } - -+ if (fstat(src_fd, &sb) < 0) { -+ fprintf(stderr, _("Failed to stat %s: %m\n"), src_name); -+ goto out; -+ -+ } -+ if (check_owner_uid(uid, src_name, &sb)) -+ goto out; -+ - dst_fd = openat(dst_dirfd, dst_name, O_PATH | O_NOFOLLOW | O_CLOEXEC); - if (dst_fd < 0 && errno == ENOENT) - dst_fd = openat(dst_dirfd, dst_name, -@@ -321,6 +330,14 @@ static int seunshare_mount_file(int src_dirfd, const char *src_name, - goto out; - } - -+ if (fstat(dst_fd, &sb) < 0) { -+ fprintf(stderr, _("Failed to stat %s: %m\n"), dst_name); -+ goto out; -+ -+ } -+ if (check_owner_uid(uid, dst_name, &sb)) -+ goto out; -+ - snprintf(srcprocfd, sizeof(srcprocfd), "/proc/self/fd/%d", src_fd); - snprintf(dstprocfd, sizeof(dstprocfd), "/proc/self/fd/%d", dst_fd); - -@@ -1080,14 +1097,14 @@ int main(int argc, char **argv) { - - if (runuserdir_s && (wayland_display || pipewire_socket)) { - if (wayland_display && -- seunshare_mount_file(fd_runtime_dir, -+ seunshare_mount_file(uid, fd_runtime_dir, - wayland_display, - fd_runuserdir_s, - wayland_display) == -1) - goto childerr; - - if (pipewire_socket && -- seunshare_mount_file(fd_runtime_dir, -+ seunshare_mount_file(uid, fd_runtime_dir, - "pipewire-0", - fd_runuserdir_s, - pipewire_socket) == -1) --- -2.54.0 - diff --git a/0023-sandbox-seunshare-fix-fd_tmpdir_r-check.patch b/0023-sandbox-seunshare-fix-fd_tmpdir_r-check.patch deleted file mode 100644 index f14c4a2..0000000 --- a/0023-sandbox-seunshare-fix-fd_tmpdir_r-check.patch +++ /dev/null @@ -1,29 +0,0 @@ -From d99b5a313a2790b1ca703023112f548cbe65617a Mon Sep 17 00:00:00 2001 -From: Stephen Smalley -Date: Tue, 19 May 2026 08:13:40 -0400 -Subject: [PATCH] sandbox/seunshare: fix fd_tmpdir_r check -Content-type: text/plain - -Check fd_tmpdir_r not fd for a failed pin_dir() here. - -Signed-off-by: Stephen Smalley ---- - sandbox/seunshare.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c -index 3afe1554ae56..7a4233fbee00 100644 ---- a/sandbox/seunshare.c -+++ b/sandbox/seunshare.c -@@ -1034,7 +1034,7 @@ int main(int argc, char **argv) { - */ - if (tmpdir_r) { - fd_tmpdir_r = pin_dir(tmpdir_r, &sb); -- if (fd < 0) -+ if (fd_tmpdir_r < 0) - goto childerr; - /* - * tmpdir_r checks differ in that it is --- -2.54.0 - diff --git a/0024-restorecond-Do-not-unlink-pidfile-if-not-used.patch b/0024-restorecond-Do-not-unlink-pidfile-if-not-used.patch deleted file mode 100644 index cdeef2c..0000000 --- a/0024-restorecond-Do-not-unlink-pidfile-if-not-used.patch +++ /dev/null @@ -1,30 +0,0 @@ -From a063bc28044a23dd7aa0c496c52a9c9ff4abd349 Mon Sep 17 00:00:00 2001 -From: Petr Lautrbach -Date: Mon, 25 May 2026 18:11:21 +0200 -Subject: [PATCH] restorecond: Do not unlink pidfile if not used -Content-type: text/plain - -With -F or -d, restorecond does not create nor use pidfile and therefore -it should not try to remove it. - -Signed-off-by: Petr Lautrbach ---- - restorecond/restorecond.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/restorecond/restorecond.c b/restorecond/restorecond.c -index 36f82ae5e9cb..6353b3b72798 100644 ---- a/restorecond/restorecond.c -+++ b/restorecond/restorecond.c -@@ -217,6 +217,8 @@ int main(int argc, char **argv) - if (daemon(0, 0) < 0) - exitApp("daemon"); - write_pid_file(); -+ } else { -+ pidfile = 0; - } - - while (watch(master_fd, watch_file) == 0) { --- -2.54.0 - diff --git a/changelog b/changelog index bb32e33..64e43a1 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,6 @@ +* Wed Jul 01 2026 Petr Lautrbach - 3.11-1 +- SELinux userspace 3.11 release + * Mon May 25 2026 Petr Lautrbach - 3.10-3 - Several sandbox and seunshare security improvements diff --git a/policycoreutils.spec b/policycoreutils.spec index aa6f33e..8753a7a 100644 --- a/policycoreutils.spec +++ b/policycoreutils.spec @@ -1,7 +1,7 @@ %global libauditver 4.0 -%global libsepolver 3.10-1 -%global libsemanagever 3.10-1 -%global libselinuxver 3.10-1 +%global libsepolver 3.11-1 +%global libsemanagever 3.11-1 +%global libselinuxver 3.11-1 %global generatorsdir %{_prefix}/lib/systemd/system-generators @@ -10,13 +10,13 @@ Summary: SELinux policy core utilities Name: policycoreutils -Version: 3.10 -Release: 3%{?dist} +Version: 3.11 +Release: 1%{?dist} License: GPL-2.0-or-later # https://github.com/SELinuxProject/selinux/wiki/Releases Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/selinux-%{version}.tar.gz Source1: https://github.com/SELinuxProject/selinux/releases/download/%{version}/selinux-%{version}.tar.gz.asc -Source2: https://github.com/perfinion.gpg +Source2: https://github.com/bachradsusi.gpg Source3: changelog Source4: macros URL: https://github.com/SELinuxProject/selinux @@ -37,7 +37,7 @@ Source22: selinux-gui.zip # wlc --key --url https://translate.fedoraproject.org/api/ download selinux/sandbox --output ./ Source23: selinux-sandbox.zip # https://github.com/fedora-selinux/selinux -# $ git format-patch -N 3.10 -- policycoreutils python gui sandbox dbus semodule-utils restorecond +# $ git format-patch -N 3.11 -- policycoreutils python gui sandbox dbus semodule-utils restorecond # $ for j in [0-9]*.patch; do printf "Patch%s: %s\n" ${j/-*/} $j; done # Patch list start Patch0001: 0001-Don-t-be-verbose-if-you-are-not-on-a-tty.patch @@ -46,24 +46,8 @@ Patch0003: 0003-sandbox-Use-matchbox-window-manager-instead-of-openb.patch Patch0004: 0004-Use-SHA-2-instead-of-SHA-1.patch Patch0005: 0005-python-sepolicy-Fix-spec-file-dependencies.patch Patch0006: 0006-sepolicy-Fix-detection-of-writeable-locations.patch -Patch0007: 0007-restorecond-Add-F-for-run-in-foreground.patch -Patch0008: 0008-restorecond.service-Use-Type-simple.patch -Patch0009: 0009-seunshare-guard-fallible-function-calls-by-checking-.patch -Patch0010: 0010-sandbox-seunshare-pass-O_NOFOLLOW-to-openat.patch -Patch0011: 0011-sandbox-seunshare-switch-seunshare_mount_file-to-use.patch -Patch0012: 0012-sandbox-seunshare-fix-error-checking-for-setfsuid.patch -Patch0013: 0013-sandbox-seunshare-remount-tmp-and-var-tmp-with-the-p.patch -Patch0014: 0014-sandbox-seunshare-prevent-rsync-from-interpreting-pa.patch -Patch0015: 0015-sandbox-seunshare-fix-getopt-flags.patch -Patch0016: 0016-sandbox-seunshare-prevent-path-traversal-via-W-P.patch -Patch0017: 0017-sandbox-seunshare-verify-RUNTIME_DIR-before-use.patch -Patch0018: 0018-sandbox-seunshare-drop-unused-runuserdir_r.patch -Patch0019: 0019-sandbox-seunshare-fix-killall-realloc-and-missing-ty.patch -Patch0020: 0020-sandbox-seunshare-rewrite-to-pin-directories-before-.patch -Patch0021: 0021-sandbox-seunshare-fully-check-setfsuid-calls.patch -Patch0022: 0022-sandbox-seunshare-check-owner-in-seunshare_mount_fil.patch -Patch0023: 0023-sandbox-seunshare-fix-fd_tmpdir_r-check.patch -Patch0024: 0024-restorecond-Do-not-unlink-pidfile-if-not-used.patch +Patch0007: 0007-Revert-libselinux-python-Use-system-Python3-build-mo.patch +Patch0008: 0008-Revert-python-sepolicy-update-for-modern-python-buil.patch # Patch list end # gen_changelog @@ -79,7 +63,8 @@ Provides: /sbin/restorecon BuildRequires: gcc make BuildRequires: pam-devel libsepol-static >= %{libsepolver} libsemanage-devel >= %{libsemanagever} libselinux-devel >= %{libselinuxver} libcap-devel audit-libs-devel >= %{libauditver} gettext BuildRequires: desktop-file-utils dbus-devel glib2-devel -BuildRequires: python3-devel python3-setuptools python3-wheel python3-pip +BuildRequires: python3-devel python3-setuptools python3-pip +BuildRequires: (python3-wheel if python3-setuptools < 71) BuildRequires: systemd BuildRequires: git-core BuildRequires: gnupg2 diff --git a/sources b/sources index 55752eb..6175871 100644 --- a/sources +++ b/sources @@ -2,5 +2,5 @@ SHA512 (selinux-policycoreutils.zip) = 0df9dc274e0d1a2e4e2467f95a18a5bf7b6de2428 SHA512 (selinux-python.zip) = 35d209f8bcff498f66465499fcc4cef0780781276a4ba060b2d1d56eed1dd72d253f6b0eae5f679d46cf426b967a7aadac909363513be5d483c95a31249eacdd SHA512 (selinux-sandbox.zip) = ecbc0c8280eb6c013b039a2e63ee5a361cd84807613962a012ac0a98092357e9809bea23c3c71bd8ae4745b1dd12a4fce43db5e1cab31614f386a2a8db88b733 SHA512 (selinux-gui.zip) = 3ae41eba5dd6d34e10dfdb97f4194d170ace2f3044e984077db7d26d05bdaad86625e48e5694e3e8680487ad99a50861d4bea30c4bf08e2820e3b7a8671270c7 -SHA512 (selinux-3.10.tar.gz) = 40ada85709ad23c368579bc661661ac77f4ada6d9a65243bc25de8e46202baed264d1b49de1765d5dd21ebc8d94d872b86d2b0e7b56a7269f1942d609ff7278e -SHA512 (selinux-3.10.tar.gz.asc) = 5efaecb97be2da435c7ece88e213dd753a4c6ee6f6a2726f25b82b0e30c77a5136efb593fb9590c0395f0c63e9536abf407dcec95b3d62027defbeafaa5d4b91 +SHA512 (selinux-3.11.tar.gz) = 67a460e0ee8c652ee88b1defb56ae2cb9d46c45a3a92d4add631cb7073377a846f31901a8fa659a664e7c3190531f58d774c99321d7870b542a99e033a16df32 +SHA512 (selinux-3.11.tar.gz.asc) = 866acdc35ff2e6450cefe1a5350c537aa5877c1ee6c39b985e3bfde8f12558b9df890450ce34b8463590abe54033052474267453d6820675f9b1d0e36dd43fcf