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

Null pointer dereference in Perl_sv_setpvn() #16133

Closed
p5pRT opened this issue Aug 31, 2017 · 12 comments
Closed

Null pointer dereference in Perl_sv_setpvn() #16133

p5pRT opened this issue Aug 31, 2017 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 31, 2017

Migrated from rt.perl.org#132001 (status was 'rejected')

Searchable as RT132001$

@p5pRT
Copy link
Author

p5pRT commented Aug 31, 2017

From fumfi.255@gmail.com

After some fuzz testing I found a crashing test case.

perl -v output​: This is perl 5, version 27, subversion 4 (v5.27.4
(v5.27.3-15-ga0fd450)) built for x86_64-linux

Faulting test case in attachment.

Command​: perl perl_nullptr_Perl_sv_setpvn

ASAN Context​:

==19717==ERROR​: AddressSanitizer​: SEGV on unknown address 0x000000000000
(pc 0x0000004c692a bp 0x7ffc1268bd90 sp 0x7ffc1268b540 T0)
==19717==The signal is caused by a READ memory access.
==19717==Hint​: address points to the zero page.
  #0 0x4c6929 in AddressIsPoisoned
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_mapping.h​:322​:29
  #1 0x4c6929 in QuickCheckForUnpoisonedRegion
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc​:43
  #2 0x4c6929 in __asan_memmove
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_interceptors.cc​:461
  #3 0x96fcf3 in Perl_sv_setpvn XYZ/perl/sv.c​:5001​:5
  #4 0x9beff4 in Perl_newSVpvn_flags XYZ/perl/sv.c​:9302​:5
  #5 0xd11801 in S_unpack_rec XYZ/perl/pp_pack.c​:1627​:3
  #6 0xd0bd11 in Perl_unpackstring XYZ/perl/pp_pack.c​:838​:12
  #7 0xd26662 in Perl_pp_unpack XYZ/perl/pp_pack.c​:1848​:11
  #8 0x83945c in Perl_runops_debug XYZ/perl/dump.c​:2486​:23
  #9 0x5e0120 in S_run_body XYZ/perl/perl.c
  #10 0x5e0120 in perl_run XYZ/perl/perl.c​:2484
  #11 0x509498 in main XYZ/perl/perlmain.c​:123​:9
  #12 0x7f3f0faf082f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
  #13 0x4359c8 in _start (XYZ/perl/perl+0x4359c8)

AddressSanitizer can not provide additional info.
SUMMARY​: AddressSanitizer​: SEGV
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-rt/lib/asan/asan_mapping.h​:322​:29
in AddressIsPoisoned
==19717==ABORTING

Pozdrawiam / Best Regards
Kamil Frankowicz

@p5pRT
Copy link
Author

p5pRT commented Aug 31, 2017

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2017

From @atoomic

To save some time to readers, the test case from attachment is the following

$$_=0;$0=unpack'@​'|'0'&~*0

On Thu, 31 Aug 2017 00​:32​:54 -0700, fumfi.255@​gmail.com wrote​:

After some fuzz testing I found a crashing test case.

perl -v output​: This is perl 5, version 27, subversion 4 (v5.27.4
(v5.27.3-15-ga0fd450)) built for x86_64-linux

Faulting test case in attachment.

Command​: perl perl_nullptr_Perl_sv_setpvn

ASAN Context​:

==19717==ERROR​: AddressSanitizer​: SEGV on unknown address
0x000000000000
(pc 0x0000004c692a bp 0x7ffc1268bd90 sp 0x7ffc1268b540 T0)
==19717==The signal is caused by a READ memory access.
==19717==Hint​: address points to the zero page.
#0 0x4c6929 in AddressIsPoisoned
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_mapping.h​:322​:29
#1 0x4c6929 in QuickCheckForUnpoisonedRegion
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_interceptors.cc​:43
#2 0x4c6929 in __asan_memmove
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_interceptors.cc​:461
#3 0x96fcf3 in Perl_sv_setpvn XYZ/perl/sv.c​:5001​:5
#4 0x9beff4 in Perl_newSVpvn_flags XYZ/perl/sv.c​:9302​:5
#5 0xd11801 in S_unpack_rec XYZ/perl/pp_pack.c​:1627​:3
#6 0xd0bd11 in Perl_unpackstring XYZ/perl/pp_pack.c​:838​:12
#7 0xd26662 in Perl_pp_unpack XYZ/perl/pp_pack.c​:1848​:11
#8 0x83945c in Perl_runops_debug XYZ/perl/dump.c​:2486​:23
#9 0x5e0120 in S_run_body XYZ/perl/perl.c
#10 0x5e0120 in perl_run XYZ/perl/perl.c​:2484
#11 0x509498 in main XYZ/perl/perlmain.c​:123​:9
#12 0x7f3f0faf082f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#13 0x4359c8 in _start (XYZ/perl/perl+0x4359c8)

AddressSanitizer can not provide additional info.
SUMMARY​: AddressSanitizer​: SEGV
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_mapping.h​:322​:29
in AddressIsPoisoned
==19717==ABORTING

Pozdrawiam / Best Regards
Kamil Frankowicz

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2017

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2017

From @atoomic

need more investigation, seems this is happening in S_unpack_rec when calling SHIFT_VAR
needs_swap and utf8 are both false

  │1624 char *aptr;
  │1625 SHIFT_VAR(utf8, s, strend, aptr, datumtype, needs_swap);
  │1626 /* newSVpvn generates undef if aptr is NULL */
  >│1627 PUSHs(newSVpvn_flags(aptr, len, SVs_TEMP));

backtrace run

Program received signal SIGBUS, Bus error.
0x00007ffff6d2f55e in __memmove_sse2 (dest=<optimized out>, src=<optimized out>, len=<optimized out>) at ../string/memmove.c​:85
85 BYTE_COPY_FWD (dstp, srcp, len);
(gdb) bt
#0 0x00007ffff6d2f55e in __memmove_sse2 (dest=<optimized out>, src=<optimized out>, len=<optimized out>) at ../string/memmove.c​:85
#1 0x0000000000532d6a in Perl_sv_setpvn (sv=0x89cd90, ptr=0x302852414c414353 <Address 0x302852414c414353 out of bounds>, len=1) at sv.c​:5001
#2 0x000000000053c465 in Perl_newSVpvn_flags (s=0x302852414c414353 <Address 0x302852414c414353 out of bounds>, len=1, flags=524288) at sv.c​:9302
#3 0x00000000005e705e in S_unpack_rec (symptr=0x7fffffffd9f0, s=0x89f672 "x881190)", strbeg=0x89f66a "SCALAR(0x881190)", strend=0x89f67a "", new_s=0x0) at pp_pack.c​:1627
#4 0x00000000005e3a94 in Perl_unpackstring (pat=0x897610 "P", patend=0x897611 "", s=0x89f66a "SCALAR(0x881190)", strend=0x89f67a "", flags=16) at pp_pack.c​:838
#5 0x00000000005e7f15 in Perl_pp_unpack () at pp_pack.c​:1848
#6 0x000000000051524c in Perl_runops_standard () at run.c​:41
#7 0x000000000044c6c0 in S_run_body (oldscope=1) at perl.c​:2561
#8 0x000000000044c261 in perl_run (my_perl=0x87f010) at perl.c​:2484
#9 0x000000000041f255 in main (argc=2, argv=0x7fffffffdd98, env=0x7fffffffddb0) at perlmain.c​:123

On Thu, 31 Aug 2017 00​:32​:54 -0700, fumfi.255@​gmail.com wrote​:

After some fuzz testing I found a crashing test case.

perl -v output​: This is perl 5, version 27, subversion 4 (v5.27.4
(v5.27.3-15-ga0fd450)) built for x86_64-linux

Faulting test case in attachment.

Command​: perl perl_nullptr_Perl_sv_setpvn

ASAN Context​:

==19717==ERROR​: AddressSanitizer​: SEGV on unknown address
0x000000000000
(pc 0x0000004c692a bp 0x7ffc1268bd90 sp 0x7ffc1268b540 T0)
==19717==The signal is caused by a READ memory access.
==19717==Hint​: address points to the zero page.
#0 0x4c6929 in AddressIsPoisoned
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_mapping.h​:322​:29
#1 0x4c6929 in QuickCheckForUnpoisonedRegion
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_interceptors.cc​:43
#2 0x4c6929 in __asan_memmove
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_interceptors.cc​:461
#3 0x96fcf3 in Perl_sv_setpvn XYZ/perl/sv.c​:5001​:5
#4 0x9beff4 in Perl_newSVpvn_flags XYZ/perl/sv.c​:9302​:5
#5 0xd11801 in S_unpack_rec XYZ/perl/pp_pack.c​:1627​:3
#6 0xd0bd11 in Perl_unpackstring XYZ/perl/pp_pack.c​:838​:12
#7 0xd26662 in Perl_pp_unpack XYZ/perl/pp_pack.c​:1848​:11
#8 0x83945c in Perl_runops_debug XYZ/perl/dump.c​:2486​:23
#9 0x5e0120 in S_run_body XYZ/perl/perl.c
#10 0x5e0120 in perl_run XYZ/perl/perl.c​:2484
#11 0x509498 in main XYZ/perl/perlmain.c​:123​:9
#12 0x7f3f0faf082f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#13 0x4359c8 in _start (XYZ/perl/perl+0x4359c8)

AddressSanitizer can not provide additional info.
SUMMARY​: AddressSanitizer​: SEGV
/scratch/llvm/clang-4/xenial/final/llvm.src/projects/compiler-
rt/lib/asan/asan_mapping.h​:322​:29
in AddressIsPoisoned
==19717==ABORTING

Pozdrawiam / Best Regards
Kamil Frankowicz

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2017

From @tonycoz

On Fri, 01 Sep 2017 12​:53​:02 -0700, atoomic wrote​:

To save some time to readers, the test case from attachment is the following

$$_=0;$0=unpack'@​'|'0'&~*0

The

  '@​'|'0'&~*0

expression evaluates to

  'P'

so the program is equivalent to​:

  $$_=0; $0=unpack"P"

The $$_ = 0 auto-vivifies $_ into a scalar reference, so the unpack behaves like​:

  $0 = unpack "P", "SCALAR(0x...)";

The P template for pack reads a pointer from the supplied scalar, so treating the bytes "SCAL" or "SCALAR(0" as a pointer, which very reasonably crashes.

This isn't a bug.

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2017

@tonycoz - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Sep 4, 2017
@p5pRT
Copy link
Author

p5pRT commented Sep 4, 2017

From @demerphq

I agree it's not a bug but the P format is arguably a security concern.
Maybe P should only be available under a pragma specifying it is legal (and
thus that the programmer understands they get to keep both pieces if it
blows up in their face).

Yves

On 4 Sep 2017 04​:30, "Tony Cook via RT" <perlbug-followup@​perl.org> wrote​:

On Fri, 01 Sep 2017 12​:53​:02 -0700, atoomic wrote​:

To save some time to readers, the test case from attachment is the
following

$$_=0;$0=unpack'@​'|'0'&~*0

The

'@​'|'0'&~*0

expression evaluates to

'P'

so the program is equivalent to​:

$$_=0; $0=unpack"P"

The $$_ = 0 auto-vivifies $_ into a scalar reference, so the unpack
behaves like​:

$0 = unpack "P", "SCALAR(0x...)";

The P template for pack reads a pointer from the supplied scalar, so
treating the bytes "SCAL" or "SCALAR(0" as a pointer, which very reasonably
crashes.

This isn't a bug.

Tony

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001

@p5pRT
Copy link
Author

p5pRT commented Sep 5, 2017

From @xsawyerx

Before we evaluate such an option, it would be good to have a cursory
check of CPAN.

On 09/04/2017 12​:18 PM, demerphq wrote​:

I agree it's not a bug but the P format is arguably a security
concern. Maybe P should only be available under a pragma specifying it
is legal (and thus that the programmer understands they get to keep
both pieces if it blows up in their face).

Yves

On 4 Sep 2017 04​:30, "Tony Cook via RT" <perlbug-followup@​perl.org
<mailto​:perlbug-followup@​perl.org>> wrote​:

On Fri\, 01 Sep 2017 12&#8203;:53&#8203;:02 \-0700\, atoomic wrote&#8203;:
> To save some time to readers\, the test case from attachment is
the following
>
> $$\_=0;$0=unpack'@&#8203;'|'0'&~\*0

The

  '@&#8203;'|'0'&~\*0

expression evaluates to

  'P'

so the program is equivalent to&#8203;:

  $$\_=0; $0=unpack"P"

The $$\_ = 0 auto\-vivifies $\_ into a scalar reference\, so the
unpack behaves like&#8203;:

  $0 = unpack "P"\, "SCALAR\(0x\.\.\.\)";

The P template for pack reads a pointer from the supplied scalar\,
so treating the bytes "SCAL" or "SCALAR\(0" as a pointer\, which
very reasonably crashes\.

This isn't a bug\.

Tony

\-\-\-
via perlbug&#8203;:  queue&#8203;: perl5 status&#8203;: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001
\<https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001>

@p5pRT
Copy link
Author

p5pRT commented Sep 5, 2017

From @khwilliamson

On 09/05/2017 07​:01 AM, Sawyer X wrote​:

Before we evaluate such an option, it would be good to have a cursory
check of CPAN.

Since grep.cpan.me has been down for some time, such a check is
currently impossible.

On 09/04/2017 12​:18 PM, demerphq wrote​:

I agree it's not a bug but the P format is arguably a security
concern. Maybe P should only be available under a pragma specifying it
is legal (and thus that the programmer understands they get to keep
both pieces if it blows up in their face).

Yves

On 4 Sep 2017 04​:30, "Tony Cook via RT" <perlbug-followup@​perl.org
<mailto​:perlbug-followup@​perl.org>> wrote​:

 On Fri\, 01 Sep 2017 12&#8203;:53&#8203;:02 \-0700\, atoomic wrote&#8203;:
 > To save some time to readers\, the test case from attachment is
 the following
 >
 > $$\_=0;$0=unpack'@&#8203;'|'0'&~\*0

 The

   '@&#8203;'|'0'&~\*0

 expression evaluates to

   'P'

 so the program is equivalent to&#8203;:

   $$\_=0; $0=unpack"P"

 The $$\_ = 0 auto\-vivifies $\_ into a scalar reference\, so the
 unpack behaves like&#8203;:

   $0 = unpack "P"\, "SCALAR\(0x\.\.\.\)";

 The P template for pack reads a pointer from the supplied scalar\,
 so treating the bytes "SCAL" or "SCALAR\(0" as a pointer\, which
 very reasonably crashes\.

 This isn't a bug\.

 Tony

 \-\-\-
 via perlbug&#8203;:  queue&#8203;: perl5 status&#8203;: open
 https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001
 \<https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001>

@p5pRT
Copy link
Author

p5pRT commented Sep 5, 2017

From @xsawyerx

grep.metacpan.org

On 09/05/2017 05​:57 PM, Karl Williamson wrote​:

On 09/05/2017 07​:01 AM, Sawyer X wrote​:

Before we evaluate such an option, it would be good to have a cursory
check of CPAN.

Since grep.cpan.me has been down for some time, such a check is
currently impossible.

On 09/04/2017 12​:18 PM, demerphq wrote​:

I agree it's not a bug but the P format is arguably a security
concern. Maybe P should only be available under a pragma specifying it
is legal (and thus that the programmer understands they get to keep
both pieces if it blows up in their face).

Yves

On 4 Sep 2017 04​:30, "Tony Cook via RT" <perlbug-followup@​perl.org
<mailto​:perlbug-followup@​perl.org>> wrote​:

 On Fri\, 01 Sep 2017 12&#8203;:53&#8203;:02 \-0700\, atoomic wrote&#8203;:
 > To save some time to readers\, the test case from attachment is
 the following
 >
 > $$\_=0;$0=unpack'@&#8203;'|'0'&~\*0

 The

   '@&#8203;'|'0'&~\*0

 expression evaluates to

   'P'

 so the program is equivalent to&#8203;:

   $$\_=0; $0=unpack"P"

 The $$\_ = 0 auto\-vivifies $\_ into a scalar reference\, so the
 unpack behaves like&#8203;:

   $0 = unpack "P"\, "SCALAR\(0x\.\.\.\)";

 The P template for pack reads a pointer from the supplied scalar\,
 so treating the bytes "SCAL" or "SCALAR\(0" as a pointer\, which
 very reasonably crashes\.

 This isn't a bug\.

 Tony

 \-\-\-
 via perlbug&#8203;:  queue&#8203;: perl5 status&#8203;: open
 https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001
 \<https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001>

@p5pRT
Copy link
Author

p5pRT commented Sep 5, 2017

From @ilmari

Karl Williamson <public@​khwilliamson.com> writes​:

On 09/05/2017 07​:01 AM, Sawyer X wrote​:

Before we evaluate such an option, it would be good to have a cursory
check of CPAN.

Since grep.cpan.me has been down for some time, such a check is
currently impossible.

However, https://grep.metacpan.org/ is up and running, and gives 44
distributions (some of which are false positives)​:

https://grep.metacpan.org/search?q=\bunpack\s*\(%3F\s*\S%2BP&qd=&qft=

On 09/04/2017 12​:18 PM, demerphq wrote​:

I agree it's not a bug but the P format is arguably a security
concern. Maybe P should only be available under a pragma specifying it
is legal (and thus that the programmer understands they get to keep
both pieces if it blows up in their face).

Yves

On 4 Sep 2017 04​:30, "Tony Cook via RT" <perlbug-followup@​perl.org
<mailto​:perlbug-followup@​perl.org>> wrote​:

 On Fri\, 01 Sep 2017 12&#8203;:53&#8203;:02 \-0700\, atoomic wrote&#8203;:
 > To save some time to readers\, the test case from attachment is
 the following
 >
 > $$\_=0;$0=unpack'@&#8203;'|'0'&~\*0

 The

   '@&#8203;'|'0'&~\*0

 expression evaluates to

   'P'

 so the program is equivalent to&#8203;:

   $$\_=0; $0=unpack"P"

 The $$\_ = 0 auto\-vivifies $\_ into a scalar reference\, so the
 unpack behaves like&#8203;:

   $0 = unpack "P"\, "SCALAR\(0x\.\.\.\)";

 The P template for pack reads a pointer from the supplied scalar\,
 so treating the bytes "SCAL" or "SCALAR\(0" as a pointer\, which
 very reasonably crashes\.

 This isn't a bug\.

 Tony

 \-\-\-
 via perlbug&#8203;:  queue&#8203;: perl5 status&#8203;: open
 https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001
 \<https://rt-archive.perl.org/perl5/Ticket/Display.html?id=132001>

--
- Twitter seems more influential [than blogs] in the 'gets reported in
  the mainstream press' sense at least. - Matt McLeod
- That'd be because the content of a tweet is easier to condense down
  to a mainstream media article. - Calle Dybedahl

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

No branches or pull requests

1 participant