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

heap-use-after-free Perl_utf8n_to_uvchr (utf8.c:918) #15530

Closed
p5pRT opened this issue Aug 19, 2016 · 19 comments
Closed

heap-use-after-free Perl_utf8n_to_uvchr (utf8.c:918) #15530

p5pRT opened this issue Aug 19, 2016 · 19 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 19, 2016

Migrated from rt.perl.org#128996 (status was 'resolved')

Searchable as RT128996$

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2016

From @geeknik

The attached test case triggers a heap-use-after-free
in Perl_utf8n_to_uvchr (utf8.c​:918). This was found with AFL, ASAN and
libdislocator.so affects v5.25.4 (v5.25.3-305-g8c6b0c7).

==10391==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x619000009c68 at pc 0x000000bb8164 bp 0x7ffddc2e65e0 sp 0x7ffddc2e65d8
READ of size 2 at 0x619000009c68 thread T0
  #0 0xbb8163 in Perl_utf8n_to_uvchr /root/perl/utf8.c​:918​:6
  #1 0x6077de in Perl_yylex /root/perl/toke.c​:4887​:17
  #2 0x6ac9d5 in Perl_yyparse /root/perl/perly.c​:334​:19
  #3 0x59c4a1 in S_parse_body /root/perl/perl.c​:2372​:9
  #4 0x59283c in perl_parse /root/perl/perl.c​:1688​:2
  #5 0x4de835 in main /root/perl/perlmain.c​:121​:18
  #6 0x7f81617f6b44 in __libc_start_main
/build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c​:287
  #7 0x4de4cc in _start (/root/perl/perl+0x4de4cc)

0x619000009c68 is located 232 bytes inside of 1024-byte region
[0x619000009b80,0x619000009f80)
freed by thread T0 here​:
  #0 0x4c0bcb in __interceptor_free (/root/perl/perl+0x4c0bcb)
  #1 0x4e0d8d in Perl_opslab_free /root/perl/op.c​:480​:2

previously allocated by thread T0 here​:
  #0 0x4c0fa0 in calloc (/root/perl/perl+0x4c0fa0)
  #1 0x4dfa34 in S_new_slab /root/perl/op.c​:243​:30
  #2 0x4dfa34 in Perl_Slab_Alloc /root/perl/op.c​:343

SUMMARY​: AddressSanitizer​: heap-use-after-free /root/perl/utf8.c​:918
Perl_utf8n_to_uvchr
Shadow bytes around the buggy address​:
  0x0c327fff9330​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9340​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9350​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9360​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9370​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c327fff9380​: fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd
  0x0c327fff9390​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93a0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93b0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93c0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93d0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes)​:
  Addressable​: 00
  Partially addressable​: 01 02 03 04 05 06 07
  Heap left redzone​: fa
  Heap right redzone​: fb
  Freed heap region​: fd
  Stack left redzone​: f1
  Stack mid redzone​: f2
  Stack right redzone​: f3
  Stack partial redzone​: f4
  Stack after return​: f5
  Stack use after scope​: f8
  Global redzone​: f9
  Global init order​: f6
  Poisoned by user​: f7
  Container overflow​: fc
  ASan internal​: fe
==10391==ABORTING

Perl 5.20.2 returns this set of errors​:

Passing malformed UTF-8 to "" is deprecated at test17 line 1.
Malformed UTF-8 character (unexpected non-continuation byte 0x00,
immediately after start byte 0xdd) at test17 line 1.
Unrecognized character \x{0}; marked by <-- HERE after oin"">0,1}<-- HERE
near column 40 at test17 line 1.

@p5pRT
Copy link
Author

p5pRT commented Aug 19, 2016

From @geeknik

test17.gz

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @tonycoz

On Fri Aug 19 12​:09​:59 2016, brian.carpenter@​gmail.com wrote​:

The attached test case triggers a heap-use-after-free
in Perl_utf8n_to_uvchr (utf8.c​:918). This was found with AFL, ASAN and
libdislocator.so affects v5.25.4 (v5.25.3-305-g8c6b0c7).

Simplifies to the attached.

