Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault in simple program reading from ARGV #19340

Open
sisyphus-ppcg opened this issue Jan 11, 2022 · 10 comments
Open

Segfault in simple program reading from ARGV #19340

sisyphus-ppcg opened this issue Jan 11, 2022 · 10 comments

Comments

@sisyphus-ppcg
Copy link

Steps to Reproduce
Run on your command line.

perl -e 'map<>,@ARGV' 1 2 < /dev/null

Expected behavior
No segfault.

Actual behavior

sisyphus$ perl -e 'map<>,@ARGV' 1 2 < /dev/null
Can't open 1: No such file or directory at -e line 1.
Can't open 2: No such file or directory at -e line 1.
Segmentation fault

Note that the segfault happens regardless of whether the files in @ARGV exist or not.

Perl configuration

Summary of my perl5 (revision 5 version 34 subversion 0) configuration:

  Platform:
    osname=linux
    osvers=4.19.128-microsoft-standard
    archname=x86_64-linux
    uname='linux laptop-u12kikmv 4.19.128-microsoft-standard #1 smp tue jun 23 12:58:10 utc 2020 x86_64 x86_64 x86_64 gnulinux '
    config_args='-de -Dprefix=/home/sisyphus/perl5/perlbrew/perls/perl-5.34.0 -Aeval:scriptdir=/home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/bin'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=undef
    usemultiplicity=undef
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='-O2'
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='9.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='cc'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64
    libs=-lpthread -lnsl -lgdbm -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.31.so
    so=so
    useshrplib=false
    libperl=libperl.a
    gnulibc_version='2.31'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


Characteristics of this binary (from libperl):
  Compile-time options:
    HAS_TIMES
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
  Built under linux
  Compiled at Jan 11 2022 11:07:31
  %ENV:
    PERL5LIB="/home/sisyphus/perl5/lib/perl5"
    PERLBREW_HOME="/home/sisyphus/.perlbrew"
    PERLBREW_MANPATH="/home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/man"
    PERLBREW_PATH="/home/sisyphus/perl5/perlbrew/bin:/home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/bin"
    PERLBREW_PERL="perl-5.34.0"
    PERLBREW_ROOT="/home/sisyphus/perl5/perlbrew"
    PERLBREW_SHELLRC_VERSION="0.94"
    PERLBREW_VERSION="0.94"
    PERL_LOCAL_LIB_ROOT="/home/sisyphus/perl5"
    PERL_MB_OPT="--install_base "/home/sisyphus/perl5""
    PERL_MM_OPT="INSTALL_BASE=/home/sisyphus/perl5"
  @INC:
    /home/sisyphus/perl5/lib/perl5
    /home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0/x86_64-linux
    /home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/lib/site_perl/5.34.0
    /home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/lib/5.34.0/x86_64-linux
    /home/sisyphus/perl5/perlbrew/perls/perl-5.34.0/lib/5.34.0
@hvds
Copy link
Contributor

hvds commented Jan 12, 2022

Confirmed with blead@7931406120; miniperl is sufficient, -w may also be present:

% ./miniperl -we 'map <>, @ARGV' 1 2 </dev/null
Can't open 1: No such file or directory at -e line 1.
Can't open 2: No such file or directory at -e line 1.
miniperl: sv.c:6784: Perl_sv_clear: Assertion `SvTYPE(sv) != (svtype)SVTYPEMASK' failed.
Aborted (core dumped)

Stack trace from the assert() shows:

#4  0x000055f4bd3e25ed in Perl_sv_clear (orig_sv=0x55f4be60e9d8) at sv.c:6784
#5  0x000055f4bd3e59a3 in Perl_sv_free2 (sv=0x55f4be60e9d8, rc=1) at sv.c:7360
#6  0x000055f4bd44279a in Perl_SvREFCNT_dec (sv=0x55f4be60e9d8) at inline.h:398
#7  0x000055f4bd447916 in Perl_leave_scope (base=0) at scope.c:992
#8  0x000055f4bd442e09 in Perl_pop_scope () at scope.c:130
#9  0x000055f4bd454d64 in Perl_pp_mapwhile () at pp_ctl.c:1115
#10 0x000055f4bd33d2ff in Perl_runops_debug () at dump.c:2588
#11 0x000055f4bd20113b in S_run_body (oldscope=1) at perl.c:2725
#12 0x000055f4bd2006b6 in perl_run (my_perl=0x55f4be5ea260) at perl.c:2648
#13 0x000055f4bd551cd6 in main (argc=5, argv=0x7ffd20a69528, 
    env=0x7ffd20a69558) at miniperlmain.c:116

I haven't tried to dig further yet - could this be a stack refcounting issue?

@JRaspass
Copy link
Contributor

Yeah recounting seems likely as taking a copy seems to "fix" it:

$ perl -e 'map<>,@foo=@ARGV' 1 2 </dev/null
Can't open 1: No such file or directory at -e line 1.
Can't open 2: No such file or directory at -e line 1.

FGasper added a commit to FGasper/perl5 that referenced this issue Feb 8, 2022
Issue Perl#19340: This prevents an obscure segfault.
@FGasper
Copy link
Contributor

FGasper commented Feb 8, 2022

Perl_nextargv() sets each argv to SAVEFREESV(). This conflicts with the fact that those same SVs are in @ARGV.

FGasper added a commit to FGasper/perl5 that referenced this issue Feb 8, 2022
Issue Perl#19340: This prevents an obscure segfault.
@Leont
Copy link
Contributor

Leont commented Feb 8, 2022

Yeah recounting seems likely as taking a copy seems to "fix" it:

I think that strongly suggests that this is another case of the infamous "the stack is not refcounted" bug.

@FGasper
Copy link
Contributor

FGasper commented Feb 9, 2022

I think that strongly suggests that this is another case of the infamous "the stack is not refcounted" bug.

Can you possibly point to some previous solutions for this one?

Here is another example of what seems to be the same bug (or at least a closely-related one):

> perl -e'my @foo = qw(1 2 3); map { @foo = () } @foo'
zsh: segmentation fault  perl -e'my @foo = qw(1 2 3); map { @foo = () } @foo'

FGasper added a commit to FGasper/perl5 that referenced this issue Feb 9, 2022
Issue Perl#19340: Previously if you mapped/grepped over an array and mutated
the array within the map/grep, a segfault would happen. This fixes that
by bumping the map/grep args' reference count at the start of the map/grep,
then enqueueing those args for a refcount decrement at the end.
@Leont
Copy link
Contributor

Leont commented Feb 9, 2022

Can you possibly point to some previous solutions for this one?

I can't, unfortunately. Fixing this is a fairly big refactor (one I would be in favor of nonetheless).

Here is another example of what seems to be the same bug (or at least a closely-related one):

Yes, that's exactly the category of bug I'm talking about.

@FGasper
Copy link
Contributor

FGasper commented Feb 9, 2022

@Leont Then I’m guessing the refcount-bump fix I just pushed has some drawback, or else someone would likely have already implemented it …

@demerphq
Copy link
Collaborator

demerphq commented Feb 9, 2022 via email

@hvds
Copy link
Contributor

hvds commented Feb 9, 2022

It would be nice to fix the problem, but I can't personally say how easy that would be, nor what kind of performance consequences it would have. The fact that none of the relavently skilled internals hackers have taken it on is suggestive that it is intractable, or at the very least low ROI.

As far as I recall, @iabyn was at one point considering taking this on as his next big project. I don't know if he still is.

@iabyn
Copy link
Contributor

iabyn commented Mar 7, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants