Open p5pRT opened 7 years ago
Hello\,
I've attached the poc and the asan log. Tested on git version of perl.
Configure options:
“./Configure -des -Dusedevel -DDEBUGGING -Dcc=clang -Doptimize=-O2 -Accflags="-fsanitize=address -fsanitize-coverage=edge" -Aldflags="-fsanitize=address -fsanitize-coverage=edge" -Alddlflags=-shared"
Information about configuration:
Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety Arch: x86_64
Best Regards\, Marcin T.
==11610==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000113f at pc 0x00000080b9cc bp 0x7fff324f3110 sp 0x7fff324f3108 READ of size 1 at 0x60200000113f thread T0 #0 0x80b9cb in S_ckwarn_common /home/mtowalski/Fuzzing/Programs/perl-git/util.c:2027:6 #1 0x655ce6 in S_pending_ident /home/mtowalski/Fuzzing/Programs/perl-git/toke.c:8971:9 #2 0x655ce6 in Perl_yylex /home/mtowalski/Fuzzing/Programs/perl-git/toke.c:4811 #3 0x6e834d in Perl_yyparse /home/mtowalski/Fuzzing/Programs/perl-git/perly.c:340:34 #4 0x5e3dc6 in S_parse_body /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:2377:9 #5 0x5db300 in perl_parse /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:1692:2 #6 0x5242ce in main /home/mtowalski/Fuzzing/Programs/perl-git/perlmain.c:121:18 #7 0x7f209dc513f0 in __libc_start_main /build/glibc-jxM2Ev/glibc-2.24/csu/../csu/libc-start.c:291 #8 0x4356f9 in _start (/home/mtowalski/Fuzzing/Programs/perl-git/perl+0x4356f9)
0x60200000113f is located 6 bytes to the right of 9-byte region [0x602000001130\,0x602000001139) allocated by thread T0 here: #0 0x4eb0a8 in malloc (/home/mtowalski/Fuzzing/Programs/perl-git/perl+0x4eb0a8) #1 0x5548ac in Perl_block_start /home/mtowalski/Fuzzing/Programs/perl-git/op.c:4106:33 #2 0x5e3dc6 in S_parse_body /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:2377:9 #3 0x5db300 in perl_parse /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:1692:2 #4 0x5242ce in main /home/mtowalski/Fuzzing/Programs/perl-git/perlmain.c:121:18 #5 0x7f209dc513f0 in __libc_start_main /build/glibc-jxM2Ev/glibc-2.24/csu/../csu/libc-start.c:291
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/mtowalski/Fuzzing/Programs/perl-git/util.c:2027:6 in S_ckwarn_common Shadow bytes around the buggy address: 0x0c047fff81d0: fa fa 00 01 fa fa 00 01 fa fa 00 00 fa fa 00 00 0x0c047fff81e0: fa fa 00 02 fa fa 07 fa fa fa 02 fa fa fa 00 04 0x0c047fff81f0: fa fa fd fd fa fa fd fd fa fa fd fd fa fa 00 02 0x0c047fff8200: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fd 0x0c047fff8210: fa fa 00 02 fa fa fd fd fa fa 00 05 fa fa 00 02 =>0x0c047fff8220: fa fa 00 02 fa fa 00[01]fa fa fa fa fa fa fa fa 0x0c047fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8240: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==11610==ABORTING
On 03/04/2017 06:03 AM\, (via RT) wrote:
# New Ticket Created by # Please include the string: [perl #130916] # in the subject line of all future correspondence about this issue. # \<URL: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=130916 >
Hello\,
I've attached the poc and the asan log. Tested on git version of perl.
Configure options:
“./Configure -des -Dusedevel -DDEBUGGING -Dcc=clang -Doptimize=-O2 -Accflags="-fsanitize=address -fsanitize-coverage=edge" -Aldflags="-fsanitize=address -fsanitize-coverage=edge" -Alddlflags=-shared"
Information about configuration:
Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety Arch: x86_64
Best Regards\, Marcin T.
Hello\,
I've attached the poc and the asan log. Tested on git version of perl.
Configure options:
“./Configure -des -Dusedevel -DDEBUGGING -Dcc=clang -Doptimize=-O2 -Accflags="-fsanitize=address -fsanitize-coverage=edge" -Aldflags="-fsanitize=address -fsanitize-coverage=edge" -Alddlflags=-shared"
Information about configuration:
Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety Arch: x86_64
Best Regards\, Marcin T.
All these are weird around the locale setting. Could you run this with the environment variable PERL_DEBUG_LOCALE_INIT=1 and send the output.
The RT System itself - Status changed from 'new' to 'open'
Hello\,
Here is the output from the command - "PERL_DEBUG_LOCALE_INIT=1 ./perl perl-heap-buffer-overflow-9cb-ce6-ce6”
Best Regards\, Marcin T.
On 5 Mar 2017\, at 05:51\, karl williamson via RT \perl5\-security\-report@​perl\.org wrote:
On 03/04/2017 06:03 AM\, (via RT) wrote:
# New Ticket Created by # Please include the string: [perl #130916] # in the subject line of all future correspondence about this issue. # \<URL: https://rt.perl.org/Ticket/Display.html?id=130916 \https://rt-archive.perl.org/perl5/Ticket/Display.html?id=130916 >
Hello\,
I've attached the poc and the asan log. Tested on git version of perl.
Configure options:
“./Configure -des -Dusedevel -DDEBUGGING -Dcc=clang -Doptimize=-O2 -Accflags="-fsanitize=address -fsanitize-coverage=edge" -Aldflags="-fsanitize=address -fsanitize-coverage=edge" -Alddlflags=-shared"
Information about configuration:
Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety Arch: x86_64
Best Regards\, Marcin T.
Hello\,
I've attached the poc and the asan log. Tested on git version of perl.
Configure options:
“./Configure -des -Dusedevel -DDEBUGGING -Dcc=clang -Doptimize=-O2 -Accflags="-fsanitize=address -fsanitize-coverage=edge" -Aldflags="-fsanitize=address -fsanitize-coverage=edge" -Alddlflags=-shared"
Information about configuration:
Distributor ID: Ubuntu Description: Ubuntu 16.10 Release: 16.10 Codename: yakkety Arch: x86_64
Best Regards\, Marcin T.
All these are weird around the locale setting. Could you run this with the environment variable PERL_DEBUG_LOCALE_INIT=1 and send the output.
==12872==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000033ff at pc 0x00000080b9cc bp 0x7ffe22920dd0 sp 0x7ffe22920dc8 READ of size 1 at 0x6020000033ff thread T0 #0 0x80b9cb in S_ckwarn_common /home/mtowalski/Fuzzing/Programs/perl-git/util.c:2027:6 #1 0x655ce6 in S_pending_ident /home/mtowalski/Fuzzing/Programs/perl-git/toke.c:8971:9 #2 0x655ce6 in Perl_yylex /home/mtowalski/Fuzzing/Programs/perl-git/toke.c:4811 #3 0x6e834d in Perl_yyparse /home/mtowalski/Fuzzing/Programs/perl-git/perly.c:340:34 #4 0x5e3dc6 in S_parse_body /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:2377:9 #5 0x5db300 in perl_parse /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:1692:2 #6 0x5242ce in main /home/mtowalski/Fuzzing/Programs/perl-git/perlmain.c:121:18 #7 0x7f368e7173f0 in __libc_start_main /build/glibc-jxM2Ev/glibc-2.24/csu/../csu/libc-start.c:291 #8 0x4356f9 in _start (/home/mtowalski/Fuzzing/Programs/perl-git/perl+0x4356f9)
0x6020000033ff is located 6 bytes to the right of 9-byte region [0x6020000033f0\,0x6020000033f9) allocated by thread T0 here: #0 0x4eb0a8 in malloc (/home/mtowalski/Fuzzing/Programs/perl-git/perl+0x4eb0a8) #1 0x5548ac in Perl_block_start /home/mtowalski/Fuzzing/Programs/perl-git/op.c:4106:33 #2 0x5e3dc6 in S_parse_body /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:2377:9 #3 0x5db300 in perl_parse /home/mtowalski/Fuzzing/Programs/perl-git/perl.c:1692:2 #4 0x5242ce in main /home/mtowalski/Fuzzing/Programs/perl-git/perlmain.c:121:18 #5 0x7f368e7173f0 in __libc_start_main /build/glibc-jxM2Ev/glibc-2.24/csu/../csu/libc-start.c:291
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/mtowalski/Fuzzing/Programs/perl-git/util.c:2027:6 in S_ckwarn_common Shadow bytes around the buggy address: 0x0c047fff8620: fa fa fd fa fa fa 00 02 fa fa fd fd fa fa fd fd 0x0c047fff8630: fa fa fd fd fa fa 00 03 fa fa fd fd fa fa 00 02 0x0c047fff8640: fa fa fd fd fa fa fd fa fa fa 00 00 fa fa fd fd 0x0c047fff8650: fa fa fd fd fa fa 00 02 fa fa fd fa fa fa fd fd 0x0c047fff8660: fa fa fd fd fa fa fd fd fa fa 00 02 fa fa fd fd =>0x0c047fff8670: fa fa 00 05 fa fa fd fd fa fa 00 02 fa fa 00[01] 0x0c047fff8680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff8690: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff86a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff86b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff86c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==12872==ABORTING
On Sat\, Mar 04\, 2017 at 05:03:32AM -0800\, via RT wrote:
BEGIN{$x=${;};${^WARNING_BITS}="x"}{$
This:
${^WARNING_BITS}="x"
sets\, in Perl_magic_set()\, PL_curcop->cop_warnings to point to a malloced U8 buffer of size 0x19\, containing: * an 8 byte length field (set to the value 1)\, * followed by the one byte 'x'\, * followed by 16 bytes of padding
Later\, Perl_block_start() does:
PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
but DUP_WARNINGS() only copies the actual length\, so the new buffer is malloced with size 0x9\, containing the length and just the 'x'\, with no padding.
Then later\, S_ckwarn_common() checks which warnings are enabled\, and assumes the buffer is big enough to index into to check for any enabled warning bit. This triggers the ASAN error.
I don't understand the warning bits code well enough (and especially the meaning of the length word\, and why its sometimes treated as a STRLEN*) to know whether:
a) Perl_magic_set should have set the length to 0x11 rather than 0x1; or b) DUP_WARNINGS should have allocated a larger buffer even though the length field has the value 0x1; or c) whether S_ckwarn_common() and other code which accesses the warnings array should honour the length field and not check for bits beyond the end of it.
Of the three\, (c) seems the least desirable as it could have the biggest runtime overhead.
In any event\, I don't think its a security issue\, because it will only occur if perl-level code deliberately sets ${^WARNING_BITS} to a short string\, which normal code is exceedingly unlikely to do\, and the read beyond the end of the buffer then only affects which warnings are interpreted as being enabled.
So I propose moving this to the public queue.
-- The Enterprise successfully ferries an alien VIP from one place to another without serious incident. -- Things That Never Happen in "Star Trek" #7
On Fri\, Mar 17\, 2017 at 04:12:23PM +0000\, Dave Mitchell wrote:
On Sat\, Mar 04\, 2017 at 05:03:32AM -0800\, via RT wrote:
BEGIN{$x=${;};${^WARNING_BITS}="x"}{$
This:
$\{^WARNING\_BITS\}="x"
sets\, in Perl_magic_set()\, PL_curcop->cop_warnings to point to a malloced U8 buffer of size 0x19\, containing: * an 8 byte length field (set to the value 1)\, * followed by the one byte 'x'\, * followed by 16 bytes of padding
Later\, Perl_block_start() does:
PL\_compiling\.cop\_warnings = DUP\_WARNINGS\(PL\_compiling\.cop\_warnings\);
but DUP_WARNINGS() only copies the actual length\, so the new buffer is malloced with size 0x9\, containing the length and just the 'x'\, with no padding.
Then later\, S_ckwarn_common() checks which warnings are enabled\, and assumes the buffer is big enough to index into to check for any enabled warning bit. This triggers the ASAN error.
I don't understand the warning bits code well enough (and especially the meaning of the length word\, and why its sometimes treated as a STRLEN*) to know whether:
a) Perl_magic_set should have set the length to 0x11 rather than 0x1; or b) DUP_WARNINGS should have allocated a larger buffer even though the length field has the value 0x1; or c) whether S_ckwarn_common() and other code which accesses the warnings array should honour the length field and not check for bits beyond the end of it.
Of the three\, (c) seems the least desirable as it could have the biggest runtime overhead.
In any event\, I don't think its a security issue\, because it will only occur if perl-level code deliberately sets ${^WARNING_BITS} to a short string\, which normal code is exceedingly unlikely to do\, and the read beyond the end of the buffer then only affects which warnings are interpreted as being enabled.
So I propose moving this to the public queue.
Which I've now done.
-- print+qq&$}$"$/$s$\,$a$d$g$s$@$.$q$\,$:$.$q$^$\,$@$a$~$;$.$q$m&if+map{m\,^\d{0\\,}\,\,${$::{$'}}=chr($"+=$&||1)}q&10m22\,42}6:17a2~2.3@3;^2dg3q/s"&=~m*\d\*.*g
Migrated from rt.perl.org#130916 (status was 'open')
Searchable as RT130916$