Skip to content

writing to magic variables connected to the selected output GV when its IO object has been cleared crashes perl #20733

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
sigdevel opened this issue Jan 21, 2023 · 3 comments · Fixed by #20736

Comments

@sigdevel
Copy link

Description

Tested at 5.15.78-2.el7.3.x86_64 (RED OS release MUROM 7.3.2 - Centos based system), but also reproduced this bug on other platforms x86_64.

Steps to Reproduce

Fonded several examples were found using endless recursion and causing falls.
Insert this string and run with perl -e or run string from file.

while(()){$0=();int""}((unpack("p>",pack("P"))))
for(0){$0=('',unpack('P>',pack('P')))}
sub o{}*STDOUT=0;{{$~=0}{()}}

Expected behavior

Is it correct that the interpreter does not processing such samples (even with the flag -w) and just calling SEGFAULT when trying to address the memory areas inaccessible to recording?

Perl configuration

perl version: v5.30.1
@jkeenan
Copy link
Contributor

jkeenan commented Jan 21, 2023

Steps to Reproduce

Found several examples were found using endless recursion and causing falls. Insert this string and run with perl -e or run string from file.

while(()){$0=();int""}((unpack("p>",pack("P"))))
for(0){$0=('',unpack('P>',pack('P')))}

Rewritten slightly for quotation marks as:
$ perl -e 'for(0){$0=(q||,unpack(q|P>|,pack(q|P|)))}'

sub o{}*STDOUT=0;{{$~=0}{()}}

In all cases, confirmed on FreeBSD-12 at both perl-5.32 and blead. Output:

Bus error (core dumped)

@demerphq
Copy link
Collaborator

demerphq commented Jan 22, 2023 via email

@tonycoz
Copy link
Contributor

tonycoz commented Jan 23, 2023

while(()){$0=();int""}((unpack("p>",pack("P"))))
for(0){$0=('',unpack('P>',pack('P')))}

You're creating a pointer to something (pack 'P') then swapping the byte order of the pointer, and trying to access what it refers to.

The P/p pack/unpack template characters are very low level, you can't blindly use them and expect a sane result.

If you have a specific case where you expect some behaviour from these template characters and don't get it, please provide all the details, not just a "this crashes". You can assume unpack "P" or "p" crashes by default.

sub o{}*STDOUT=0;{{$~=0}{()}}

This is a real problem, and applies to other magic variables when *STDOUT has been cleared:

tony@venus:.../git/perl6$ ./perl -e '*STDOUT=0; $~ = 0;'
Segmentation fault
tony@venus:.../git/perl6$ ./perl -e '*STDOUT=0; $^ = 0;'
Segmentation fault
tony@venus:.../git/perl6$ ./perl -e '*STDOUT=0; $% = 0;'
Segmentation fault
tony@venus:.../git/perl6$ ./perl -e '*STDOUT=0; $- = 0;'
Segmentation fault
tony@venus:.../git/perl6$ ./perl -e '*STDOUT=0; $= = 0;'
Segmentation fault

tonycoz added a commit to tonycoz/perl5 that referenced this issue Jan 23, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes Perl#20733
@tonycoz tonycoz changed the title Some samples with endless recursion cause Segfault writing to magic variables connected to the selected output GV when its IO object has been cleared crashes perl Jan 24, 2023
tonycoz added a commit that referenced this issue Jan 24, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes #20733
steve-m-hay pushed a commit that referenced this issue Apr 10, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes #20733

(cherry picked from commit af62106)
pjacklam pushed a commit to pjacklam/perl5 that referenced this issue May 20, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes Perl#20733
pjacklam pushed a commit to pjacklam/perl5 that referenced this issue May 20, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes Perl#20733
khwilliamson pushed a commit to khwilliamson/perl5 that referenced this issue Jul 10, 2023
pp_select() ensures that the GV in PL_defoutgv has an IO object
when it the default output is set, but can't prevent that GV
being cleared afterwards, resulting in a seg fault when the
variable is written.

To prevent this, check PL_defoutgv has an IO object before trying
to write to it.

Fixes Perl#20733
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.

4 participants