Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.91k stars 542 forks source link

Under dash, Perl provides different results for $? #19020

Open xsawyerx opened 3 years ago

xsawyerx commented 3 years ago

Description

Under dash, (certain?) signals in calls to targetsh produce different values for $?.

Steps to Reproduce

# /bin/sh -> dash
$ perl -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Killed
Raw: 35072, Exit: 137, signal: 0

# /bin/sh -> bash
$ perl -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9

Long-form

Perl's backticks and system() call out to shell (specifically to targetsh[1]) when they receive an argument with an escaped variable ("\$"). (With system(), this only happens when there's only one argument.)

# Notice PID 24167
$ strace -f perl -e'system("ls \$foo");' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-esystem(\"ls \\$foo\");"], 0x7ffe89dee6c0 /* 33 vars */) = 0
[pid 24167] execve("/bin/sh", ["sh", "-c", "ls $foo"], 0x559db1baae80 /* 33 vars */) = 0
[pid 24168] execve("/bin/ls", ["ls"], 0x558771ffeb78 /* 33 vars */) = 0

# Notice PID 24376
$ strace -f perl -e'`ls\$foo`' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-e`ls\\$foo`"], 0x7ffcf69a68d0 /* 33 vars */) = 0
[pid 24376] execve("/bin/sh", ["sh", "-c", "ls$foo"], 0x55dcf524ce80 /* 33 vars */ <unfinished ...>
[pid 24376] <... execve resumed> )      = 0
[pid 24377] execve("/bin/ls", ["ls"], 0x55edd5930b50 /* 33 vars */) = 0

On Debian, dash is the default non-interactive shell[2] and on Ubuntu as well[3] and that's what /bin/sh (the targetsh) will point to.

Perl's $? variable is described as the status returned "by [...] backtick command, [...], or from the system() operator."[4] - There's an exec, a wait(), and then $? reflects that result.

It seems like the behavior of signal catching is not consistent between shells[5] causing this lack of consistency when:

  1. Perl's targetsh is set to /bin/sh (the default).
  2. We call backticks or a one-arg system().
  3. It has an escaped variable.
  4. Our /bin/sh is pointing to dash.
  5. The wait on that sh -c call that Perl makes is cut off by a signal.
  6. That signal is captured or not by the shell. (Not entirely sure about this.)
# /bin/sh -> dash
$ perl -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Killed
Raw: 35072, Exit: 137, signal: 0

# /bin/sh -> bash
$ perl -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9

In the same paragraph I quote above on $?, it also states that $? is a 16-bit word: "This is just the 16-bit status word returned by the traditional Unix wait() system call (or else is made up to look like it)."[4]

Notably, when Perl does not receive a 16-bit word, it is "made up to look like it." I'm not sure if this means Perl did not convert whatever dash returned (so it could be shifted) or not, but I thought it might be relevant that Perl provides a certain expectation, but the results are different between shells.

Suggestions to fix

  1. Possibly change how Perl handles the response from dash.
  2. Document this in perlport.
  3. Document this in perlvar under $?.
  4. Document this in perlipc.

I don't know if suggestion 1 is correct or not (I'll leave that to the experts) but I think at least suggestions 2 to 4 should be done. I'm happy to provide the patches, if that's desired.

[1] targetsh can be configured using -Dtargetsh=.... It is /bin/sh by default. [2] https://wiki.debian.org/Shell [3] "In Ubuntu 6.10, the default system shell, /bin/sh, was changed to dash" -- https://wiki.ubuntu.com/DashAsBinSh [4] https://perldoc.perl.org/perlvar#Error-Variables [5] https://unix.stackexchange.com/questions/240723/exit-trap-in-dash-vs-ksh-and-bash

Leont commented 3 years ago

I can't reproduce this, I get the same (and correct) Raw: 9, Exit: 0, signal: 9 result for both shells (on Arch Linux; dash 0.5.11, bash 5.1.8)

atoomic commented 3 years ago

To reproduce you probably want to be sure Perl was compiled with dash as the default shell?

jkeenan commented 3 years ago

@xsawyerx , can you post enough of ./perl -Ilib -V so that we can get an idea of the platform and the config_args?

Thank you very much. Jim Keenan

tonycoz commented 3 years ago

bash appears to exec the command if it's the final command:

tony@venus:.../git/perl4$ perl ../19020.pl 
lrwxrwxrwx 1 root root 4 Aug  4 15:43 /bin/sh -> bash
systemd---sshd---sshd---sshd---bash---xterm---bash---perl---pstree
tony@venus:.../git/perl4$ perl ../19020.pl 
lrwxrwxrwx 1 root root 4 Aug  4 15:46 /bin/sh -> dash
systemd---sshd---sshd---sshd---bash---xterm---bash---perl---sh---pstree
tony@venus:.../git/perl4$ cat ../19020.pl
my $x = 'pstree -s $$';
system 'ls -l /bin/sh';
print `$x`;