00000000 42 45 47 49 4e 7b 24 5e 48 3d 30 78 38 30 30 30 |BEGIN{$^H=0x8000|
0000000 B E G I N { $ ^ H = 0 x 8 0 0 0
00000010 30 30 7d dd 0a |00}..|
0000010 0 0 } � \n
0000015

Again, while it's a bug, I don't think it's a security issue.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @tonycoz

On Sun Aug 21 21​:11​:36 2016, tonyc wrote​:

Simplifies to the attached.

Attached, gzipped to prevent any mailers mangling it.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 22, 2016

From @tonycoz

128996b.pl.gz

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2016

From @iabyn

On Sun, Aug 21, 2016 at 09​:11​:36PM -0700, Tony Cook via RT wrote​:

Simplifies to the attached.

00000000 42 45 47 49 4e 7b 24 5e 48 3d 30 78 38 30 30 30 |BEGIN{$^H=0x8000|
0000000 B E G I N { $ ^ H = 0 x 8 0 0 0
00000010 30 30 7d dd 0a |00}..|
0000010 0 0 } � \n
0000015

Again, while it's a bug, I don't think it's a security issue.

I can't reproduce, but again, agreed.

--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
  -- Larry Wall

@p5pRT
Copy link
Author

p5pRT commented Oct 14, 2016

From @geeknik

Triggered in Perl v5.25.6 (v5.25.5-104-gaff2be5) with AFL+ASAN.

Integer overflow in hexadecimal number at test002 line 1.

==24232==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x619000009c28 at pc 0x000000bc48ba bp 0x7fff3b31c8d0 sp 0x7fff3b31c8c8
READ of size 2 at 0x619000009c28 thread T0
  #0 0xbc48b9 in Perl_utf8n_to_uvchr_error /root/perl/utf8.c​:1570​:21
  #1 0x6052e1 in Perl_yylex /root/perl/toke.c​:4887​:17
  #2 0x6addde in Perl_yyparse /root/perl/perly.c​:334​:19
  #3 0x59c581 in S_parse_body /root/perl/perl.c​:2374​:9
  #4 0x59291c in perl_parse /root/perl/perl.c​:1689​:2
  #5 0x4de5e5 in main /root/perl/perlmain.c​:121​:18
  #6 0x7f54a9442b44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
  #7 0x4de27c in _start (/root/perl/perl+0x4de27c)

0x619000009c28 is located 168 bytes inside of 1024-byte region
[0x619000009b80,0x619000009f80)
freed by thread T0 here​:
  #0 0x4c097b in __interceptor_free (/root/perl/perl+0x4c097b)
  #1 0x4e0b3d in Perl_opslab_free /root/perl/op.c​:480​:2

previously allocated by thread T0 here​:
  #0 0x4c0d50 in calloc (/root/perl/perl+0x4c0d50)
  #1 0x4df7e4 in S_new_slab /root/perl/op.c​:243​:30
  #2 0x4df7e4 in Perl_Slab_Alloc /root/perl/op.c​:343

SUMMARY​: AddressSanitizer​: heap-use-after-free /root/perl/utf8.c​:1570
Perl_utf8n_to_uvchr_error
Shadow bytes around the buggy address​:
  0x0c327fff9330​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9340​: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9350​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9360​: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9370​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c327fff9380​: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd
  0x0c327fff9390​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93a0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93b0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93c0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c327fff93d0​: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes)​:
  Addressable​: 00
  Partially addressable​: 01 02 03 04 05 06 07
  Heap left redzone​: fa
  Heap right redzone​: fb
  Freed heap region​: fd
  Stack left redzone​: f1
  Stack mid redzone​: f2
  Stack right redzone​: f3
  Stack partial redzone​: f4
  Stack after return​: f5
  Stack use after scope​: f8
  Global redzone​: f9
  Global init order​: f6
  Poisoned by user​: f7
  Container overflow​: fc
  ASan internal​: fe
==24232==ABORTING

Running under Valgrind with a non-ASAN build​:

Integer overflow in hexadecimal number at test002 line 1.
==17539== Invalid read of size 2
==17539== at 0x5CAF65​: Perl_utf8n_to_uvchr_error (utf8.c​:1571)
==17539== by 0x477AC5​: Perl_yylex (toke.c​:4887)
==17539== by 0x48AA3A​: Perl_yyparse (perly.c​:334)
==17539== by 0x450F87​: S_parse_body (perl.c​:2374)
==17539== by 0x452B1C​: perl_parse (perl.c​:1689)
==17539== by 0x4218FF​: main (perlmain.c​:121)
==17539== Address 0x5f80068 is 168 bytes inside a block of size 1,024
free'd
==17539== at 0x4C29E90​: free (vg_replace_malloc.c​:473)
==17539== by 0x424ABB​: Perl_opslab_free (op.c​:480)
==17539== by 0x4257C5​: Perl_op_free (op.c​:855)
==17539== by 0x492751​: Perl_cv_undef_flags (pad.c​:328)
==17539== by 0x5149FB​: Perl_sv_clear (sv.c​:6517)
==17539== by 0x515926​: Perl_sv_free2 (sv.c​:6967)
==17539== by 0x48A53C​: S_SvREFCNT_dec (inline.h​:189)
==17539== by 0x48A53C​: Perl_yyparse (perly.c​:435)
==17539== by 0x450F87​: S_parse_body (perl.c​:2374)
==17539== by 0x452B1C​: perl_parse (perl.c​:1689)
==17539== by 0x4218FF​: main (perlmain.c​:121)
==17539==
Malformed UTF-8 character​: \xf3 (too short; got 1 byte, need 4) in freed op
at test002 line 1.

@p5pRT
Copy link
Author

p5pRT commented Oct 14, 2016

From @geeknik

test002.gz

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @tonycoz

On Fri Oct 14 13​:35​:03 2016, brian.carpenter@​gmail.com wrote​:

Triggered in Perl v5.25.6 (v5.25.5-104-gaff2be5) with AFL+ASAN.

Integer overflow in hexadecimal number at test002 line 1.

==24232==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x619000009c28 at pc 0x000000bc48ba bp 0x7fff3b31c8d0 sp 0x7fff3b31c8c8
READ of size 2 at 0x619000009c28 thread T0
#0 0xbc48b9 in Perl_utf8n_to_uvchr_error /root/perl/utf8.c​:1570​:21
#1 0x6052e1 in Perl_yylex /root/perl/toke.c​:4887​:17
#2 0x6addde in Perl_yyparse /root/perl/perly.c​:334​:19
#3 0x59c581 in S_parse_body /root/perl/perl.c​:2374​:9
#4 0x59291c in perl_parse /root/perl/perl.c​:1689​:2
#5 0x4de5e5 in main /root/perl/perlmain.c​:121​:18
#6 0x7f54a9442b44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
#7 0x4de27c in _start (/root/perl/perl+0x4de27c)

Simplified to the attached.

The attached patch fixes it.

I don't think this is a security issue, it requires feeding code to the parser.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @tonycoz

0001-perl-129879-prevent-PL_op-pointing-to-freed-ops.patch
From 9b5695063334b507444dd0b833d2eb838b29440a Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Mon, 17 Oct 2016 11:42:20 +1100
Subject: (perl #129879) prevent PL_op pointing to freed ops

When yylex() attempts to report a UTF-8 encoding error, it
indirectly accesses PL_op, this would cause an access to freed
memory if the CV containing that op (and the op itself) had been
freed.
---
 op.c       | 2 --
 t/op/lex.t | 9 ++++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/op.c b/op.c
index 697faa7..1866632 100644
--- a/op.c
+++ b/op.c
@@ -853,10 +853,8 @@ Perl_op_free(pTHX_ OP *o)
 
         op_clear(o);
         FreeOp(o);
-#ifdef DEBUG_LEAKING_SCALARS
         if (PL_op == o)
             PL_op = NULL;
-#endif
     } while ( (o = POP_DEFERRED_OP()) );
 
     Safefree(defer_stack);
