Hello community, here is the log from the commit of package zsh for openSUSE:Factory checked in at 2020-02-20 14:53:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/zsh (Old) and /work/SRC/openSUSE:Factory/.zsh.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "zsh" Thu Feb 20 14:53:48 2020 rev:89 rq:774851 version:5.8 Changes: -------- --- /work/SRC/openSUSE:Factory/zsh/zsh.changes 2020-02-15 22:23:28.383246555 +0100 +++ /work/SRC/openSUSE:Factory/.zsh.new.26092/zsh.changes 2020-02-20 14:53:55.814117341 +0100 @@ -1,0 +2,6 @@ +Mon Feb 17 05:18:47 UTC 2020 - Ismail Dönmez <[email protected]> + +- Update to version 5.8 + * Fixes CVE-2019-20044 bsc#1163882 + +------------------------------------------------------------------- Old: ---- zsh-5.7.1-test-3.tar.xz zsh-5.7.1-test-3.tar.xz.asc New: ---- zsh-5.8.tar.xz zsh-5.8.tar.xz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ zsh.spec ++++++ --- /var/tmp/diff_new_pack.KBH2PU/_old 2020-02-20 14:53:56.666119013 +0100 +++ /var/tmp/diff_new_pack.KBH2PU/_new 2020-02-20 14:53:56.666119013 +0100 @@ -16,9 +16,6 @@ # -# Only for -test builds -%define _version 5.7.1-test-3 - %if 0%{?rhel_version} || 0%{?centos_version} || 0%{?fedora_version} %if 0%{?rhel_version} >= 700 || 0%{?centos_version} >= 700 %global __requires_exclude ^/bin/zsh$ @@ -28,14 +25,14 @@ BuildRequires: texinfo %endif Name: zsh -Version: 5.8~pre3 +Version: 5.8 Release: 0%{?dist} Summary: Shell with comprehensive completion License: MIT Group: System/Shells URL: http://www.zsh.org -Source0: https://downloads.sourceforge.net/project/zsh/zsh-test/%{_version}/zsh-%{_version}.tar.xz -Source1: https://downloads.sourceforge.net/project/zsh/zsh-test/%{_version}/zsh-%{_version}.tar.xz.asc +Source0: https://downloads.sourceforge.net/project/zsh/zsh/%{version}/zsh-%{version}.tar.xz +Source1: https://downloads.sourceforge.net/project/zsh/zsh/%{version}/zsh-%{version}.tar.xz.asc Source2: %{name}.keyring Source3: zshrc Source4: zshenv @@ -94,7 +91,7 @@ This package contains the Zsh manual in HTML format. %prep -%setup -q -n %{name}-%{_version} +%setup -q %if 0%{?suse_version} %patch1 -p1 %endif ++++++ zsh-5.7.1-test-3.tar.xz -> zsh-5.8.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/ChangeLog new/zsh-5.8/ChangeLog --- old/zsh-5.7.1-test-3/ChangeLog 2020-02-06 20:57:35.000000000 +0100 +++ new/zsh-5.8/ChangeLog 2020-02-14 23:11:10.000000000 +0100 @@ -1,3 +1,28 @@ +2020-02-14 dana <[email protected]> + + * unposted: Config/version.mk: Update for 5.8 + + * Sam Foxman, Daniel Shahaf, dana: CVE-2019-20044: NEWS, + README, Src/openssh_bsd_setres_id.c, Src/options.c, Src/zsh.mdd, + Src/zsh_system.h, Test/E01options.ztst, Test/P01privileged.ztst, + Test/README, configure.ac: Fix insecure dropping of privileges + when unsetting PRIVILEGED option + + * unposted: Test/V01zmodload.ztst: Fix failing test from + workers/45385 + + * 45423 (tweaked): Completion/Unix/Command/_su: Improve arg + handling, shell look-ups + +2020-02-07 dana <[email protected]> + + * unposted: Completion/Unix/Command/_zip: Recognise '--' + +2020-02-06 Daniel Shahaf <[email protected]> + + * 45385: Test/V01zmodload.ztst: Add a test for 'zmodload -Fa' + preemptively disabling ("blacklisting"?) features. + 2020-02-06 dana <[email protected]> * unposted: Config/version.mk: Update for 5.7.1-test-3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Completion/Unix/Command/_su new/zsh-5.8/Completion/Unix/Command/_su --- old/zsh-5.7.1-test-3/Completion/Unix/Command/_su 2017-12-04 15:09:35.000000000 +0100 +++ new/zsh-5.8/Completion/Unix/Command/_su 2020-02-14 17:15:11.000000000 +0100 @@ -9,36 +9,44 @@ (( $words[(i)-(l|-login)] < CURRENT )) || args=( '-[use a login shell]' ) case $OSTYPE in linux*) + # Some of these options only apply to util-linux, not shadow-utils args=( -S $args - '(-c --command --session-command *)'{-c,--command=}'[pass command to shell]:command string:_cmdstring' + '(-c --command --session-command *)'{-c+,--command=}'[pass command to shell]:command string:_cmdstring' "(-c --command *)--session-command=[pass command to shell and don't create a new session]:command string:_cmdstring" '(--fast -f)'{-f,--fast}'[pass -f to shell]' '(-l --login -m -p --preserve-environment)'{-l,--login}'[use a login shell]' '(-l --login -m -p --preserve-environment)'{-m,-p,--preserve-environment}"[don't reset environment]" - '(-s --shell)'{-s,--shell=}'[run the specified shell]:shell:->shells' + '(-s --shell)'{-s+,--shell=}'[run the specified shell]:shell:->shells' '(-)--help[display help information]' '(-)--version[display version information]' ) - (( EUID )) || args+=( - '(-g --group)'{-g,--group=}'[specify primary group]:group:_groups' - \*{-G,--supp-group=}'[specify supplemental group]:group:_groups' + (( $#_comp_priv_prefix || EUID == 0 )) && args+=( + '(-g --group)'{-g+,--group=}'[specify primary group]:group:_groups' + \*{-G+,--supp-group=}'[specify supplemental group]:group:_groups' ) first="(--help --version)${first#???}" ;; *bsd*|darwin*|dragonfly*) args+=( - '-c[use settings from specified login class]:class' '-f[if the invoked shell is csh, prevent it from reading .cshrc]' '(-m)-l[use a login shell]' "(-l)-m[don't reset environment]" ) ;| + *bsd*|dragonfly*) + args+=( + '-c+[use settings from specified login class]:class' + ) + ;| freebsd*) args+=( '-s[set the MAC label]' ) ;; openbsd*) args+=( - '(-K)-a[specify authentication type]:authentication type' + # See login.conf(5) + '(-K)-a+[specify authentication type]:authentication type:( + activ chpass crypto lchpass passwd radius reject skey snk token yubikey + )' '(-a)-K[shorthand for -a passwd]' - '-s[run the specified shell]:shell:->shells' + '-s+[run the specified shell]:shell:->shells' '-L[loop until login succeeds]' ) ;; @@ -57,13 +65,26 @@ _arguments $args ${(e)first} "*:shell arguments:= ->rest" && return -usr=${line[norm]/--/root} -if (( $#opt_args[(i)-(s|-shell)] )); then +usr=${${(Q)line[norm]}/--/root} +# OpenBSD supports appending a log-in method to the user name, as in usr:radius +[[ $OSTYPE == openbsd* ]] && usr=${usr%:*} + +# Normal users generally don't appear in passwd on macOS; try the Directory +# Service first +if [[ $OSTYPE == darwin* ]] && (( $+commands[dscl] )); then + shell=${"$( + _call_program shells dscl . -read /Users/${(q)usr} UserShell + )"#UserShell: } +fi + +if [[ -n $shell ]]; then + : # Found above +elif (( ${#${(@M)args:#*-s[+\[]*:*}} && $#opt_args[(i)-(s|-shell)] )); then shell=${(v)opt_args[(i)-(s|-shell)]} elif (( ${+commands[getent]} )); then - shell="${$(_call_program shells getent passwd $usr)##*:}" + shell="${$(_call_program shells getent passwd ${(q)usr})##*:}" else - shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}" + shell="${${(M@)${(@f)$(</etc/passwd)}:#${usr}:*}##*:}" fi case $state in diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Completion/Unix/Command/_zip new/zsh-5.8/Completion/Unix/Command/_zip --- old/zsh-5.7.1-test-3/Completion/Unix/Command/_zip 2017-12-04 15:09:35.000000000 +0100 +++ new/zsh-5.8/Completion/Unix/Command/_zip 2020-02-14 17:15:11.000000000 +0100 @@ -82,7 +82,7 @@ '*:file:->files' && ret=0 ;; unzip) - _arguments -C -s \ + _arguments -C -s -S \ '(-Z)-M[page output]' \ - unzip \ '(-f -u -l -t -z -d -p)-c[extract files to stdout including file names]' \ @@ -130,7 +130,7 @@ [[ $state == zipinfo ]] && uzi="-Z[zipinfo mode]" if [[ $service == zipinfo ]] || [[ -n $uzi ]]; then - _arguments -C -s \ + _arguments -C -s -S \ $uzi \ '(-2 -s -m -l -v -h -t -T -z)-1[filenames only]' \ '(-1 -s -m -l -v -T)-2[just filenames but allow -h/-t/-z]' \ @@ -170,7 +170,7 @@ fi 2>/dev/null if [[ $zipfile != $_zip_cache_name ]]; then _zip_cache_name="$zipfile" - _zip_cache_list=( ${(f)"$(zipinfo -1 $_zip_cache_name)"} ) + _zip_cache_list=( ${(f)"$(zipinfo -1 -- $_zip_cache_name)"} ) fi _wanted files expl 'file from archive' \ _multi_parts / _zip_cache_list && return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Config/version.mk new/zsh-5.8/Config/version.mk --- old/zsh-5.7.1-test-3/Config/version.mk 2020-02-06 20:56:06.000000000 +0100 +++ new/zsh-5.8/Config/version.mk 2020-02-14 23:11:10.000000000 +0100 @@ -27,5 +27,5 @@ # This must also serve as a shell script, so do not add spaces around the # `=' signs. -VERSION=5.7.1-test-3 -VERSION_DATE='February 6, 2020' +VERSION=5.8 +VERSION_DATE='February 14, 2020' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/version.yo new/zsh-5.8/Doc/version.yo --- old/zsh-5.7.1-test-3/Doc/version.yo 2020-02-06 21:06:20.000000000 +0100 +++ new/zsh-5.8/Doc/version.yo 2020-02-14 23:13:00.000000000 +0100 @@ -1,6 +1,6 @@ IFDEF(INCWSLEVEL)(INCWSLEVEL())(STARTDEF()) -def(version)(0)(5.7.1-test-3) -def(date)(0)(February 6, 2020) +def(version)(0)(5.8) +def(date)(0)(February 14, 2020) def(zshenv)(0)(/etc/zshenv) def(zprofile)(0)(/etc/zprofile) def(zshrc)(0)(/etc/zshrc) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zsh.1 new/zsh-5.8/Doc/zsh.1 --- old/zsh-5.7.1-test-3/Doc/zsh.1 2020-02-06 21:06:20.000000000 +0100 +++ new/zsh-5.8/Doc/zsh.1 2020-02-14 23:13:01.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSH" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSH" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zsh \- the Z shell .\" Yodl file: Zsh/intro.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zsh.texi new/zsh-5.8/Doc/zsh.texi --- old/zsh-5.7.1-test-3/Doc/zsh.texi 2020-02-06 21:06:27.000000000 +0100 +++ new/zsh-5.8/Doc/zsh.texi 2020-02-14 23:13:08.000000000 +0100 @@ -27,8 +27,8 @@ @end iftex @titlepage @title The Z Shell Manual -@subtitle Version 5.7.1-test-3 -@subtitle Updated February 6, 2020 +@subtitle Version 5.8 +@subtitle Updated February 14, 2020 @author Original documentation by Paul Falstad @page This is a texinfo version of the documentation for the Z Shell, originally by @@ -63,7 +63,7 @@ @noindent @cindex version -Version 5.7.1-test-3, last updated February 6, 2020. +Version 5.8, last updated February 14, 2020. @end ifinfo @menu @@ -34876,7 +34876,7 @@ @noindent @example mkdir ~/zsh_help -perl ~/zsh-5.7.1-test-3/Util/helpfiles ~/zsh_help +perl ~/zsh-5.8/Util/helpfiles ~/zsh_help @end example @noindent @@ -35037,7 +35037,7 @@ @noindent @example -zsh -f ~/zsh-5.7.1-test-3/Functions/Misc/zkbd +zsh -f ~/zsh-5.8/Functions/Misc/zkbd @end example @noindent @@ -35102,7 +35102,7 @@ @noindent @example -. ~/zsh-5.7.1-test-3/Util/reporter > zsh.report +. ~/zsh-5.8/Util/reporter > zsh.report @end example @noindent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshall.1 new/zsh-5.8/Doc/zshall.1 --- old/zsh-5.7.1-test-3/Doc/zshall.1 2020-02-06 21:06:24.000000000 +0100 +++ new/zsh-5.8/Doc/zshall.1 2020-02-14 23:13:05.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHALL" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHALL" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshall \- the Z shell meta\-man page .\" Yodl file: Zsh/intro.yo @@ -476,7 +476,7 @@ .so man1/zshtcpsys.1 .so man1/zshzftpsys.1 .so man1/zshcontrib.1 -.TH "ZSHALL" "1" "February 6, 2020" "zsh 5\&.7\&.1\-test\-3" +.TH "ZSHALL" "1" "February 14, 2020" "zsh 5\&.8" .\" Yodl file: Zsh/filelist.yo .SH "FILES" .PD 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshbuiltins.1 new/zsh-5.8/Doc/zshbuiltins.1 --- old/zsh-5.7.1-test-3/Doc/zshbuiltins.1 2020-02-06 21:06:20.000000000 +0100 +++ new/zsh-5.8/Doc/zshbuiltins.1 2020-02-14 23:13:01.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHBUILTINS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHBUILTINS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshbuiltins \- zsh built\-in commands .\" Yodl file: Zsh/builtins.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshcalsys.1 new/zsh-5.8/Doc/zshcalsys.1 --- old/zsh-5.7.1-test-3/Doc/zshcalsys.1 2020-02-06 21:06:21.000000000 +0100 +++ new/zsh-5.8/Doc/zshcalsys.1 2020-02-14 23:13:01.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHCALSYS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHCALSYS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshcalsys \- zsh calendar system .\" Yodl file: Zsh/calsys.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshcompctl.1 new/zsh-5.8/Doc/zshcompctl.1 --- old/zsh-5.7.1-test-3/Doc/zshcompctl.1 2020-02-06 21:06:21.000000000 +0100 +++ new/zsh-5.8/Doc/zshcompctl.1 2020-02-14 23:13:01.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHCOMPCTL" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHCOMPCTL" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshcompctl \- zsh programmable completion .\" Yodl file: Zsh/compctl.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshcompsys.1 new/zsh-5.8/Doc/zshcompsys.1 --- old/zsh-5.7.1-test-3/Doc/zshcompsys.1 2020-02-06 21:06:21.000000000 +0100 +++ new/zsh-5.8/Doc/zshcompsys.1 2020-02-14 23:13:02.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHCOMPSYS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHCOMPSYS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshcompsys \- zsh completion system .\" Yodl file: Zsh/compsys.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshcompwid.1 new/zsh-5.8/Doc/zshcompwid.1 --- old/zsh-5.7.1-test-3/Doc/zshcompwid.1 2020-02-06 21:06:21.000000000 +0100 +++ new/zsh-5.8/Doc/zshcompwid.1 2020-02-14 23:13:01.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHCOMPWID" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHCOMPWID" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshcompwid \- zsh completion widgets .\" Yodl file: Zsh/compwid.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshcontrib.1 new/zsh-5.8/Doc/zshcontrib.1 --- old/zsh-5.7.1-test-3/Doc/zshcontrib.1 2020-02-06 21:06:22.000000000 +0100 +++ new/zsh-5.8/Doc/zshcontrib.1 2020-02-14 23:13:02.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHCONTRIB" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHCONTRIB" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshcontrib \- user contributions to zsh .\" Yodl file: Zsh/contrib.yo @@ -41,7 +41,7 @@ .RS .nf \fBmkdir ~/zsh_help -perl ~/zsh\-5\&.7\&.1\-test\-3/Util/helpfiles ~/zsh_help\fP +perl ~/zsh\-5\&.8/Util/helpfiles ~/zsh_help\fP .fi .RE .PP @@ -181,7 +181,7 @@ .PP .RS .nf -\fBzsh \-f ~/zsh\-5\&.7\&.1\-test\-3/Functions/Misc/zkbd\fP +\fBzsh \-f ~/zsh\-5\&.8/Functions/Misc/zkbd\fP .fi .RE .PP @@ -237,7 +237,7 @@ .PP .RS .nf -\fB\&. ~/zsh\-5\&.7\&.1\-test\-3/Util/reporter > zsh\&.report\fP +\fB\&. ~/zsh\-5\&.8/Util/reporter > zsh\&.report\fP .fi .RE .PP diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshexpn.1 new/zsh-5.8/Doc/zshexpn.1 --- old/zsh-5.7.1-test-3/Doc/zshexpn.1 2020-02-06 21:06:22.000000000 +0100 +++ new/zsh-5.8/Doc/zshexpn.1 2020-02-14 23:13:03.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHEXPN" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHEXPN" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshexpn \- zsh expansion and substitution .\" Yodl file: Zsh/expn.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshmisc.1 new/zsh-5.8/Doc/zshmisc.1 --- old/zsh-5.7.1-test-3/Doc/zshmisc.1 2020-02-06 21:06:22.000000000 +0100 +++ new/zsh-5.8/Doc/zshmisc.1 2020-02-14 23:13:03.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHMISC" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHMISC" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshmisc \- everything and then some .\" Yodl file: Zsh/grammar.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshmodules.1 new/zsh-5.8/Doc/zshmodules.1 --- old/zsh-5.7.1-test-3/Doc/zshmodules.1 2020-02-06 21:06:23.000000000 +0100 +++ new/zsh-5.8/Doc/zshmodules.1 2020-02-14 23:13:03.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHMODULES" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHMODULES" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshmodules \- zsh loadable modules .\" Yodl file: Zsh/modules.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshoptions.1 new/zsh-5.8/Doc/zshoptions.1 --- old/zsh-5.7.1-test-3/Doc/zshoptions.1 2020-02-06 21:06:23.000000000 +0100 +++ new/zsh-5.8/Doc/zshoptions.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHOPTIONS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHOPTIONS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshoptions \- zsh options .\" Yodl file: Zsh/options.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshparam.1 new/zsh-5.8/Doc/zshparam.1 --- old/zsh-5.7.1-test-3/Doc/zshparam.1 2020-02-06 21:06:23.000000000 +0100 +++ new/zsh-5.8/Doc/zshparam.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHPARAM" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHPARAM" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshparam \- zsh parameters .\" Yodl file: Zsh/params.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshroadmap.1 new/zsh-5.8/Doc/zshroadmap.1 --- old/zsh-5.7.1-test-3/Doc/zshroadmap.1 2020-02-06 21:06:23.000000000 +0100 +++ new/zsh-5.8/Doc/zshroadmap.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHROADMAP" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHROADMAP" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshroadmap \- informal introduction to the zsh manual .\" Yodl file: Zsh/roadmap.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshtcpsys.1 new/zsh-5.8/Doc/zshtcpsys.1 --- old/zsh-5.7.1-test-3/Doc/zshtcpsys.1 2020-02-06 21:06:23.000000000 +0100 +++ new/zsh-5.8/Doc/zshtcpsys.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHTCPSYS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHTCPSYS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshtcpsys \- zsh tcp system .\" Yodl file: Zsh/tcpsys.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshzftpsys.1 new/zsh-5.8/Doc/zshzftpsys.1 --- old/zsh-5.7.1-test-3/Doc/zshzftpsys.1 2020-02-06 21:06:24.000000000 +0100 +++ new/zsh-5.8/Doc/zshzftpsys.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHZFTPSYS" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHZFTPSYS" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshzftpsys \- zftp function front\-end .\" Yodl file: Zsh/zftpsys.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Doc/zshzle.1 new/zsh-5.8/Doc/zshzle.1 --- old/zsh-5.7.1-test-3/Doc/zshzle.1 2020-02-06 21:06:24.000000000 +0100 +++ new/zsh-5.8/Doc/zshzle.1 2020-02-14 23:13:04.000000000 +0100 @@ -1,4 +1,4 @@ -.TH "ZSHZLE" "1" "February 6, 2020" "zsh 5\&.7\&.1-test-3" +.TH "ZSHZLE" "1" "February 14, 2020" "zsh 5\&.8" .SH "NAME" zshzle \- zsh command line editor .\" Yodl file: Zsh/zle.yo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/NEWS new/zsh-5.8/NEWS --- old/zsh-5.7.1-test-3/NEWS 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/NEWS 2020-02-14 23:06:58.000000000 +0100 @@ -4,8 +4,22 @@ Note also the list of incompatibilities in the README file. -Changes since 5.7.1 -------------------- +Changes since 5.7.1-test-3 +-------------------------- + +CVE-2019-20044: When unsetting the PRIVILEGED option, the shell sets its +effective user and group IDs to match their respective real IDs. On some +platforms (including Linux and macOS, but not FreeBSD), when the RUID and +EUID were both non-zero, it was possible to regain the shell's former +privileges by e.g. assigning to the EUID or EGID parameter. In the course +of investigating this issue, it was also found that the setopt built-in +did not correctly report errors when unsetting the option, which +prevented users from handling them as the documentation recommended. +setopt now returns non-zero if it is unable to safely drop privileges. +[ Reported by Sam Foxman <[email protected]>. ] + +Changes from 5.7.1 to 5.7.1-test-3 +---------------------------------- The zsh/zutil module's zparseopts builtin learnt an -F option to abort parsing when an unrecognised option-like parameter is encountered. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/README new/zsh-5.8/README --- old/zsh-5.7.1-test-3/README 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/README 2020-02-14 23:06:58.000000000 +0100 @@ -5,8 +5,9 @@ Version ------- -This is version 5.8 of the shell. This is a stable release. There are -a few visible improvements since 5.7 as well as many bugfixes. +This is version 5.8 of the shell. This is a security and feature release. +There are a few visible improvements since 5.7, as well as many bugfixes. +All zsh installations are encouraged to upgrade as soon as possible. Note in particular the changes highlighted under "Incompatibilities since 5.7.1" below. See NEWS for more information. @@ -56,6 +57,12 @@ The cd and chdir builtins no longer interpret operands like -1 and +2 as stack entries when POSIX_CD is enabled. +Dropping privileges with `unsetopt privileged` may fail (with an error +message) on some older and uncommon platforms due to library dependency +changes made in the course of fixing CVE-2019-20044. Please report this +to the zsh-workers mailing list if your system is affected. See NEWS for +more. + Incompatibilities between 5.6.2 and 5.7.1 ----------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Src/openssh_bsd_setres_id.c new/zsh-5.8/Src/openssh_bsd_setres_id.c --- old/zsh-5.7.1-test-3/Src/openssh_bsd_setres_id.c 1970-01-01 01:00:00.000000000 +0100 +++ new/zsh-5.8/Src/openssh_bsd_setres_id.c 2020-02-14 23:06:57.000000000 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012 Darren Tucker (dtucker at zip com au). + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * openssh_bsd_setres_id.c - setresuid() and setresgid() wrappers + * + * This file is part of zsh, the Z shell. + * + * It is based on the file openbsd-compat/bsd-setres_id.c in OpenSSH 7.9p1, + * which is subject to the copyright notice above. The zsh modifications are + * licensed as follows: + * + * Copyright (c) 2019 Daniel Shahaf + * All rights reserved. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and to distribute modified versions of this software for any + * purpose, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * In no event shall Daniel Shahaf or the Zsh Development Group be liable + * to any party for direct, indirect, special, incidental, or consequential + * damages arising out of the use of this software and its documentation, + * even if Daniel Shahaf and the Zsh Development Group have been advised of + * the possibility of such damage. + * + * Daniel Shahaf and the Zsh Development Group specifically disclaim any + * warranties, including, but not limited to, the implied warranties of + * merchantability and fitness for a particular purpose. The software + * provided hereunder is on an "as is" basis, and Daniel Shahaf and the + * Zsh Development Group have no obligation to provide maintenance, + * support, updates, enhancements, or modifications. + * + */ + + +#include <sys/types.h> + +#include <stdarg.h> +#include <unistd.h> +#include <string.h> + +#include "zsh.mdh" + +#if defined(ZSH_IMPLEMENT_SETRESGID) || defined(BROKEN_SETRESGID) +int +setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + int ret = 0, saved_errno; + + if (rgid != sgid) { + errno = ENOSYS; + return -1; + } +#if defined(ZSH_HAVE_NATIVE_SETREGID) && !defined(BROKEN_SETREGID) + if (setregid(rgid, egid) < 0) { + saved_errno = errno; + zwarnnam("setregid", "to gid %L: %e", (long)rgid, errno); + errno = saved_errno; + ret = -1; + } +#else + if (setegid(egid) < 0) { + saved_errno = errno; + zwarnnam("setegid", "to gid %L: %e", (long)(unsigned int)egid, errno); + errno = saved_errno; + ret = -1; + } + if (setgid(rgid) < 0) { + saved_errno = errno; + zwarnnam("setgid", "to gid %L: %e", (long)rgid, errno); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif + +#if defined(ZSH_IMPLEMENT_SETRESUID) || defined(BROKEN_SETRESUID) +int +setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + int ret = 0, saved_errno; + + if (ruid != suid) { + errno = ENOSYS; + return -1; + } +#if defined(ZSH_HAVE_NATIVE_SETREUID) && !defined(BROKEN_SETREUID) + if (setreuid(ruid, euid) < 0) { + saved_errno = errno; + zwarnnam("setreuid", "to uid %L: %e", (long)ruid, errno); + errno = saved_errno; + ret = -1; + } +#else + +# ifndef SETEUID_BREAKS_SETUID + if (seteuid(euid) < 0) { + saved_errno = errno; + zwarnnam("seteuid", "to uid %L: %e", (long)euid, errno); + errno = saved_errno; + ret = -1; + } +# endif + if (setuid(ruid) < 0) { + saved_errno = errno; + zwarnnam("setuid", "to uid %L: %e", (long)ruid, errno); + errno = saved_errno; + ret = -1; + } +#endif + return ret; +} +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Src/options.c new/zsh-5.8/Src/options.c --- old/zsh-5.7.1-test-3/Src/options.c 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/Src/options.c 2020-02-14 23:06:57.000000000 +0100 @@ -577,6 +577,7 @@ bin_setopt(char *nam, char **args, UNUSED(Options ops), int isun) { int action, optno, match = 0; + int retval = 0; /* With no arguments or options, display options. */ if (!*args) { @@ -604,18 +605,24 @@ inittyptab(); return 1; } - if(!(optno = optlookup(*args))) + if(!(optno = optlookup(*args))) { zwarnnam(nam, "no such option: %s", *args); - else if(dosetopt(optno, action, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { zwarnnam(nam, "can't change option: %s", *args); + retval |= 1; + } break; } else if(**args == 'm') { match = 1; } else { - if (!(optno = optlookupc(**args))) + if (!(optno = optlookupc(**args))) { zwarnnam(nam, "bad option: -%c", **args); - else if(dosetopt(optno, action, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, action, 0, opts)) { zwarnnam(nam, "can't change option: -%c", **args); + retval |= 1; + } } } args++; @@ -625,10 +632,13 @@ if (!match) { /* Not globbing the arguments -- arguments are simply option names. */ while (*args) { - if(!(optno = optlookup(*args++))) + if(!(optno = optlookup(*args++))) { zwarnnam(nam, "no such option: %s", args[-1]); - else if(dosetopt(optno, !isun, 0, opts)) + retval |= 1; + } else if (dosetopt(optno, !isun, 0, opts)) { zwarnnam(nam, "can't change option: %s", args[-1]); + retval |= 1; + } } } else { /* Globbing option (-m) set. */ @@ -651,7 +661,8 @@ tokenize(s); if (!(pprog = patcompile(s, PAT_HEAPDUP, NULL))) { zwarnnam(nam, "bad pattern: %s", *args); - continue; + retval |= 1; + break; } /* Loop over expansions. */ scanmatchtable(optiontab, pprog, 0, 0, OPT_ALIAS, @@ -660,7 +671,7 @@ } } inittyptab(); - return 0; + return retval; } /* Identify an option name */ @@ -769,37 +780,99 @@ return -1; } else if(optno == PRIVILEGED && !value) { /* unsetting PRIVILEGED causes the shell to make itself unprivileged */ -#ifdef HAVE_SETUID - int ignore_err; - errno = 0; + +/* For simplicity's sake, require both setresgid() and setresuid() up-front. */ +#if !defined(HAVE_SETRESGID) + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; setresgid() and friends not available"); + return -1; +#elif !defined(HAVE_SETRESUID) + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; setresuid() and friends not available"); + return -1; +#else + /* If set, return -1 so lastval will be non-zero. */ + int failed = 0; + const int orig_euid = geteuid(); + const int orig_egid = getegid(); + /* * Set the GID first as if we set the UID to non-privileged it * might be impossible to restore the GID. - * - * Some OSes (possibly no longer around) have been known to - * fail silently the first time, so we attempt the change twice. - * If it fails we are guaranteed to pick this up the second - * time, so ignore the first time. - * - * Some versions of gcc make it hard to ignore the results the - * first time, hence the following. (These are probably not - * systems that require the doubled calls.) */ - ignore_err = setgid(getgid()); - (void)ignore_err; - ignore_err = setuid(getuid()); - (void)ignore_err; - if (setgid(getgid())) { - zwarn("failed to change group ID: %e", errno); - return -1; - } else if (setuid(getuid())) { - zwarn("failed to change user ID: %e", errno); - return -1; + if (setresgid(getgid(), getgid(), getgid())) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; failed to change group ID: %e", + errno); + return -1; } -#else - zwarn("setuid not available"); - return -1; -#endif /* not HAVE_SETUID */ + +# ifdef HAVE_INITGROUPS + /* Set the supplementary groups list. + * + * Note that on macOS, FreeBSD, and possibly some other platforms, + * initgroups() resets the EGID to its second argument (see setgroups(2) for + * details). This has the potential to leave the EGID in an unexpected + * state. However, it seems common in other projects that do this dance to + * simply re-use the same GID that's going to become the EGID anyway, in + * which case it doesn't matter. That's what we do here. It's therefore + * possible, in some probably uncommon cases, that the shell ends up not + * having the privileges of the RUID user's primary/passwd group. */ + if (geteuid() == 0) { + struct passwd *pw = getpwuid(getuid()); + if (pw == NULL) { + zwarnnam("unsetopt", + "can't drop privileges; failed to get user information for uid %L: %e", + (long)getuid(), errno); + failed = 1; + /* This may behave strangely in the unlikely event that the same user + * name appears with multiple UIDs in the passwd database */ + } else if (initgroups(pw->pw_name, getgid())) { + zwarnnam("unsetopt", + "can't drop privileges; failed to set supplementary group list: %e", + errno); + return -1; + } + } else if (getuid() != 0 && + (geteuid() != getuid() || orig_egid != getegid())) { + zwarnnam("unsetopt", + "PRIVILEGED: supplementary group list not changed due to lack of permissions: EUID=%L", + (long)geteuid()); + failed = 1; + } +# else + /* initgroups() isn't in POSIX. If it's not available on the system, + * we silently skip it. */ +# endif + + /* Set the UID second. */ + if (setresuid(getuid(), getuid(), getuid())) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; failed to change user ID: %e", + errno); + return -1; + } + + if (getuid() != 0 && orig_egid != getegid() && + (setgid(orig_egid) != -1 || setegid(orig_egid) != -1)) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; was able to restore the egid"); + return -1; + } + + if (getuid() != 0 && orig_euid != geteuid() && + (setuid(orig_euid) != -1 || seteuid(orig_euid) != -1)) { + zwarnnam("unsetopt", + "PRIVILEGED: can't drop privileges; was able to restore the euid"); + return -1; + } + + if (failed) { + /* A warning message has been printed. */ + return -1; + } +#endif /* HAVE_SETRESGID && HAVE_SETRESUID */ + #ifdef JOB_CONTROL } else if (!force && optno == MONITOR && value) { if (new_opts[optno] == value) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Src/patchlevel.h.release new/zsh-5.8/Src/patchlevel.h.release --- old/zsh-5.7.1-test-3/Src/patchlevel.h.release 2020-02-06 21:07:33.000000000 +0100 +++ new/zsh-5.8/Src/patchlevel.h.release 2020-02-14 23:16:14.000000000 +0100 @@ -1 +1 @@ -#define ZSH_PATCHLEVEL "zsh-5.7.1-test-3-0-g643de93" +#define ZSH_PATCHLEVEL "zsh-5.8-0-g77d203f" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Src/zsh.mdd new/zsh-5.8/Src/zsh.mdd --- old/zsh-5.7.1-test-3/Src/zsh.mdd 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/Src/zsh.mdd 2020-02-14 23:06:57.000000000 +0100 @@ -13,7 +13,8 @@ exec.o glob.o hashtable.o hashnameddir.o \ hist.o init.o input.o jobs.o lex.o linklist.o loop.o math.o \ mem.o module.o options.o params.o parse.o pattern.o prompt.o signals.o \ -signames.o sort.o string.o subst.o text.o utils.o watch.o" +signames.o sort.o string.o subst.o text.o utils.o watch.o \ +openssh_bsd_setres_id.o" headers="../config.h zsh_system.h zsh.h sigcount.h signals.h \ prototypes.h hashtable.h ztype.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Src/zsh_system.h new/zsh-5.8/Src/zsh_system.h --- old/zsh-5.7.1-test-3/Src/zsh_system.h 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/Src/zsh_system.h 2020-02-14 23:06:57.000000000 +0100 @@ -468,30 +468,90 @@ # define setpgrp setpgid #endif -/* can we set the user/group id of a process */ +/* compatibility wrappers */ -#ifndef HAVE_SETUID +/* Our strategy is as follows: + * + * - Ensure that either setre[ug]id() or set{e,}[ug]id() is available. + * - If setres[ug]id() are missing, provide them in terms of either + * setre[ug]id() or set{e,}[ug]id(), whichever is available. + * - Provide replacement setre[ug]id() or set{e,}[ug]id() if they are not + * available natively. + * + * There isn't a circular dependency because, right off the bat, we check that + * there's an end condition, and #error out otherwise. + */ +#if !defined(HAVE_SETREUID) && !(defined(HAVE_SETEUID) && defined(HAVE_SETUID)) + /* + * If you run into this error, you have two options: + * - Teach zsh how to do the equivalent of setreuid() on your system + * - Remove support for PRIVILEGED option, and then remove the #error. + */ +# error "Don't know how to change UID" +#endif +#if !defined(HAVE_SETREGID) && !(defined(HAVE_SETEGID) && defined(HAVE_SETGID)) + /* See above comment. */ +# error "Don't know how to change GID" +#endif + +/* Provide setresuid(). */ +#ifndef HAVE_SETRESUID +int setresuid(uid_t, uid_t, uid_t); +# define HAVE_SETRESUID +# define ZSH_IMPLEMENT_SETRESUID # ifdef HAVE_SETREUID -# define setuid(X) setreuid(X,X) -# define setgid(X) setregid(X,X) -# define HAVE_SETUID +# define ZSH_HAVE_NATIVE_SETREUID +# endif +#endif + +/* Provide setresgid(). */ +#ifndef HAVE_SETRESGID +int setresgid(gid_t, gid_t, gid_t); +# define HAVE_SETRESGID +# define ZSH_IMPLEMENT_SETRESGID +# ifdef HAVE_SETREGID +# define ZSH_HAVE_NATIVE_SETREGID # endif #endif -/* can we set the effective user/group id of a process */ +/* Provide setreuid(). */ +#ifndef HAVE_SETREUID +# define setreuid(X, Y) setresuid((X), (Y), -1) +# define HAVE_SETREUID +#endif + +/* Provide setregid(). */ +#ifndef HAVE_SETREGID +# define setregid(X, Y) setresgid((X), (Y), -1) +# define HAVE_SETREGID +#endif +/* Provide setuid(). */ +/* ### TODO: Either remove this (this function has been standard since 1985), + * ### or rewrite this without multiply-evaluating the argument */ +#ifndef HAVE_SETUID +# define setuid(X) setreuid((X), (X)) +# define HAVE_SETUID +#endif + +/* Provide setgid(). */ +#ifndef HAVE_SETGID +/* ### TODO: Either remove this (this function has been standard since 1985), + * ### or rewrite this without multiply-evaluating the argument */ +# define setgid(X) setregid((X), (X)) +# define HAVE_SETGID +#endif + +/* Provide seteuid(). */ #ifndef HAVE_SETEUID -# ifdef HAVE_SETREUID -# define seteuid(X) setreuid(-1,X) -# define setegid(X) setregid(-1,X) -# define HAVE_SETEUID -# else -# ifdef HAVE_SETRESUID -# define seteuid(X) setresuid(-1,X,-1) -# define setegid(X) setresgid(-1,X,-1) -# define HAVE_SETEUID -# endif -# endif +# define seteuid(X) setreuid(-1, (X)) +# define HAVE_SETEUID +#endif + +/* Provide setegid(). */ +#ifndef HAVE_SETEGID +# define setegid(X) setregid(-1, (X)) +# define HAVE_SETEGID #endif #ifdef HAVE_SYS_RESOURCE_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Test/E01options.ztst new/zsh-5.8/Test/E01options.ztst --- old/zsh-5.7.1-test-3/Test/E01options.ztst 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/Test/E01options.ztst 2020-02-14 23:06:58.000000000 +0100 @@ -74,7 +74,6 @@ # HASH_LIST_ALL ) # PRINT_EXIT_STATUS haven't worked out what this does yet, although # Bart suggested a fix. -# PRIVILEGED (similar to GLOBAL_RCS) # RCS ( " " " " ) # SH_OPTION_LETTERS even I found this too dull to set up a test for # SINGLE_COMMAND kills shell @@ -95,6 +94,15 @@ %test + # setopt should move on to the next operation in the face of an error, but + # preserve the >0 return code + unsetopt aliases + setopt not_a_real_option aliases && return 2 + print -r - $options[aliases] +0:setopt error handling +?(eval):setopt:4: no such option: not_a_real_option +>on + alias echo='print foo' unsetopt aliases # use eval else aliases are all parsed at start @@ -1391,3 +1399,18 @@ ?(anon):4: `break' active at end of function scope ?(anon):4: `break' active at end of function scope ?(anon):4: `break' active at end of function scope + +# There are further tests for PRIVILEGED in P01privileged.ztst. + if [[ -o privileged ]]; then + unsetopt privileged + fi + unsetopt privileged +0:PRIVILEGED sanity check: unsetting is idempotent +F:If this test fails at the first unsetopt, refer to P01privileged.ztst. + + if [[ -o privileged ]]; then + (( UID != EUID )) + else + (( UID == EUID )) + fi +0:PRIVILEGED sanity check: default value is correct diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Test/P01privileged.ztst new/zsh-5.8/Test/P01privileged.ztst --- old/zsh-5.7.1-test-3/Test/P01privileged.ztst 1970-01-01 01:00:00.000000000 +0100 +++ new/zsh-5.8/Test/P01privileged.ztst 2020-02-14 23:06:58.000000000 +0100 @@ -0,0 +1,197 @@ +# This file contains tests related to the PRIVILEGED option. In order to run, +# it requires that the test process itself have super-user privileges (or that +# one of the environment variables described below be set). This can be achieved +# via, e.g., `sudo make check TESTNUM=P`. +# +# Optionally, the environment variables ZSH_TEST_UNPRIVILEGED_UID and/or +# ZSH_TEST_UNPRIVILEGED_GID may be set to UID:EUID or GID:EGID pairs, where the +# two IDs in each pair are different, non-0 IDs valid on the system being used +# to run the tests. (The UIDs must both be non-0 to effectively test downgrading +# of privileges, and they must be non-matching to test auto-enabling of +# PRIVILEGED and to ensure that disabling PRIVILEGED correctly resets the saved +# UID. Technically GID 0 is not special, but for simplicity's sake we apply the +# same requirements here.) +# +# If either of the aforementioned environment variables is not set, the test +# script will try to pick the first two >0 IDs from the passwd/group databases +# on the current system. +# +# If either variable is set, the tests will run, but they will likely fail +# without super-user privileges. + +%prep + + # Mind your empty lines here. The logic in this %prep section is somewhat + # complex compared to most others; to avoid lots of nested/duplicated + # conditions we need to make sure that this all gets executed as a single + # function from which we can return early + [[ $EUID == 0 || -n $ZSH_TEST_UNPRIVILEGED_UID$ZSH_TEST_UNPRIVILEGED_GID ]] || { + ZTST_unimplemented='PRIVILEGED tests require super-user privileges (or env var)' + return 1 + } + (( $+commands[perl] )) || { # @todo Eliminate this dependency with a C wrapper? + ZTST_unimplemented='PRIVILEGED tests require Perl' + return 1 + } + grep -qE '#define HAVE_SETRES?UID' $ZTST_testdir/../config.h || { + ZTST_unimplemented='PRIVILEGED tests require setreuid()/setresuid()' + return 1 + } + # + ruid= euid= rgid= egid= + # + if [[ -n $ZSH_TEST_UNPRIVILEGED_UID ]]; then + ruid=${ZSH_TEST_UNPRIVILEGED_UID%%:*} + euid=${ZSH_TEST_UNPRIVILEGED_UID##*:} + else + print -ru$ZTST_fd 'Selecting unprivileged UID:EUID pair automatically' + local tmp=$( getent passwd 2> /dev/null || < /etc/passwd ) + # Note: Some awks require -v and its argument to be separate + ruid=$( awk -F: '$3 > 0 { print $3; exit; }' <<< $tmp ) + euid=$( awk -F: -v u=$ruid '$3 > u { print $3; exit; }' <<< $tmp ) + fi + # + if [[ -n $ZSH_TEST_UNPRIVILEGED_GID ]]; then + rgid=${ZSH_TEST_UNPRIVILEGED_GID%%:*} + egid=${ZSH_TEST_UNPRIVILEGED_GID##*:} + else + print -ru$ZTST_fd 'Selecting unprivileged GID:EGID pair automatically' + local tmp=$( getent group 2> /dev/null || < /etc/group ) + # Note: Some awks require -v and its argument to be separate + rgid=$( awk -F: '$3 > 0 { print $3; exit; }' <<< $tmp ) + egid=$( awk -F: -v g=$rgid '$3 > g { print $3; exit; }' <<< $tmp ) + fi + # + [[ $ruid/$euid == <1->/<1-> && $ruid != $euid ]] || ruid= euid= + [[ $rgid/$egid == <1->/<1-> && $rgid != $egid ]] || rgid= egid= + # + [[ -n $ruid && -n $euid ]] || { + ZTST_unimplemented='PRIVILEGED tests require unprivileged UID:EUID' + return 1 + } + [[ -n $rgid || -n $egid ]] || { + ZTST_unimplemented='PRIVILEGED tests require unprivileged GID:EGID' + return 1 + } + # + print -ru$ZTST_fd \ + "Using unprivileged UID $ruid, EUID $euid, GID $rgid, EGID $egid" + # + # Execute process with specified UID and EUID + # $1 => Real UID + # $2 => Effective UID + # $3 => Real GID + # $4 => Effective GID + # $5 ... => Command + args to execute (must NOT be a shell command string) + re_exec() { + perl -e ' + die("re_exec: not enough arguments") unless (@ARGV >= 5); + my ($ruid, $euid, $rgid, $egid, @cmd) = @ARGV; + foreach my $id ($ruid, $euid, $rgid, $egid) { + die("re_exec: invalid ID: $id") unless ($id =~ /^(-1|\d+)$/a); + } + $< = 0 + $ruid if ($ruid >= 0); + $> = 0 + $euid if ($euid >= 0); + $( = 0 + $rgid if ($rgid >= 0); + $) = 0 + $egid if ($egid >= 0); + exec(@cmd); + die("re_exec: exec failed: $!"); + ' -- "$@" + } + # + # Convenience wrapper for re_exec to call `zsh -c` + # -* ... => (optional) Command-line options to zsh + # $1 => Real UID + # $2 => Effective UID + # $3 => Real GID + # $4 => Effective GID + # $5 ... => zsh command string; multiple strings are joined by \n + re_zsh() { + local -a opts + while [[ $1 == -[A-Za-z-]* ]]; do + opts+=( $1 ) + shift + done + re_exec "$1" "$2" "$3" "$4" $ZTST_exe $opts -fc \ + "MODULE_PATH=${(q)MODULE_PATH}; ${(F)@[5,-1]}" + } + # + # Return one or more random unused UIDs + # $1 ... => Names of parameters to store UIDs in + get_unused_uid() { + while (( $# )); do + local i_=0 uid_= + until [[ -n $uid_ ]]; do + (( ++i_ > 99 )) && return 1 + uid_=$RANDOM + id $uid_ &> /dev/null || break + uid_= + done + : ${(P)1::=$uid_} + shift + done + } + +%test + + re_zsh $ruid $ruid -1 -1 'echo $UID/$EUID $options[privileged]' + re_zsh $euid $euid -1 -1 'echo $UID/$EUID $options[privileged]' + re_zsh $ruid $euid -1 -1 'echo $UID/$EUID $options[privileged]' +0q:PRIVILEGED automatically enabled when RUID != EUID +>$ruid/$ruid off +>$euid/$euid off +>$ruid/$euid on + + re_zsh -1 -1 $rgid $rgid 'echo $GID/$EGID $options[privileged]' + re_zsh -1 -1 $egid $egid 'echo $GID/$EGID $options[privileged]' + re_zsh -1 -1 $rgid $egid 'echo $GID/$EGID $options[privileged]' +0q:PRIVILEGED automatically enabled when RGID != EGID +>$rgid/$rgid off +>$egid/$egid off +>$rgid/$egid on + + re_zsh $ruid $euid -1 -1 'unsetopt privileged; echo $UID/$EUID' +0q:EUID set to RUID after disabling PRIVILEGED +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +>$ruid/$ruid + + re_zsh 0 $euid -1 -1 'unsetopt privileged && echo $UID/$EUID' +0:RUID/EUID set to 0/0 when privileged after disabling PRIVILEGED +>0/0 + + re_zsh $ruid $euid -1 -1 "unsetopt privileged; UID=$euid" || + re_zsh $ruid $euid -1 -1 "unsetopt privileged; EUID=$euid" +1:not possible to regain EUID when unprivileged after disabling PRIVILEGED +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +*?zsh:1: failed to change user ID: * +*?zsh:unsetopt:1: PRIVILEGED: supplementary group list not changed * +*?zsh:unsetopt:1: can't change option: privileged +*?zsh:1: failed to change effective user ID: * + + re_zsh -1 -1 $rgid $egid 'unsetopt privileged && echo $GID/$EGID' +0q:EGID set to RGID after disabling PRIVILEGED +>$rgid/$rgid + +# This test also confirms that we can't revert to the original EUID's primary +# GID, which initgroups() may reset the EGID to on some systems + re_zsh $ruid 0 $rgid 0 'unsetopt privileged; GID=0' || + re_zsh $ruid 0 $rgid 0 'unsetopt privileged; EGID=0' +1:not possible to regain EGID when unprivileged after disabling PRIVILEGED +*?zsh:1: failed to change group ID: * +*?zsh:1: failed to change effective group ID: * + + local rruid + grep -qF '#define HAVE_INITGROUPS' $ZTST_testdir/../config.h || { + ZTST_skip='initgroups() not available' + return 1 + } + get_unused_uid rruid || { + ZTST_skip="Can't get unused UID" + return 1 + } + re_zsh $rruid 0 -1 -1 'unsetopt privileged' +1:getpwuid() fails with non-existent RUID and 0 EUID +*?zsh:unsetopt:1: can't drop privileges; failed to get user information * +*?zsh:unsetopt:1: can't change option: privileged diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Test/README new/zsh-5.8/Test/README --- old/zsh-5.7.1-test-3/Test/README 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/Test/README 2020-02-14 23:06:58.000000000 +0100 @@ -6,6 +6,7 @@ C: shell commands with special syntax D: substititution E: options + P: privileged (needs super-user privileges) V: modules W: builtin interactive commands and constructs X: line editing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/Test/V01zmodload.ztst new/zsh-5.8/Test/V01zmodload.ztst --- old/zsh-5.7.1-test-3/Test/V01zmodload.ztst 2018-11-13 09:04:43.000000000 +0100 +++ new/zsh-5.8/Test/V01zmodload.ztst 2020-02-14 23:07:11.000000000 +0100 @@ -348,6 +348,22 @@ ?(eval):6: unknown function: systell ?(eval):9: file descriptor out of range + $ZTST_testdir/../Src/zsh -fc " + MODULE_PATH=${(q)MODULE_PATH} + # + zmodload zsh/zutil + zmodload -Fal zsh/zutil | grep parse + zmodload -u zsh/zutil + # + zmodload -Fa zsh/zutil -b:zregexparse + zmodload zsh/zutil + zmodload -Fal zsh/zutil | grep parse >&2 + " +0:zmodload -Fa can disable features from being loaded +>b:zparseopts +>b:zregexparse +?b:zparseopts + %clean eval "$deps" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/config.h.in new/zsh-5.8/config.h.in --- old/zsh-5.7.1-test-3/config.h.in 2020-01-12 04:43:21.000000000 +0100 +++ new/zsh-5.8/config.h.in 2020-02-14 18:38:46.000000000 +0100 @@ -613,12 +613,18 @@ /* Define to 1 if you have the `setcchar' function. */ #undef HAVE_SETCCHAR +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID +/* Define to 1 if you have the `setgid' function. */ +#undef HAVE_SETGID + /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE @@ -631,6 +637,12 @@ /* Define to 1 if the system supports `setproctitle' to change process name */ #undef HAVE_SETPROCTITLE +/* Define to 1 if you have the `setregid' function. */ +#undef HAVE_SETREGID + +/* Define to 1 if you have the `setresgid' function. */ +#undef HAVE_SETRESGID + /* Define to 1 if you have the `setresuid' function. */ #undef HAVE_SETRESUID diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/configure new/zsh-5.8/configure --- old/zsh-5.7.1-test-3/configure 2020-02-06 20:53:57.000000000 +0100 +++ new/zsh-5.8/configure 2020-02-14 23:11:48.000000000 +0100 @@ -8661,6 +8661,7 @@ getlogin getpwent getpwnam getpwuid getgrgid getgrnam \ initgroups nis_list \ setuid seteuid setreuid setresuid setsid \ + setgid setegid setregid setresgid \ memcpy memmove strstr strerror strtoul \ getrlimit getrusage \ setlocale \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zsh-5.7.1-test-3/configure.ac new/zsh-5.8/configure.ac --- old/zsh-5.7.1-test-3/configure.ac 2020-02-03 06:52:13.000000000 +0100 +++ new/zsh-5.8/configure.ac 2020-02-14 23:06:57.000000000 +0100 @@ -1311,6 +1311,7 @@ getlogin getpwent getpwnam getpwuid getgrgid getgrnam \ initgroups nis_list \ setuid seteuid setreuid setresuid setsid \ + setgid setegid setregid setresgid \ memcpy memmove strstr strerror strtoul \ getrlimit getrusage \ setlocale \