which leads to the behaviour you're seeing. If you add another command after the pstree above (like an echo) the trees match.

Possibly from this in execute_cmd.c:

  /* If this is a simple command, tell execute_disk_command that it
     might be able to get away without forking and simply exec.
     This means things like ( sleep 10 ) will only cause one fork.
     If we're timing the command or inverting its return value, however,
     we cannot do this optimization. */
  if ((user_subshell || user_coproc) && (tcom->type == cm_simple || tcom->type == cm_subshell) &&
      ((tcom->flags & CMD_TIME_PIPELINE) == 0) &&
      ((tcom->flags & CMD_INVERT_RETURN) == 0))
    {
      tcom->flags |= CMD_NO_FORK;
      if (tcom->type == cm_simple)
        tcom->value.Simple->flags |= CMD_NO_FORK;
    }
xsawyerx commented 3 years ago

I can't reproduce this, I get the same (and correct) Raw: 9, Exit: 0, signal: 9 result for both shells (on Arch Linux; dash 0.5.11, bash 5.1.8)

I'm running Dash Version: 0.5.11+git20200708+dd9ef66+really0.5.11+git20200708+dd9ef66-5ubuntu1 (Ubuntu) and 0.5.10.2-5 (Debian) where the issue exists.

The Dash manual (even on the 0.5.11 mentioned above) includes:

The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell.

I'm not sure if it's part of that or not. The changelog seems to include notes on wait() and signal catching but I haven't investigated which are relevant. It's possible it's fixed in a patch you have, Leon, or that there's a patch that the Ubuntu distro I'm quoting above did not apply.

To reproduce you probably want to be sure Perl was compiled with dash as the default shell?

I'm not sure this is the case.

Perl details on one on one of the Ubuntu systems:

``` Summary of my perl5 (revision 5 version 32 subversion 1) configuration: Platform: osname=linux osvers=4.19.0 archname=x86_64-linux-gnu-thread-multi uname='linux localhost 4.19.0 #1 smp debian 4.19.0 x86_64 gnulinux ' config_args='-Dmksymlinks -Dusethreads -Duselargefiles -Dcc=x86_64-linux-gnu-gcc -Dcpp=x86_64-linux-gnu-cpp -Dld=x86_64-linux-gnu-gcc -Dccflags=-DDEBIAN -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -ffile-prefix-map=/dummy/build/dir=. -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Dldflags= -Wl,-Bsymbolic-functions -flto=auto -Wl,-z,relro -Dlddlflags=-shared -Wl,-Bsymbolic-functions -flto=auto -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.32 -Darchlib=/usr/lib/x86_64-linux-gnu/perl/5.32 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/x86_64-linux-gnu/perl5/5.32 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.32.1 -Dsitearch=/usr/local/lib/x86_64-linux-gnu/perl/5.32.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Ui_xlocale -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -dEs -Duseshrplib -Dlibperl=libperl.so.5.32.1' hint=recommended useposix=true d_sigaction=define useithreads=define usemultiplicity=define use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n default_inc_excludes_dot=define bincompat5005=undef Compiler: cc='x86_64-linux-gnu-gcc' ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' optimize='-O2 -g' cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='' gccversion='10.2.1 20210320' gccosandvers='' intsize=4 longsize=8 ptrsize=8 doublesize=8 byteorder=12345678 doublekind=3 d_longlong=define longlongsize=8 d_longdbl=define longdblsize=16 longdblkind=3 ivtype='long' ivsize=8 nvtype='double' nvsize=8 Off_t='off_t' lseeksize=8 alignbytes=8 prototype=define Linker and Libraries: ld='x86_64-linux-gnu-gcc' ldflags =' -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=libc-2.33.so so=so useshrplib=true libperl=libperl.so.5.32 gnulibc_version='2.33' Dynamic Linking: dlsrc=dl_dlopen.xs dlext=so d_dlsymun=undef ccdlflags='-Wl,-E' cccdlflags='-fPIC' lddlflags='-shared -L/usr/local/lib -fstack-protector-strong' Characteristics of this binary (from libperl): Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP PERL_OP_PARENT PERL_PRESERVE_IVUV USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API USE_THREAD_SAFE_LOCALE Locally applied patches: DEBPKG:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN. DEBPKG:debian/db_file_ver - https://bugs.debian.org/340047 Remove overly restrictive DB_File version check. DEBPKG:debian/doc_info - Replace generic man(1) instructions with Debian-specific information. DEBPKG:debian/enc2xs_inc - https://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @INC directories. DEBPKG:debian/errno_ver - https://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes. DEBPKG:debian/libperl_embed_doc - https://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking DEBPKG:fixes/respect_umask - Respect umask during installation DEBPKG:debian/writable_site_dirs - Set umask approproately for site install directories DEBPKG:debian/extutils_set_libperl_path - EU:MM: set location of libperl.a under /usr/lib DEBPKG:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor DEBPKG:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets. DEBPKG:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor. DEBPKG:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy. DEBPKG:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable. DEBPKG:debian/perlivp - https://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local DEBPKG:debian/squelch-locale-warnings - https://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts DEBPKG:debian/patchlevel - https://bugs.debian.org/567489 List packaged patches for 5.32.1-3ubuntu2 in patchlevel.h DEBPKG:fixes/document_makemaker_ccflags - https://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags} DEBPKG:debian/find_html2text - https://bugs.debian.org/640479 Configure CPAN::Distribution with correct name of html2text DEBPKG:debian/perl5db-x-terminal-emulator.patch - https://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl DEBPKG:debian/cpan-missing-site-dirs - https://bugs.debian.org/688842 Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable DEBPKG:fixes/memoize_storable_nstore - [rt.cpan.org #77790] https://bugs.debian.org/587650 Memoize::Storable: respect 'nstore' option not respected DEBPKG:debian/makemaker-pasthru - https://bugs.debian.org/758471 Pass LD settings through to subdirectories DEBPKG:debian/makemaker-manext - https://bugs.debian.org/247370 Make EU::MakeMaker honour MANnEXT settings in generated manpage headers DEBPKG:debian/kfreebsd-softupdates - https://bugs.debian.org/796798 Work around Debian Bug#796798 DEBPKG:fixes/memoize-pod - [rt.cpan.org #89441] Fix POD errors in Memoize DEBPKG:debian/hurd-softupdates - https://bugs.debian.org/822735 Fix t/op/stat.t failures on hurd DEBPKG:fixes/math_complex_doc_great_circle - https://bugs.debian.org/697567 [rt.cpan.org #114104] Math::Trig: clarify definition of great_circle_midpoint DEBPKG:fixes/math_complex_doc_see_also - https://bugs.debian.org/697568 [rt.cpan.org #114105] Math::Trig: add missing SEE ALSO DEBPKG:fixes/math_complex_doc_angle_units - https://bugs.debian.org/731505 [rt.cpan.org #114106] Math::Trig: document angle units DEBPKG:fixes/cpan_web_link - https://bugs.debian.org/367291 CPAN: Add link to main CPAN web site DEBPKG:debian/hppa_op_optimize_workaround - https://bugs.debian.org/838613 Temporarily lower the optimization of op.c on hppa due to gcc-6 problems DEBPKG:debian/installman-utf8 - https://bugs.debian.org/840211 Generate man pages with UTF-8 characters DEBPKG:debian/hppa_opmini_optimize_workaround - https://bugs.debian.org/869122 Lower the optimization level of opmini.c on hppa DEBPKG:debian/sh4_op_optimize_workaround - https://bugs.debian.org/869373 Also lower the optimization level of op.c and opmini.c on sh4 DEBPKG:debian/perldoc-pager - https://bugs.debian.org/870340 [rt.cpan.org #120229] Fix perldoc terminal escapes when sensible-pager is less DEBPKG:debian/prune_libs - https://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need. DEBPKG:debian/mod_paths - Tweak @INC ordering for Debian DEBPKG:debian/configure-regen - https://bugs.debian.org/762638 Regenerate Configure et al. after probe unit changes DEBPKG:debian/deprecate-with-apt - https://bugs.debian.org/747628 Point users to Debian packages of deprecated core modules DEBPKG:debian/disable-stack-check - https://bugs.debian.org/902779 [GH #16607] Disable debugperl stack extension checks for binary compatibility with perl DEBPKG:debian/perlbug-editor - https://bugs.debian.org/922609 Use "editor" as the default perlbug editor, as per Debian policy DEBPKG:debian/eu-mm-perl-base - https://bugs.debian.org/962138 Suppress an ExtUtils::MakeMaker warning about our non-default @INC DEBPKG:fixes/hurd-cachepropagate-test-fix - https://bugs.debian.org/963214 GNU/Hurd doesn't support SO_PROTOCOL DEBPKG:fixes/io_socket_ip_ipv6 - Disable getaddrinfo(3) AI_ADDRCONFIG for localhost and IPv4 numeric addresses DEBPKG:disable-libperl-tests - Built under linux Compiled at Mar 23 2021 16:50:32 %ENV: PERL5LIB="/home/sawyer/perl5/lib/perl5:/home/sawyer/perl5/lib/perl5" PERLBREW_HOME="/home/sawyer/.perlbrew" PERLBREW_ROOT="/home/sawyer/perl5/perlbrew" PERLBREW_SHELLRC_VERSION="0.92" PERL_LOCAL_LIB_ROOT="/home/sawyer/perl5:/home/sawyer/perl5" PERL_MB_OPT="--install_base "/home/sawyer/perl5"" PERL_MM_OPT="INSTALL_BASE=/home/sawyer/perl5" @INC: /home/sawyer/perl5/lib/perl5/x86_64-linux-gnu-thread-multi /home/sawyer/perl5/lib/perl5 /home/sawyer/perl5/lib/perl5/x86_64-linux-gnu-thread-multi /home/sawyer/perl5/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.32.1 /usr/local/share/perl/5.32.1 /usr/lib/x86_64-linux-gnu/perl5/5.32 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl-base /usr/lib/x86_64-linux-gnu/perl/5.32 /usr/share/perl/5.32 /usr/local/lib/site_perl ```

Perl details on one of the Debian systems:

``` Summary of my perl5 (revision 5 version 28 subversion 1) configuration: Platform: osname=linux osvers=4.9.0 archname=x86_64-linux-gnu-thread-multi uname='linux localhost 4.9.0 #1 smp debian 4.9.0 x86_64 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dcc=x86_64-linux-gnu-gcc -Dcpp=x86_64-linux-gnu-cpp -Dld=x86_64-linux-gnu-gcc -Dccflags=-DDEBIAN -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/perl-voFw8F/perl-5.28.1=. -fstack-protector-strong -Wformat -Werror=format-security -Dldflags= -Wl,-z,relro -Dlddlflags=-shared -Wl,-z,relro -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.28 -Darchlib=/usr/lib/x86_64-linux-gnu/perl/5.28 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/x86_64-linux-gnu/perl5/5.28 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.28.1 -Dsitearch=/usr/local/lib/x86_64-linux-gnu/perl/5.28.1 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Duse64bitint -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Ui_libutil -Ui_xlocale -Uversiononly -DDEBUGGING=-g -Doptimize=-O2 -dEs -Duseshrplib -Dlibperl=libperl.so.5.28.1' hint=recommended useposix=true d_sigaction=define useithreads=define usemultiplicity=define use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n default_inc_excludes_dot=define bincompat5005=undef Compiler: cc='x86_64-linux-gnu-gcc' ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64' optimize='-O2 -g' cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='' gccversion='8.3.0' gccosandvers='' intsize=4 longsize=8 ptrsize=8 doublesize=8 byteorder=12345678 doublekind=3 d_longlong=define longlongsize=8 d_longdbl=define longdblsize=16 longdblkind=3 ivtype='long' ivsize=8 nvtype='double' nvsize=8 Off_t='off_t' lseeksize=8 alignbytes=8 prototype=define Linker and Libraries: ld='x86_64-linux-gnu-gcc' ldflags =' -fstack-protector-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=libc-2.28.so so=so useshrplib=true libperl=libperl.so.5.28 gnulibc_version='2.28' Dynamic Linking: dlsrc=dl_dlopen.xs dlext=so d_dlsymun=undef ccdlflags='-Wl,-E' cccdlflags='-fPIC' lddlflags='-shared -L/usr/local/lib -fstack-protector-strong' Characteristics of this binary (from libperl): Compile-time options: HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP PERL_OP_PARENT PERL_PRESERVE_IVUV USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API Locally applied patches: DEBPKG:debian/cpan_definstalldirs - Provide a sensible INSTALLDIRS default for modules installed from CPAN. DEBPKG:debian/db_file_ver - https://bugs.debian.org/340047 Remove overly restrictive DB_File version check. DEBPKG:debian/doc_info - Replace generic man(1) instructions with Debian-specific information. DEBPKG:debian/enc2xs_inc - https://bugs.debian.org/290336 Tweak enc2xs to follow symlinks and ignore missing @INC directories. DEBPKG:debian/errno_ver - https://bugs.debian.org/343351 Remove Errno version check due to upgrade problems with long-running processes. DEBPKG:debian/libperl_embed_doc - https://bugs.debian.org/186778 Note that libperl-dev package is required for embedded linking DEBPKG:fixes/respect_umask - Respect umask during installation DEBPKG:debian/writable_site_dirs - Set umask approproately for site install directories DEBPKG:debian/extutils_set_libperl_path - EU:MM: set location of libperl.a under /usr/lib DEBPKG:debian/no_packlist_perllocal - Don't install .packlist or perllocal.pod for perl or vendor DEBPKG:debian/fakeroot - Postpone LD_LIBRARY_PATH evaluation to the binary targets. DEBPKG:debian/instmodsh_doc - Debian policy doesn't install .packlist files for core or vendor. DEBPKG:debian/ld_run_path - Remove standard libs from LD_RUN_PATH as per Debian policy. DEBPKG:debian/libnet_config_path - Set location of libnet.cfg to /etc/perl/Net as /usr may not be writable. DEBPKG:debian/perlivp - https://bugs.debian.org/510895 Make perlivp skip include directories in /usr/local DEBPKG:debian/squelch-locale-warnings - https://bugs.debian.org/508764 Squelch locale warnings in Debian package maintainer scripts DEBPKG:debian/patchlevel - https://bugs.debian.org/567489 List packaged patches for 5.28.1-6+deb10u1 in patchlevel.h DEBPKG:fixes/document_makemaker_ccflags - https://bugs.debian.org/628522 [rt.cpan.org #68613] Document that CCFLAGS should include $Config{ccflags} DEBPKG:debian/find_html2text - https://bugs.debian.org/640479 Configure CPAN::Distribution with correct name of html2text DEBPKG:debian/perl5db-x-terminal-emulator.patch - https://bugs.debian.org/668490 Invoke x-terminal-emulator rather than xterm in perl5db.pl DEBPKG:debian/cpan-missing-site-dirs - https://bugs.debian.org/688842 Fix CPAN::FirstTime defaults with nonexisting site dirs if a parent is writable DEBPKG:fixes/memoize_storable_nstore - [rt.cpan.org #77790] https://bugs.debian.org/587650 Memoize::Storable: respect 'nstore' option not respected DEBPKG:debian/makemaker-pasthru - https://bugs.debian.org/758471 Pass LD settings through to subdirectories DEBPKG:debian/makemaker-manext - https://bugs.debian.org/247370 Make EU::MakeMaker honour MANnEXT settings in generated manpage headers DEBPKG:debian/kfreebsd-softupdates - https://bugs.debian.org/796798 Work around Debian Bug#796798 DEBPKG:fixes/autodie-scope - https://bugs.debian.org/798096 Fix a scoping issue with "no autodie" and the "system" sub DEBPKG:fixes/memoize-pod - [rt.cpan.org #89441] Fix POD errors in Memoize DEBPKG:debian/hurd-softupdates - https://bugs.debian.org/822735 Fix t/op/stat.t failures on hurd DEBPKG:fixes/math_complex_doc_great_circle - https://bugs.debian.org/697567 [rt.cpan.org #114104] Math::Trig: clarify definition of great_circle_midpoint DEBPKG:fixes/math_complex_doc_see_also - https://bugs.debian.org/697568 [rt.cpan.org #114105] Math::Trig: add missing SEE ALSO DEBPKG:fixes/math_complex_doc_angle_units - https://bugs.debian.org/731505 [rt.cpan.org #114106] Math::Trig: document angle units DEBPKG:fixes/cpan_web_link - https://bugs.debian.org/367291 CPAN: Add link to main CPAN web site DEBPKG:debian/hppa_op_optimize_workaround - https://bugs.debian.org/838613 Temporarily lower the optimization of op.c on hppa due to gcc-6 problems DEBPKG:debian/installman-utf8 - https://bugs.debian.org/840211 Generate man pages with UTF-8 characters DEBPKG:fixes/getopt-long-4 - https://bugs.debian.org/864544 [rt.cpan.org #122068] Fix issue #122068. DEBPKG:debian/hppa_opmini_optimize_workaround - https://bugs.debian.org/869122 Lower the optimization level of opmini.c on hppa DEBPKG:debian/sh4_op_optimize_workaround - https://bugs.debian.org/869373 Also lower the optimization level of op.c and opmini.c on sh4 DEBPKG:debian/perldoc-pager - https://bugs.debian.org/870340 [rt.cpan.org #120229] Fix perldoc terminal escapes when sensible-pager is less DEBPKG:debian/prune_libs - https://bugs.debian.org/128355 Prune the list of libraries wanted to what we actually need. DEBPKG:debian/mod_paths - Tweak @INC ordering for Debian DEBPKG:debian/configure-regen - https://bugs.debian.org/762638 Regenerate Configure et al. after probe unit changes DEBPKG:debian/deprecate-with-apt - https://bugs.debian.org/747628 Point users to Debian packages of deprecated core modules DEBPKG:debian/disable-stack-check - https://bugs.debian.org/902779 [perl #133327] Disable debugperl stack extension checks for binary compatibility with perl DEBPKG:debian/gdbm-fatal - [perl #133295] https://bugs.debian.org/904005 Temporarily skip GDBM_File fatal.t for gdbm >= 1.15 compatibility DEBPKG:fixes/storable-recursion - https://bugs.debian.org/912900 [perl #133326] [120060c] (perl #133326) fix and clarify handling of recurs_sv. DEBPKG:fixes/caretx-fallback - https://bugs.debian.org/913347 [perl #133573] [03b94aa] RT#133573: $^X fallback when platform-specific technique fails DEBPKG:fixes/eumm-usrmerge - https://bugs.debian.org/913637 Avoid mangling /bin non-perl shebangs on merged-/usr systems DEBPKG:fixes/errno-include-path - [6c5080f] [perl #133662] https://bugs.debian.org/875921 Make Errno_pm.PL compatible with /usr/include//errno.h DEBPKG:fixes/kfreebsd-renameat - [a3c63a9] https://bugs.debian.org/912521 [perl #133668] Also work around renameat() kernel bug on GNU/kFreeBSD DEBPKG:fixes/time-local-2020 - https://bugs.debian.org/915209 [rt.cpan.org #124787] Fix Time::Local tests DEBPKG:fixes/inplace-editing-bugfix/part1 - https://bugs.debian.org/914651 (perl #133659) move argvout cleanup to a new function DEBPKG:fixes/inplace-editing-bugfix/part2 - https://bugs.debian.org/914651 (perl #133659) tests for global destruction handling of inplace editing DEBPKG:fixes/inplace-editing-bugfix/part3 - https://bugs.debian.org/914651 (perl #133659) make an in-place edit successful if the exit status is zero DEBPKG:fixes/fix-manifest-failures - https://bugs.debian.org/914962 Fix t/porting/manifest.t failures when run in a foreign git checkout DEBPKG:fixes/pipe-open-bugfix/part1 - [perl #133726] https://bugs.debian.org/916313 Always mark pipe in pipe-open as inherit-on-exec DEBPKG:fixes/pipe-open-bugfix/part2 - [perl #133726] https://bugs.debian.org/916313 Always mark pipe in list pipe-open as inherit-on-exec DEBPKG:fixes/storable-probing/prereq1 - [3f4cad1] Storable: fix for strawberry build failures: DEBPKG:fixes/storable-probing/prereq2 - [perl #133411] [edf639f] (perl #133411) don't try to load Storable with -Dusecrosscompile DEBPKG:fixes/storable-probing/disable-probing - https://bugs.debian.org/914133 [perl #133708] [2a0bbd3] (perl #133708) remove build-time probing for stack limits for Storable DEBPKG:debian/perlbug-editor - https://bugs.debian.org/922609 Use "editor" as the default perlbug editor, as per Debian policy DEBPKG:fixes/posix-mbrlen - [25d7b7a] https://bugs.debian.org/924517 [perl #133928] Fix POSIX::mblen mbstate_t initialization on threaded perls with glibc DEBPKG:fixes/CVE-2020-10543 - https://bugs.debian.org/962005 regcomp.c: Prevent integer overflow from nested regex quantifiers. DEBPKG:fixes/CVE-2020-10878 - https://bugs.debian.org/962005 study_chunk: extract rck_elide_nothing DEBPKG:fixes/CVE-2020-12723 - https://bugs.debian.org/962005 study_chunk: avoid mutating regexp program within GOSUB DEBPKG:fixes/io-socket-ip-nov4 - https://bugs.debian.org/962019 Fix test failures in IO::Socket::IP with an IPv6-only host Built under linux Compiled at Jul 21 2020 19:27:00 @INC: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/x86_64-linux-gnu/perl5/5.28 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base ```
jkeenan commented 3 years ago

We should consider the possibility that these results may be Linux-specific. So far I am unable to reproduce the bash/dash difference on FreeBSD-12 (though I concede I have never tried varying targetsh before).

$ uname -mrs
FreeBSD 12.2-STABLE amd64

[perlmonger: jkeenan] $ which sh
/bin/sh
[perlmonger: jkeenan] $ perl -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9

That's with perl-5.32.0 (the "vendor perl"). I get the same result at blead:

[perlmonger: perl] $ gitcurr
blead
[perlmonger: perl] $ git describe
v5.35.2-111-g972308c272
[perlmonger: perl] $ regular_configure
...
[perlmonger: perl] $ grep '^targetsh' config.sh
targetsh='/bin/sh'
[perlmonger: perl] $ make test_prep
...
[perlmonger: perl] $ ./perl -Ilib -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9
[perlmonger: perl] $ git clean -dfx

Targeting bash

[perlmonger: perl] $ $ sh ./Configure -des -Dusedevel -Dtargetsh=/usr/local/bin/bash -Duseithreads -Doptimize="-O2 -pipe -fstack-protector -fno-strict-aliasing"
...
[perlmonger: perl] $ grep '^targetsh' config.sh
targetsh='/usr/local/bin/bash'
[perlmonger: perl] $ make test_prep
...
[perlmonger: perl] $ bash
[jkeenan@perlmonger /usr/home/jkeenan/gitwork/perl]$ ./perl -Ilib -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9
[jkeenan@perlmonger /usr/home/jkeenan/gitwork/perl]$ git clean -dfx; exit

Targeting dash

[perlmonger: perl] $ sh ./Configure -des -Dusedevel -Dtargetsh=/usr/local/bin/dash -Duseithreads -Doptimize="-O2 -pipe -fstack-protector -fno-strict-aliasing"
...
[perlmonger: perl] $ grep '^targetsh' config.sh
targetsh='/usr/local/bin/dash'
[perlmonger: perl] $ make test_prep
...
[perlmonger: perl] $ dash
[perlmonger: \W] $ ./perl -Ilib -e'`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Raw: 9, Exit: 0, signal: 9
[perlmonger: \W] $ git clean -dfx; exit
toddr commented 3 years ago

I think it's safe to blame this as a bug on dash 0.5.10. Version 0.5.11 seems to not have this undesirable behavior. How do we feel about adding a test to codify what we expect the behavior to be for this?

xsawyerx commented 3 years ago

I think it's safe to blame this as a bug on dash 0.5.10. Version 0.5.11 seems to not have this undesirable behavior. How do we feel about adding a test to codify what we expect the behavior to be for this?

One of my cases is version 0.5.11, though. Maybe it's a certain patch?

I think adding a test is a good idea.

toddr commented 2 years ago

The pull request for the test now shows that even the smokers on github are broken. https://github.com/Perl/perl5/pull/19152

CC @tonycoz

wolfsage commented 2 years ago

When we execute a subshell because of metacharacters, and that subshell sticks around, it is what detects that the child perl has died with signal 9, and returns 137 which perl thinks is its exit code and shifts it over 8 to 35072.

This isn't really specific to dash - the difference between dash and bash were pointed out by tonyc above, that is: bash is smart and instead of fork/execing a child process, it just replaces itself with the intended process if it can.

But if it can't, you get the same behaviour:

my $res  = system qq($^X -e'\''kill "KILL", \$\$; sleep 100'\'' && sleep 1);

The && sleep 1 forces bash to stick around, and then you get the same problem.

toddr commented 2 years ago

My concern here is that based on the designated shell perl is compiled on, Perl programs which use system/qx will unexpectedly end up with different values for $?. It seems like this is something we should protect the perl coder from. Perl should provide a reliable behavior for $?.

@wolfsage are you suggesting the test in the pull request is an invalid test?

Leont commented 2 years ago

My concern here is that based on the designated shell perl is compiled on, Perl programs which use system/qx will unexpectedly end up with different values for $?. It seems like this is something we should protect the perl coder from. Perl should provide a reliable behavior for $?.

You can protect yourself from that by using the list form instead of the single-argument form of system. The latter will use the local sh, and we are not responsible for sh's behavior.

wolfsage commented 2 years ago

I think $? can/should be reliable here, and the fact that it did, or did not spawn a subshell, should not change how the return value looks. But I don't know if this is realistic.

Leont commented 2 years ago

But I don't know if this is realistic.

I think it would require writing a shell of our own.

xsawyerx commented 2 years ago

I misunderstood Tony's explanation for it. Thank you for clarifying, @wolfsage. And thanks, @tonycoz, for researching and explaining.

It seems to me that what we're saying is: There's a bug in an older version of a shell that renders $? inaccurate at times.

We can do several things:

  1. We can document this under perlvar in case someone hits it again. (I'm happy to provide the patch.)
  2. Either with or without option 1, we can keep the test so distros know if they have a shell that has this issue. (This then serves as a regression test in case such a bug that affects perl and its users surfaces again.) In this case, we would need to set this as a TODO item for the smokers since they are still affected by this at the moment.
  3. Instead of 1 or 2, we say "it was fixed in a newer version so we consider it a moot point" and close both the ticket and test PR.

I should note that this came up not from fuzzing (which could explain a "non-feasible sequence of characters or action") but from actual code that included something along those lines and flaked out on certain boxes. That is, this actually affected a user.

tonycoz commented 2 years ago

I've done some testing with various versions of dash, and looked into what patches Debian and Ubuntu apply.

The tests:

0.5.11.4:
tony@venus:.../git/perl5$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );' 
Raw: 9, Exit: 0, signal: 9
tony@venus:.../git/perl5$ grep targetsh config.sh
config_args='-des -Dusedevel -Dtargetsh=/home/tony/local/dash-0.5.11.4/bin/dash'
config_arg3='-Dtargetsh=/home/tony/local/dash-0.5.11.4/bin/dash'
targetsh='/home/tony/local/dash-0.5.11.4/bin/dash'

0.5.10.2:
tony@venus:.../git/perl5$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );' 
Raw: 9, Exit: 0, signal: 9
tony@venus:.../git/perl5$ grep targetsh config.sh
config_args='-des -Dusedevel -Dtargetsh=/home/tony/local/dash-0.5.10.2/bin/dash'
config_arg3='-Dtargetsh=/home/tony/local/dash-0.5.10.2/bin/dash'
targetsh='/home/tony/local/dash-0.5.10.2/bin/dash'

0.5.10(.0)
tony@venus:.../git/perl5$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );' 
Raw: 9, Exit: 0, signal: 9
tony@venus:.../git/perl5$ grep targetsh config.sh
config_args='-des -Dusedevel -Dtargetsh=/home/tony/local/dash-0.5.10/bin/dash'
config_arg3='-Dtargetsh=/home/tony/local/dash-0.5.10/bin/dash'
targetsh='/home/tony/local/dash-0.5.10/bin/dash'

Debian (oldstable)
tony@venus:.../git/perl5$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );' 
Killed
Raw: 35072, Exit: 137, signal: 0
tony@venus:.../git/perl5$ grep targetsh config.sh
config_args='-des -Dusedevel -Dtargetsh=/bin/dash'
config_arg3='-Dtargetsh=/bin/dash'
targetsh='/bin/dash'

Ubuntu 21.04
tony@ubuntu21-04:~/dev/perl/git/perl$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );'
Killed
Raw: 35072, Exit: 137, signal: 0
tony@ubuntu21-04:~/dev/perl/git/perl$ grep targetsh config.sh
targetsh='/bin/sh'
tony@ubuntu21-04:~/dev/perl/git/perl$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Sep 30 10:36 /bin/sh -> dash

Note that the unpatched dash builds all produce the desired behaviour.

From looking at the Debian patch tracker, all of sid (bleeding edge), bookworm (testing), bullseye (stable), buster (oldstable) include this patch:

 src/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main.c b/src/main.c
index b2712cb..12dfc6e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -169,7 +169,7 @@ state2:
 state3:
    state = 4;
    if (minusc)
-       evalstring(minusc, sflag ? 0 : EV_EXIT);
+       evalstring(minusc, 0);

    if (sflag || minusc == NULL) {
 state4:    /* XXX ??? - why isn't this before the "if" statement */

See https://sources.debian.org/patches/dash/0.5.11+git20200708+dd9ef66-5/0004-SHELL-Disable-sh-c-command-sh-c-exec-command-optimiza.diff/

Ubuntu also apply the same patch, per https://git.launchpad.net/ubuntu/+source/dash/tree/debian/patches/0004-SHELL-Disable-sh-c-command-sh-c-exec-command-optimiza.diff

If I apply that to the original sources, I get the same unexpected behaviour:

0.5.11.4 + https://sources.debian.org/patches/dash/0.5.11+git20210120+802ebd4-1/0004-SHELL-Disable-sh-c-command-sh-c-exec-command-optimiza.diff/
tony@venus:.../git/perl5$ ./perl -e '`$^X -e'\''kill "KILL", \$\$'\''`; printf "Raw: $?, Exit: %s, signal: %s\n", ( $? >> 8 ), ( $? & 127 );' 
Killed
Raw: 35072, Exit: 137, signal: 0
You have new mail in /var/mail/tony
tony@venus:.../git/perl5$ grep targetsh config.sh
config_args='-des -Dusedevel -Dtargetsh=/home/tony/local/dash-0.5.11.4-debian/bin/dash'
config_arg3='-Dtargetsh=/home/tony/local/dash-0.5.11.4-debian/bin/dash'
targetsh='/home/tony/local/dash-0.5.11.4-debian/bin/dash'

So it looks like a Debian bug (which Ubuntu inherited).[1]

The patch appears to have been added to work around a build failure with ocamlbuild Debian ocamlbuild

[1] Assuming it's a bug, I'd expect $$ to evaluate to the shell itself rather than the child used to do the kill, but I'm not sure POSIX requires that.