diff --git a/t/op/lex.t b/t/op/lex.t
index 9696669..6766e90 100644
--- a/t/op/lex.t
+++ b/t/op/lex.t
@@ -7,7 +7,7 @@ use warnings;
 
 BEGIN { chdir 't' if -d 't'; require './test.pl'; }
 
-plan(tests => 31);
+plan(tests => 32);
 
 {
     no warnings 'deprecated';
@@ -248,3 +248,10 @@ fresh_perl_like(
     {},
     '[perl #129336] - #!perl -i argument handling'
 );
+fresh_perl_is(
+    "BEGIN{\$^H=hex ~0}\xF3",
+    "Integer overflow in hexadecimal number at - line 1.\n" .
+    "Malformed UTF-8 character: \\xf3 (too short; got 1 byte, need 4) at - line 1.",
+    {},
+    '[perl #129879] - use of PL_op after op is freed'
+);
-- 
2.1.4

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @tonycoz

129879a.pl

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

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

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @tonycoz

On Sun Oct 16 17​:50​:48 2016, tonyc wrote​:

On Fri Oct 14 13​:35​:03 2016, brian.carpenter@​gmail.com wrote​:

Triggered in Perl v5.25.6 (v5.25.5-104-gaff2be5) with AFL+ASAN.

Integer overflow in hexadecimal number at test002 line 1.

==24232==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x619000009c28 at pc 0x000000bc48ba bp 0x7fff3b31c8d0 sp
0x7fff3b31c8c8
READ of size 2 at 0x619000009c28 thread T0
#0 0xbc48b9 in Perl_utf8n_to_uvchr_error
/root/perl/utf8.c​:1570​:21
#1 0x6052e1 in Perl_yylex /root/perl/toke.c​:4887​:17
#2 0x6addde in Perl_yyparse /root/perl/perly.c​:334​:19
#3 0x59c581 in S_parse_body /root/perl/perl.c​:2374​:9
#4 0x59291c in perl_parse /root/perl/perl.c​:1689​:2
#5 0x4de5e5 in main /root/perl/perlmain.c​:121​:18
#6 0x7f54a9442b44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
#7 0x4de27c in _start (/root/perl/perl+0x4de27c)

Simplified to the attached.

Actually, this seems to be a duplicate of 128996, my patch also fixes that.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @tonycoz

On Sun Oct 16 17​:50​:48 2016, tonyc wrote​:

The attached patch fixes it.

Applied as 4eadd82 with the ticket number changed.

I don't think this is a security issue, it requires feeding code to
the parser.

Moved to the public queue, and closed.

Tony

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

@tonycoz - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Oct 17, 2016

From @khwilliamson

On 10/16/2016 06​:50 PM, Tony Cook via RT wrote​:

On Fri Oct 14 13​:35​:03 2016, brian.carpenter@​gmail.com wrote​:

Triggered in Perl v5.25.6 (v5.25.5-104-gaff2be5) with AFL+ASAN.

Integer overflow in hexadecimal number at test002 line 1.

==24232==ERROR​: AddressSanitizer​: heap-use-after-free on address
0x619000009c28 at pc 0x000000bc48ba bp 0x7fff3b31c8d0 sp 0x7fff3b31c8c8
READ of size 2 at 0x619000009c28 thread T0
#0 0xbc48b9 in Perl_utf8n_to_uvchr_error /root/perl/utf8.c​:1570​:21
#1 0x6052e1 in Perl_yylex /root/perl/toke.c​:4887​:17
#2 0x6addde in Perl_yyparse /root/perl/perly.c​:334​:19
#3 0x59c581 in S_parse_body /root/perl/perl.c​:2374​:9
#4 0x59291c in perl_parse /root/perl/perl.c​:1689​:2
#5 0x4de5e5 in main /root/perl/perlmain.c​:121​:18
#6 0x7f54a9442b44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
#7 0x4de27c in _start (/root/perl/perl+0x4de27c)

Simplified to the attached.

The attached patch fixes it.

I don't think this is a security issue, it requires feeding code to the parser.

Tony

The test is not going to work on EBCDIC. After I see the reports, I'll
figure out a fix, or a skip.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT p5pRT closed this as completed May 30, 2017
@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

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