commit: 4e8b871a3f592ed66c82fb32e99e9d7c1b92b598 Author: Kerin Millar <kfm <AT> plushkava <DOT> net> AuthorDate: Sun Sep 14 04:01:30 2025 +0000 Commit: Kerin Millar <kfm <AT> plushkava <DOT> net> CommitDate: Sun Sep 14 04:17:51 2025 +0000 URL: https://gitweb.gentoo.org/proj/locale-gen.git/commit/?id=4e8b871a
Disregard chcon(1) errors caused by ENOTSUP Version 3.5 introduced support for preserving and restoring SELinux security contexts. Where an existing archive is found to exist, locale-gen(8) executes the chcon(1) utility so as to copy the context from the old archive to the new archive, just before the former is replaced by a rename(2) syscall. This only happens in the case that the underlying filesystem is mounted with the "seclabel" option in effect. However, the presence of the mount option does not prove that the chcon(1) utility can be successfully employed. Consider a scenario in which someone installs Gentoo from an SELinux-enabled operating environment, such as Fedora. The chroot environment depicted below is one that was prepared from an ordinary "stage3-arm64-systemd" tarball. # chroot /mnt/gentoo /bin/bash # findmnt -no options -T /usr/lib/locale-archive rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota # locale-gen Found 1 locale declaration in '/etc/locale.gen'. Compiling 2 locales with 2 workers ... [1/2] Compiling locale: C.UTF-8 [2/2] Compiling locale: en_GB.UTF-8 Waiting for active workers to finish their jobs ... The location of the archive shall be '/usr/lib/locale/locale-archive'. Adding 2 locales to the locale archive ... chcon: failed to get security context of '/usr/lib/locale/locale-archive ': Operation not supported Clearly, chcon(1) is incapable of copying the security context. In turn, that's because sys-apps/coreutils hasn't been built with USE="selinux" in effect. I was able to make the utility work by copying the instance provided by Fedora into the chroot environment, along with the "libselinux.so.1" library to which it links. It is interesting to note that in a situation such as this, the files unpacked from the tarball will end up carrying security labels that are surplus to requirements. That is, the user may have no intention of using SELinux in Gentoo but will end up with a large number of files bearing a label of "unconfined_u:object_r:unlabeled_t:s0". Anyway, address this issue by capturing the standard error of chcon(1) and quietly disregarding errors where any of the captured lines are found to end with ": Operation not permitted". The C locale is duly coerced, ensuring that the error string cannot be translated to any other language. As unpalatable a solution as it may be, the alternatives that I am aware of would be worse still. Reported-by: Dennis Clarke <dc <AT> genunix.com> Fixes: 42eb5eaf744f5561e86458ba242f2514cfa80595 Closes: https://bugs.gentoo.org/962824 Bug: https://bugs.gentoo.org/962753 Signed-off-by: Kerin Millar <kfm <AT> plushkava.net> locale-gen | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/locale-gen b/locale-gen index e360da3..45919fa 100644 --- a/locale-gen +++ b/locale-gen @@ -548,7 +548,7 @@ sub install_archive ($src_path, $dst_path, $may_reset_labels) { # If a prior archive exists, attempt to preserve its SELinux label. if ($has_seclabels && $has_archive) { - run('chcon', "--reference=$dst_path", '--', $interim_path); + copy_security_context($dst_path, $interim_path); } # Activate the new archive by atomically renaming it into place. @@ -569,6 +569,18 @@ sub install_archive ($src_path, $dst_path, $may_reset_labels) { } } +sub copy_security_context ($src_path, $dst_path) { + local @ENV{'SRC_PATH', 'DST_PATH'} = ($src_path, $dst_path); + my $stderr = qx{ LC_ALL=C chcon --reference="\$SRC_PATH" -- "\$DST_PATH" 2>&1 >/dev/null }; + # Throw exceptions for any errors that are not a consequence of ENOTSUP. + if ($? != 0 && $stderr !~ m/: Operation not supported$/m) { + if (length $stderr) { + warn $stderr; + } + throw_child_error('chcon'); + } +} + sub fopen ($path, $mode = '<') { if (! open my $fh, $mode, $path) { die "$PROGRAM: Can't open '$path': $!\n";
