Skip to content

our sub nesting and eval yields crash #21067

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

Closed
mauke opened this issue May 1, 2023 · 1 comment · Fixed by #21149
Closed

our sub nesting and eval yields crash #21067

mauke opened this issue May 1, 2023 · 1 comment · Fixed by #21149

Comments

@mauke
Copy link
Contributor

mauke commented May 1, 2023

Message ID: [email protected]

This is a bug report for perl from zefram at fysh.org,
generated with the help of perlbug 1.44 running under perl 5.37.11.


$ perl -lwe 'our sub foo; 0 if sub { eval "" if 0; \&foo if 0; }'
zsh: segmentation fault  perl -lwe 

Necessary elements to get this crash: named sub declared with "our"
(rather than "my" or "state" or as a package sub); closure sub
(either anonymous sub or "my" sub); string eval use compiled inside
closure sub; reference to the named sub compiled inside closure sub;
closure constructed at runtime. Non-requirements: string eval
doesn't need to execute; reference to the named sub doesn't need to
execute; order of the string eval and sub reference doesn't matter;
closure doesn't need to be called.

Adding "-Mfeature=lexical_subs", this crash occurs all the way
back to Perl 5.17.4 when lexical subs were first introduced.


Flags

  • category=core
  • severity=medium

Perl configuration

This perlbug was built using Perl 5.32.1 - Fri Sep 24 16:10:58 UTC 2021
It is being executed now by  Perl 5.37.11 - Thu Apr 20 22:41:57 BST 2023.

Site configuration information for perl 5.37.11:

Configured by zefram at Thu Apr 20 22:41:57 BST 2023.

Summary of my perl5 (revision 5 version 37 subversion 11) configuration:
   
  Platform:
    osname=linux
    osvers=5.10.0-21-amd64
    archname=x86_64-linux-thread-multi
    uname='linux barba.rous.org 5.10.0-21-amd64 #1 smp debian 5.10.162-1 (2023-01-21) x86_64 gnulinux '
    config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='10.2.1 20210110'
    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 /lib/x86_64-linux-gnu /lib
    libs=-lpthread -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.31.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.31'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/lib/5.37.11/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.37.11:
    /home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/lib/site_perl/5.37.11/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/lib/site_perl/5.37.11
    /home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/lib/5.37.11/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/lib/5.37.11

---
Environment for perl 5.37.11:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.37.11-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh
@mauke
Copy link
Contributor Author

mauke commented May 1, 2023

./perl -lwe 'our sub foo; 0 if sub { eval "" if 0; \&foo if 0; }'
perl: pad.c:408: Perl_cv_undef_flags: Assertion `innercv' failed.
Aborted

tonycoz added a commit to tonycoz/perl5 that referenced this issue Jun 8, 2023
Fixes Perl#21067 but a WIP, needs a better commit message and test.
tonycoz added a commit to tonycoz/perl5 that referenced this issue Jun 9, 2023
Fixes Perl#21067

When an instance of a closure is created, the pad entries for the
cloned sub are copied (S_clone_sv_pad()) from either the prototype
sub (for lexicals belonging to the sub) or from the context (for
lexicals from outside
the sub).

This doesn't happen for our variables, instead the cloned sub has
these pad entries set to NULL.

This isn't an issue at runtime since references to lexical our
sub/variables are compiled into GV or GVSV ops.

cv_undef_flags() assumed this these entries were non-NULL for all
lexical subs.

Fix by checking if the entry is an our sub and the CV being freed is
a clone, if so, skip the accesses to the NULL pad entry.

Added an assert to the new branch to ensure any changes in the above
results in an early failure here and hopefully a fix.
tonycoz added a commit that referenced this issue Jul 25, 2023
Fixes #21067

When an instance of a closure is created, the pad entries for the
cloned sub are copied (S_clone_sv_pad()) from either the prototype
sub (for lexicals belonging to the sub) or from the context (for
lexicals from outside
the sub).

This doesn't happen for our variables, instead the cloned sub has
these pad entries set to NULL.

This isn't an issue at runtime since references to lexical our
sub/variables are compiled into GV or GVSV ops.

cv_undef_flags() assumed this these entries were non-NULL for all
lexical subs.

Fix by checking if the entry is an our sub and the CV being freed is
a clone, if so, skip the accesses to the NULL pad entry.

Added an assert to the new branch to ensure any changes in the above
results in an early failure here and hopefully a fix.
steve-m-hay pushed a commit that referenced this issue Oct 6, 2024
Fixes #21067

When an instance of a closure is created, the pad entries for the
cloned sub are copied (S_clone_sv_pad()) from either the prototype
sub (for lexicals belonging to the sub) or from the context (for
lexicals from outside
the sub).

This doesn't happen for our variables, instead the cloned sub has
these pad entries set to NULL.

This isn't an issue at runtime since references to lexical our
sub/variables are compiled into GV or GVSV ops.

cv_undef_flags() assumed this these entries were non-NULL for all
lexical subs.

Fix by checking if the entry is an our sub and the CV being freed is
a clone, if so, skip the accesses to the NULL pad entry.

Added an assert to the new branch to ensure any changes in the above
results in an early failure here and hopefully a fix.

(cherry picked from commit 59b7881)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant