public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/libselinux] f44: Add support for UTF-8 in file context specifications
@ 2026-09-07 12:34 Petr Lautrbach
0 siblings, 0 replies; only message in thread
From: Petr Lautrbach @ 2026-09-07 12:34 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/libselinux
Branch : f44
Commit : b756484481d400807162729464a9ecb85c97ed3c
Author : Petr Lautrbach <lautrbach@redhat.com>
Date : 2026-09-07T14:10:58+02:00
Stats : +298/-1 in 5 file(s)
URL : https://src.fedoraproject.org/rpms/libselinux/c/b756484481d400807162729464a9ecb85c97ed3c?branch=f44
Log:
Add support for UTF-8 in file context specifications
Fixes: rhbz#2427550
---
diff --git a/0002-libselinux-Replace-PyString_FromString-with-PyUnicod.patch b/0002-libselinux-Replace-PyString_FromString-with-PyUnicod.patch
new file mode 100644
index 0000000..7b19aba
--- /dev/null
+++ b/0002-libselinux-Replace-PyString_FromString-with-PyUnicod.patch
@@ -0,0 +1,56 @@
+From dc98eba184e63720cc53cc9b921e535c0951107d Mon Sep 17 00:00:00 2001
+From: Petr Lautrbach <lautrbach@redhat.com>
+Date: Thu, 6 Aug 2026 16:28:30 +0200
+Subject: [PATCH] libselinux: Replace PyString_FromString with
+ PyUnicode_FromString for SWIG 4.5.0 compatibility
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Content-type: text/plain
+
+SWIG 4.5.0 removed Python 2 C API compatibility macros (PyInt_*,
+PyString_*, SWIG_Python_str_*) from its runtime header pyhead.swg.
+These macros previously mapped deprecated Python 2 C API names to their
+Python 3 equivalents.
+
+Fixes: https://github.com/SELinuxProject/selinux/issues/538
+Authored-by: Jitka Plesníková <jplesnik@redhat.com>
+Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
+---
+ libselinux/src/selinuxswig_python.i | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i
+index 03ed296d5b85..17a2620d46f7 100644
+--- a/libselinux/src/selinuxswig_python.i
++++ b/libselinux/src/selinuxswig_python.i
+@@ -69,7 +69,7 @@ def install(src, dest):
+ PyObject* list = PyList_New(*$2);
+ int i;
+ for (i = 0; i < *$2; i++) {
+- PyList_SetItem(list, i, PyString_FromString((*$1)[i]));
++ PyList_SetItem(list, i, PyUnicode_FromString((*$1)[i]));
+ }
+ $result = SWIG_AppendOutput($result, list);
+ }
+@@ -102,7 +102,7 @@ def install(src, dest):
+ len++;
+ plist = PyList_New(len);
+ for (i = 0; i < len; i++) {
+- PyList_SetItem(plist, i, PyString_FromString((*$1)[i]));
++ PyList_SetItem(plist, i, PyUnicode_FromString((*$1)[i]));
+ }
+ } else {
+ plist = PyList_New(0);
+@@ -119,7 +119,7 @@ def install(src, dest):
+ if (*$1) {
+ plist = PyList_New(result);
+ for (i = 0; i < result; i++) {
+- PyList_SetItem(plist, i, PyString_FromString((*$1)[i]));
++ PyList_SetItem(plist, i, PyUnicode_FromString((*$1)[i]));
+ }
+ } else {
+ plist = PyList_New(0);
+--
+2.55.0
+
diff --git a/0003-libselinux-restorecon_xattr-reset-dir_xattr_list-on-.patch b/0003-libselinux-restorecon_xattr-reset-dir_xattr_list-on-.patch
new file mode 100644
index 0000000..00d7a52
--- /dev/null
+++ b/0003-libselinux-restorecon_xattr-reset-dir_xattr_list-on-.patch
@@ -0,0 +1,60 @@
+From a25169403c6858b0727ae875ffaf8b6ea8fbd246 Mon Sep 17 00:00:00 2001
+From: Vit Mojzis <vmojzis@redhat.com>
+Date: Thu, 6 Aug 2026 21:37:35 +0200
+Subject: [PATCH] libselinux: restorecon_xattr: reset dir_xattr_list on every
+ call
+Content-type: text/plain
+
+selinux_restorecon_xattr(3) documents that "xattr_list must be set to
+NULL before calling selinux_restorecon_xattr(3). The caller is
+responsible for freeing the returned xattr_list entries." Commit
+b5a23d7f30c1 ("libselinux: restorecon_xattr: clear dir_xattr_* after
+freeing") reset the dir_xattr_list/dir_xattr_last statics after
+freeing them on the internal error-cleanup path of the recursive
+walk, but not on the normal success path.
+
+After a successful call, dir_xattr_list/dir_xattr_last are left
+pointing at the just-returned, now caller-owned list. Once the caller
+frees it as required and calls the function again, add_xattr_entry()
+finds dir_xattr_list non-NULL and appends the next entry through
+dir_xattr_last->next, a dangling pointer into memory the caller has
+already freed - a use-after-free write.
+
+Reset both pointers to NULL at the top of every call instead of only
+in the error path: by the API description, any list from a prior call
+is not valid.
+
+Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
+
+Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
+Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
+---
+ libselinux/src/selinux_restorecon.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
+index d48d5a83ed6e..da61f9de59f6 100644
+--- a/libselinux/src/selinux_restorecon.c
++++ b/libselinux/src/selinux_restorecon.c
+@@ -1963,6 +1963,18 @@ int selinux_restorecon_xattr(const char *pathname, unsigned int xattr_flags,
+ if (!fc_sehandle)
+ return -1;
+
++ /*
++ * The API contract requires the caller to have already freed any
++ * xattr_list returned by a previous call before calling again.
++ * Forget our own head/tail pointers to that now caller-owned memory
++ * here instead of carrying them over: leaving them set would make
++ * the next add_xattr_entry() append a new entry through
++ * dir_xattr_last, which would be dangling once the caller has freed
++ * it, resulting in a use-after-free.
++ */
++ dir_xattr_list = NULL;
++ dir_xattr_last = NULL;
++
+ if (lstat(pathname, &sb) < 0) {
+ if (errno == ENOENT)
+ return 0;
+--
+2.55.0
+
diff --git a/0004-Add-support-for-UTF-8-in-file-context-specifications.patch b/0004-Add-support-for-UTF-8-in-file-context-specifications.patch
new file mode 100644
index 0000000..c1a106d
--- /dev/null
+++ b/0004-Add-support-for-UTF-8-in-file-context-specifications.patch
@@ -0,0 +1,175 @@
+From 3ca3ef388cc6593b2b07bc06617e33e48dff9b5e Mon Sep 17 00:00:00 2001
+From: Petr Lautrbach <lautrbach@redhat.com>
+Date: Fri, 4 Sep 2026 14:11:30 +0200
+Subject: [PATCH] Add support for UTF-8 in file context specifications
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Content-type: text/plain
+
+Implement support for UTF-8 symbols in file specifications. Strings
+representing paths are processed as bytes so if users need to use
+wildcards on non-ascii symbols, they need to put them in pcre groups,
+e.g. "/opt/žluťou(č)+"
+
+This brings some overhead and so it's possible to disable UTF-8 support
+build time using DISABLE_UTF=y environment variable.
+
+Fixes:
+ # cat unicode.cil
+ (filecon "/opt/žluťoučký(/.*)?" any (system_u object_r user_home_t ((s0) (s0))))
+
+ # semodule -i unicode.cil
+ /sbin/setfiles: /var/lib/selinux/final/targeted/contexts/files/file_contexts: line 2145 error due to: Non-ASCII characters found
+ /sbin/setfiles: /var/lib/selinux/final/targeted/contexts/files/file_contexts: line 2145 error due to: Non-ASCII characters found
+ /var/lib/selinux/final/targeted/contexts/files/file_contexts: Invalid argument
+ libsemanage.semanage_validate_and_compile_fcontexts: setfiles returned error code 1.
+ semodule: Failed!
+
+ # semanage fcontext --add -t user_home_t "/opt/žluťoučký(/.*)?"
+ /sbin/setfiles: /var/lib/selinux/final/targeted/contexts/files/file_contexts.local: line 4 error due to: Non-ASCII characters found
+ /sbin/setfiles: /var/lib/selinux/final/targeted/contexts/files/file_contexts.local: line 4 error due to: Non-ASCII characters found
+ /var/lib/selinux/final/targeted/contexts/files/file_contexts: Invalid argument
+ libsemanage.semanage_validate_and_compile_fcontexts: setfiles returned error code 1.
+ OSError: Error
+
+Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
+Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
+---
+ libselinux/Makefile | 4 ++
+ libselinux/src/label_support.c | 83 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 87 insertions(+)
+
+diff --git a/libselinux/Makefile b/libselinux/Makefile
+index aeede2b56e8e..0f8412ccf1ea 100644
+--- a/libselinux/Makefile
++++ b/libselinux/Makefile
+@@ -3,6 +3,7 @@ SUBDIRS = include src utils man
+ PKG_CONFIG ?= pkg-config
+ DISABLE_SETRANS ?= n
+ DISABLE_RPM ?= n
++DISABLE_UTF ?= n
+ ANDROID_HOST ?= n
+ LABEL_BACKEND_ANDROID ?= n
+ ifeq ($(ANDROID_HOST),y)
+@@ -21,6 +22,9 @@ endif
+ ifeq ($(DISABLE_X11),y)
+ DISABLE_FLAGS+= -DNO_X_BACKEND
+ endif
++ifeq ($(DISABLE_UTF),y)
++ DISABLE_FLAGS+= -DNO_UTF
++endif
+ export DISABLE_SETRANS DISABLE_RPM DISABLE_FLAGS ANDROID_HOST DISABLE_X11 LABEL_BACKEND_ANDROID
+
+ USE_PCRE2 ?= y
+diff --git a/libselinux/src/label_support.c b/libselinux/src/label_support.c
+index aea5ed19b45a..a229373af09c 100644
+--- a/libselinux/src/label_support.c
++++ b/libselinux/src/label_support.c
+@@ -13,6 +13,76 @@
+ #include <errno.h>
+ #include "label_internal.h"
+
++#ifndef NO_UTF
++
++#define UTF8tail(x) ((x) >= 0x80 && (x) <= 0xBF)
++
++static size_t utf8_char_len(const unsigned char *s)
++{
++ /* rfc3629
++ * UTF8-octets = *( UTF8-char )
++ * UTF8-char = UTF8-1 / UTF8-2 / UTF8-3 / UTF8-4
++ * UTF8-1 = %x00-7F
++ * UTF8-2 = %xC2-DF UTF8-tail
++ * UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
++ * %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
++ * UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
++ * %xF4 %x80-8F 2( UTF8-tail )
++ * UTF8-tail = %x80-BF
++ */
++ if (s[0] == '\0')
++ return 0;
++
++ if (s[0] < 0x80)
++ return 1;
++
++ if (s[0] < 0xC2 || s[1] == '\0')
++ return 0;
++
++ if (s[0] <= 0xDF && UTF8tail(s[1]))
++ return 2;
++
++ if (s[2] == '\0')
++ return 0;
++
++ /* %xE0 %xA0-BF UTF8-tail */
++ if (s[0] == 0xE0 && s[1] >= 0xA0 && s[1] <= 0xBF && UTF8tail(s[2]))
++ return 3;
++
++ /* %xE1-EC 2( UTF8-tail ) */
++ if (s[0] >= 0xE1 && s[0] <= 0xEC && UTF8tail(s[1]) && UTF8tail(s[2]))
++ return 3;
++
++ /* %xED %x80-9F UTF8-tail */
++ if (s[0] == 0xED && s[1] >= 0x80 && s[1] <= 0x9F && UTF8tail(s[2]))
++ return 3;
++
++ /* %xEE-EF 2( UTF8-tail ) */
++ if (s[0] >= 0xEE && s[0] <= 0xEF && UTF8tail(s[1]) && UTF8tail(s[2]))
++ return 3;
++
++ if (s[3] == '\0')
++ return 0;
++
++ /* %xF0 %x90-BF 2( UTF8-tail ) */
++ if (s[0] == 0xF0 && s[1] >= 0x90 && s[1] <= 0xBF && UTF8tail(s[2]) &&
++ UTF8tail(s[3]))
++ return 4;
++
++ /* %xF1-F3 3( UTF8-tail ) */
++ if (s[0] >= 0xF1 && s[0] <= 0xF3 && UTF8tail(s[1]) && UTF8tail(s[2]) &&
++ UTF8tail(s[3]))
++ return 4;
++
++ /* %xF4 %x80-8F 2( UTF8-tail ) */
++ if (s[0] == 0xF4 && s[1] >= 0x80 && s[1] <= 0x8F && UTF8tail(s[2]) &&
++ UTF8tail(s[3]))
++ return 4;
++
++ return 0;
++}
++#endif
++
+ /*
+ * Read an entry from a spec file (e.g. file_contexts)
+ * entry - Buffer to allocate for the entry.
+@@ -36,6 +106,7 @@ static inline int read_spec_entry(char **entry, const char **ptr, size_t *len,
+ *len = 0;
+
+ while (!isspace((unsigned char)**ptr) && **ptr != '\0') {
++#ifdef NO_UTF
+ if (!isascii((unsigned char)**ptr)) {
+ errno = EINVAL;
+ *errbuf = "Non-ASCII characters found";
+@@ -43,6 +114,18 @@ static inline int read_spec_entry(char **entry, const char **ptr, size_t *len,
+ }
+ (*ptr)++;
+ (*len)++;
++#else
++ size_t char_len = utf8_char_len((const unsigned char *)*ptr);
++
++ if (char_len == 0) {
++ errno = EINVAL;
++ *errbuf = "Invalid UTF-8 encoding";
++ return -1;
++ }
++
++ *ptr += char_len;
++ *len += char_len;
++#endif
+ }
+
+ if (*len) {
+--
+2.55.0
+
diff --git a/changelog b/changelog
index 55ef0fd..604bb92 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,6 @@
+* Mon Sep 07 2026 Petr Lautrbach <lautrbach@redhat.com> - 3.11-2
+- Add support for UTF-8 in file context specifications
+
* Wed Jul 01 2026 Petr Lautrbach <lautrbach@redhat.com> - 3.11-1
- SELinux userspace 3.11 release
diff --git a/libselinux.spec b/libselinux.spec
index 4e0f72f..8ebe95e 100644
--- a/libselinux.spec
+++ b/libselinux.spec
@@ -4,7 +4,7 @@
Summary: SELinux library and simple utilities
Name: libselinux
Version: 3.11
-Release: 1%{?dist}
+Release: 2%{?dist}
License: LicenseRef-Fedora-Public-Domain
# https://github.com/SELinuxProject/selinux/wiki/Releases
Source0: https://github.com/SELinuxProject/selinux/releases/download/%{version}/libselinux-%{version}.tar.gz
@@ -20,6 +20,9 @@ Url: https://github.com/SELinuxProject/selinux/wiki
# $ i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done
# Patch list start
Patch0001: 0001-Use-SHA-2-instead-of-SHA-1.patch
+Patch0002: 0002-libselinux-Replace-PyString_FromString-with-PyUnicod.patch
+Patch0003: 0003-libselinux-restorecon_xattr-reset-dir_xattr_list-on-.patch
+Patch0004: 0004-Add-support-for-UTF-8-in-file-context-specifications.patch
# Patch list end
BuildRequires: gcc make
BuildRequires: ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre2-devel
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-07 12:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-07 12:34 [rpms/libselinux] f44: Add support for UTF-8 in file context specifications Petr Lautrbach
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox