Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package texlive for openSUSE:Factory checked in at 2026-03-08 17:26:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/texlive (Old) and /work/SRC/openSUSE:Factory/.texlive.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "texlive" Sun Mar 8 17:26:04 2026 rev:112 rq:1337291 version:unknown Changes: -------- --- /work/SRC/openSUSE:Factory/texlive/texlive.changes 2026-02-27 17:03:00.470955509 +0100 +++ /work/SRC/openSUSE:Factory/.texlive.new.8177/texlive.changes 2026-03-08 17:26:31.909936046 +0100 @@ -1,0 +2,15 @@ +Fri Mar 6 09:30:43 UTC 2026 - Dr. Werner Fink <[email protected]> + +- Reenable setgid usage for mktexls and texhash commands + +------------------------------------------------------------------- +Thu Mar 5 14:03:22 UTC 2026 - Dr. Werner Fink <[email protected]> + +- Fix bug boo#1258938 + * Implement selinux support for the setgid mktex Kpathsea tools + wrapper public(8) which is used for executing e.g. mktexlsr + * Develop a Policy Package module to be able to use this wrapper +- New package texlive-selinux for the Policy Package module + and its %pre, %post, %postun, and %posttrans scriplets + +------------------------------------------------------------------- New: ---- SELinux texlive_wrapper.fc texlive_wrapper.te ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ texlive.spec ++++++ --- /var/tmp/diff_new_pack.PC95Fh/_old 2026-03-08 17:26:36.530125805 +0100 +++ /var/tmp/diff_new_pack.PC95Fh/_new 2026-03-08 17:26:36.550126626 +0100 @@ -70,6 +70,10 @@ # # %bcond_without luametatex +%bcond_without selinux + +%global modulename texlive_wrapper +%global selinuxtype targeted Name: texlive Version: %{texlive_version}.%{texlive_release} @@ -270,6 +274,15 @@ BuildRequires: perl(XML::LibXSLT) BuildRequires: perl(XML::Writer::String) %endif +# SELinux +%if %{with selinux} +# Required for the Policy Package module +BuildRequires: selinux-policy-devel +BuildRequires: rpm_macro(selinux_requires_min) +%{?selinux_requires_min} +%endif +# Build public always with libselinux +BuildRequires: pkgconfig(libselinux) # Download at ftp://tug.org/texlive/historic/%{texlive_version}/ Source0: %{texlive_source}.tar.xz Source1: https://github.com/plk/biber/archive/refs/tags/v%{biber_version}.tar.gz#/biber-%{biber_version}.tar.gz @@ -281,6 +294,9 @@ Source30: texlive-rpmlintrc Source50: public.c Source51: public.8 +Source52: %{modulename}.te +Source53: %{modulename}.fc +Source55: SELinux Patch0: source.dif Patch1: source-configure.dif Patch2: source-xdvizilla.dif @@ -1754,6 +1770,9 @@ Requires(pre): user(mktex) Requires(pre): group(mktex) Requires(post): %{name}-filesystem +%if %{with selinux} +Requires: (texlive-selinux = 6.4.1 if selinux-policy-%{selinuxtype}) +%endif Requires(post): permissions Requires: %{name}-gsftopk-bin Requires(pre): %{name}-scripts-bin @@ -4024,6 +4043,22 @@ %description yplan-bin Binary files of yplan +%if %{with selinux} +%package selinux +Version: 6.4.1 +Release: 0 +Summary: SELinux policy module for texlive-kpathsea +License: LGPL-2.1-or-later +Group: System/Libraries +Requires(pre): policycoreutils +Requires(pre): %{name}-scripts +Requires(post): policycoreutils +Requires(post): %{name}-scripts + +%description selinux +This package provides the SELinux policy module for texlive-kpathsea. +%endif + %package -n libkpathsea6 Version: 6.4.1 Release: 0 @@ -4735,7 +4770,14 @@ # compile public mkdir -p %{libexecdir}/mktex - $CC ${RPM_OPT_FLAGS} -D_GNU_SOURCE -DTEXGRP='"%{texgrp}"' -DTEXUSR='"%{texusr}"' -DMKTEX='"%{_libexecdir}/mktex"' -fPIE -pie -o %{libexecdir}/mktex/public %{S:50} +%if %{with selinux} + cp -p %{S:52} %{S:53} . + make -f %{_datadir}/selinux/devel/Makefile %{modulename}.pp +%endif + FLAGS_SELINUX=-DHAVE_SELINUX + LIBS_SELINUX=-lselinux + $CC ${RPM_OPT_FLAGS} -D_GNU_SOURCE -DTEXGRP='"%{texgrp}"' -DTEXUSR='"%{texusr}"' ${FLAGS_SELINUX} \ + -DMKTEX='"%{_libexecdir}/mktex"' -fPIE -pie -o %{libexecdir}/mktex/public %{S:50} ${LIBS_SELINUX} # install our own scripts mkdir -p ${prefix}/bin @@ -5139,6 +5181,14 @@ esac ln -sf %{_libexecdir}/mktex/public %{buildroot}%{_bindir}/$mktex done +%if %{with selinux} + mkdir -p %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype} + mkdir -p %{buildroot}%{_datadir}/selinux/devel/include/distributed + install -m 0644 %{modulename}.pp %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/ + install -m 0644 %{modulename}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/ + bzip2 -9 %{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp +%endif + %if %{with zypper_posttrans} ln -sf %{_texmfdistdir}/texconfig/zypper.py \ %{buildroot}/var/adm/update-scripts/%{name}-%{version}-%{release}-zypper @@ -5199,6 +5249,24 @@ %verify_permissions -e %{_libexecdir}/mktex/public %endif +%if %{with selinux} +%post selinux +%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2 +%selinux_relabel_post -s %{selinuxtype} + +%pre selinux +%selinux_relabel_pre -s %{selinuxtype} + +%postun selinux +if test $1 = 0; then + %selinux_modules_uninstall -s %{selinuxtype} %{modulename} + %selinux_relabel_post -s %{selinuxtype} +fi + +%posttrans selinux +%selinux_relabel_post -s %{selinuxtype} +%endif + %post kpathsea-bin %if %{defined set_permissions} %set_permissions %{_libexecdir}/mktex/public @@ -6236,6 +6304,14 @@ %files yplan-bin %{_bindir}/yplan +%if %{with selinux} +%files selinux +%dir %{_datadir}/selinux/packages/%{selinuxtype}/ +%dir %{_datadir}/selinux/devel/include/distributed/ +%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.* +%{_datadir}/selinux/devel/include/distributed/%{modulename}.if +%endif + %files -n libkpathsea6 %{_libdir}/libkpathsea*.so.* ++++++ SELinux ++++++ Path Label Roll /usr/libexec/mktex/public texlive_wrapper_exec_t Gatekeeper /usr/libexec/mktex/mktexlsr texlive_target_exec_t Script /usr/libexec/mktex/mktexmf texlive_target_exec_t Script /usr/libexec/mktex/mktexpk texlive_target_exec_t Script /usr/libexec/mktex/mktextfm texlive_target_exec_t Script /usr/libexec/mktex/texhash texlive_target_exec_t Script /usr/share/texmf/scripts/... texlive_target_exec_t Entrypoint /var/cache/texmf/ tetex_data_t Data /var/lib/texmf/ tetex_data_t Data /etc/texmf/ls-R etc_t ${HOME}/bin home_bin_t ${HOME}/.local gconf_home_t ${HOME}/.local/bin home_bin_t ${HOME}/.local/share data_home_t ${HOME}/.cache cache_home_t ++++++ public.c ++++++ --- /var/tmp/diff_new_pack.PC95Fh/_old 2026-03-08 17:26:37.558168027 +0100 +++ /var/tmp/diff_new_pack.PC95Fh/_new 2026-03-08 17:26:37.598169671 +0100 @@ -28,6 +28,10 @@ #include <limits.h> #include <grp.h> #include <pwd.h> +#ifdef HAVE_SELINUX +#include <selinux/selinux.h> +#include <selinux/context.h> +#endif #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -125,6 +129,25 @@ if ((grp = getgrnam(TEXGRP)) == (struct group*)0) goto err; +#ifdef HAVE_SELINUX + if (is_selinux_enabled() > 0) { + char *cur_con = NULL; + + if (getcon(&cur_con) == 0) { + context_t ctx = context_new(cur_con); + if (ctx) { + if (context_type_set(ctx, "texlive_target_t") == 0) { + if (setexeccon(context_str(ctx)) < 0) { + perror("FATAL: SELinux setexeccon failed"); + goto err; + } + } + context_free(ctx); + } + freecon(cur_con); + } + } +#endif if (ruid == 0 || euid == 0) { /* If user is root switch over to mktex:mktex */ int initgrp = 0; char *cwd; @@ -182,11 +205,46 @@ } } else if (rgid != grp->gr_gid && egid == grp->gr_gid) { - rgid = grp->gr_gid; - - if (setregid(rgid, grp->gr_gid)) - goto err; + const int ngroups = getgroups(0, NULL); + int in_group = 0; + if (ngroups > 0) { + int i; + gid_t *groups = malloc(ngroups * sizeof(gid_t)); + if (!groups) + goto err; + if (getgroups(ngroups, groups) >= 0) { + for (i = 0; i < ngroups; i++) { + if (groups[i] != grp->gr_gid) + continue; + in_group++; + break; + } + } + free(groups); + } + if (in_group) { + if (setregid(grp->gr_gid, grp->gr_gid)) + goto err; + } else { + if (strcmp(lp->prog, "mktexlsr") == 0 || strcmp(lp->prog, "texhash") == 0) { + egid = grp->gr_gid; + rgid = grp->gr_gid; + for (ep = envp; ep->name; ep++) { + if (!ep->value) + continue; + setenv(ep->name, ep->value, 1); + } + } else + egid = rgid; +#ifdef _GNU_SOURCE + if (setresgid(rgid, egid, rgid)) + goto err; +#else + if (setregid(rgid, egid)) + goto err; +#endif + } } umask(0002); ++++++ texlive_wrapper.fc ++++++ # 1. The location of our Wrapper, the compiled public.c /usr/libexec/mktex/public -- gen_context(system_u:object_r:texlive_wrapper_exec_t,s0) # 2. The path to our possible target programs which are # symbolic links (hence the "-l") /usr/libexec/mktex/mktexlsr -l gen_context(system_u:object_r:texlive_target_exec_t,s0) /usr/libexec/mktex/mktexmf -l gen_context(system_u:object_r:texlive_target_exec_t,s0) /usr/libexec/mktex/mktexpk -l gen_context(system_u:object_r:texlive_target_exec_t,s0) /usr/libexec/mktex/mktextfm -l gen_context(system_u:object_r:texlive_target_exec_t,s0) /usr/libexec/mktex/texhash -l gen_context(system_u:object_r:texlive_target_exec_t,s0) # 3. The real location of the target programs # The regular expression will set labels for the # directory as well as on the file therein. /usr/share/texmf/scripts/texlive(/.*)? gen_context(system_u:object_r:texlive_target_exec_t,s0) # 4. Correct labels /var/cache/texmf(/.*)? gen_context(system_u:object_r:tetex_data_t,s0) /var/lib/texmf(/.*)? gen_context(system_u:object_r:tetex_data_t,s0) /usr/local/share/texmf(/.*)? gen_context(system_u:object_r:tetex_data_t,s0) /usr/share/texmf(/.*)? gen_context(system_u:object_r:tetex_data_t,s0) ++++++ texlive_wrapper.te ++++++ policy_module(texlive_wrapper, 1.0) gen_require(` type bin_t; type etc_t; type tmp_t; type usr_t; type home_bin_t; type gconf_home_t; type cache_home_t; type data_home_t; type tmpfs_t; type cgroup_t; type tetex_data_t; type unconfined_t; type user_devpts_t; role unconfined_r; role system_r; class file { execute execute_no_trans getattr map read open write create rename setattr unlink lock }; class dir { getattr search read open write add_name remove_name create rmdir }; class lnk_file { read getattr }; class chr_file { read write getattr ioctl }; class filesystem getattr; class process { setfscreate }; ') # ========================================================== # 1. Type declaration # ========================================================== # A) Wrapper public type texlive_wrapper_t; type texlive_wrapper_exec_t; application_domain(texlive_wrapper_t, texlive_wrapper_exec_t) # B) The called program from public.c type texlive_target_t; type texlive_target_exec_t; application_domain(texlive_target_t, texlive_target_exec_t) # # Roles # role unconfined_r types { texlive_wrapper_t texlive_target_t }; role system_r types { texlive_wrapper_t texlive_target_t }; # ========================================================== # 2. Rules for public.c # ========================================================== # Allow system admin (unconfined_t), to start the Wrapper and # switch over to the Domain texlive_wrapper_t domain_auto_trans(unconfined_t, texlive_wrapper_exec_t, texlive_wrapper_t) # Allow stdio in/out to tty userdom_use_user_terminals(texlive_wrapper_t) userdom_use_user_terminals(texlive_target_t) # The ~/.cache/texmf and ~/.local/texmf of normal users userdom_search_user_home_dirs(texlive_wrapper_t) userdom_search_user_home_dirs(texlive_target_t) allow texlive_target_t home_bin_t:dir { search }; allow texlive_target_t data_home_t:dir { search getattr }; allow texlive_target_t gconf_home_t:dir { search getattr }; allow texlive_target_t cache_home_t:dir { getattr search read open write add_name remove_name create rmdir }; allow texlive_target_t cache_home_t:file { getattr read write create append open lock unlink rename setattr ioctl }; allow texlive_target_t cache_home_t:lnk_file { read getattr }; # Allow the Wrapper to change UID and GID (setuid / setgid) allow texlive_wrapper_t self:capability { setuid setgid }; # We use initgroups(), getgrnam(), and getpwnam() which will # access /etc/passwd and /etc/groups, make sure that nis/ssd/ldap # will not stop the Wrapper auth_use_nsswitch(texlive_wrapper_t) # Allow the Wrapper, to search through directories and and read files allow texlive_wrapper_t texlive_target_exec_t:dir { search getattr }; allow texlive_wrapper_t texlive_target_exec_t:file { read open getattr execute }; allow texlive_wrapper_t tetex_data_t:dir { search getattr }; # Allow perl or shell to search, open, and read the final scripts allow texlive_target_t texlive_target_exec_t:dir { search getattr read open }; allow texlive_target_t texlive_target_exec_t:file { read open getattr }; # Allow the Wrapper, to call setexeccon() for context switch allow texlive_wrapper_t self:process setexec; # Allow to resolve symbolic links allow texlive_wrapper_t texlive_target_exec_t:lnk_file { read getattr }; allow texlive_target_t texlive_target_exec_t:lnk_file { read getattr }; # Allow execution of standard binaries like /bin/sh and /usr/bin/perl corecmd_exec_bin(texlive_wrapper_t) corecmd_exec_bin(texlive_target_t) # Allow reading files below /usr files_read_usr_files(texlive_target_t) files_manage_generic_tmp_dirs(texlive_target_t) # Allow to manage TeX data files and directories (read, create, remove) # as well as symbolic links allow texlive_target_t tetex_data_t:dir { getattr search read open write add_name remove_name create rmdir }; allow texlive_target_t tetex_data_t:file { getattr read write create open lock unlink }; allow texlive_target_t tetex_data_t:lnk_file { read getattr }; # Allow to write ls-R files in /etc/ allow texlive_target_t etc_t:file { getattr read write open }; # Make mktemp work in /tmp allow texlive_target_t tmp_t:dir { getattr search read write add_name remove_name create rmdir }; allow texlive_target_t tmp_t:file { getattr read write create open lock unlink rename setattr }; allow texlive_target_t tmpfs_t:filesystem getattr; # Make the bunch of scripts work below /usr/libexec/mktex/ allow texlive_target_t texlive_target_exec_t:file { getattr read open execute execute_no_trans }; allow texlive_target_t texlive_wrapper_exec_t:file { getattr read open execute execute_no_trans }; allow texlive_target_t tetex_data_t:file { getattr read write create open lock unlink rename setattr }; allow texlive_target_t self:process setfscreate; allow texlive_target_t cgroup_t:dir { search getattr }; # ========================================================== # 3. The switch over (TRANSITION) and environment variables # ========================================================== # Allow the real switch (execv) into the final Domain allow texlive_wrapper_t texlive_target_t:process transition; # Declare the final files als valid entrypoints allow texlive_target_t texlive_target_exec_t:file entrypoint; # Do not remove the environment variables allow texlive_wrapper_t texlive_target_t:process { noatsecure siginh rlimitinh }; # Allow the final program to use stdio (stdout/stderr) of the Wrapper allow texlive_target_t texlive_wrapper_t:fd use; allow texlive_target_t texlive_wrapper_t:fifo_file rw_file_perms;
