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-buffer-overflow in Perl_sv_vcatpvfn_flags #16087
Comments
From gy741.kim@gmail.comHi. I found a heap-buffer-overflow bug in perl. Please confirm. Version: This is perl 5, version 27, subversion 2 (v5.27.2) built for
|
From @iabynOn Mon, Jul 24, 2017 at 09:23:22PM -0700, GwanYeong Kim wrote:
I've had a quick look, and it's a lexer issue rather than a problem yylex is doing this: Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after %" UTF8f "<-- HERE near column %d", c, where d and s are supposed to delineate part of the src code, but Since it probably requires feeding attacker-controlled src code into the I *hate* the lexer. If anyone else wants to fix this, feel free. -- |
The RT System itself - Status changed from 'new' to 'open' |
From @tonycozOn Tue, 25 Jul 2017 03:44:14 -0700, davem wrote:
d gets that value because PL_linestart is after s (aka PL_bufptr at this point), which happens due to a failed attempt to parse a
Agreed, this ticket is now public.
The attached fixes the symptom, I don't know if scan_ident() should be working harder to avoid advancing PL_linestart when it fails to parse an identifier. Tony |
From @tonycoz0001-perl-131793-sanely-handle-PL_linestart-PL_bufptr.patchFrom 77a3e1e5a81d1492a86bac337a93a1247994837d Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 26 Jul 2017 12:04:18 +1000
Subject: (perl #131793) sanely handle PL_linestart > PL_bufptr
In the test case, scan_ident() ends up fetching another line
(updating PL_linestart), and since in this case we don't
successfully parse ${identifier} s (and PL_bufptr) end up being
before PL_linestart.
---
t/comp/parser_run.t | 9 ++++++++-
toke.c | 19 +++++++++++++++----
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/t/comp/parser_run.t b/t/comp/parser_run.t
index e74644d..0fca5b2 100644
--- a/t/comp/parser_run.t
+++ b/t/comp/parser_run.t
@@ -10,7 +10,7 @@ BEGIN {
}
require './test.pl';
-plan(1);
+plan(2);
# [perl #130814] can reallocate lineptr while looking ahead for
# "Missing $ on loop variable" diagnostic.
@@ -24,5 +24,12 @@ syntax error at - line 3, near "foreach m0
Identifier too long at - line 3.
EXPECT
+fresh_perl_is(<<EOS, <<'EXPECT', {}, "linestart before bufptr");
+\${ \xD5eeeeeeeeeeee
+'x
+EOS
+Unrecognized character \xD5; marked by <-- HERE after ${ <-- HERE near column 4 at - line 1.
+EXPECT
+
__END__
# ex: set ts=8 sts=4 sw=4 et:
diff --git a/toke.c b/toke.c
index 6aa5f26..1b203cd 100644
--- a/toke.c
+++ b/toke.c
@@ -5158,12 +5158,23 @@ Perl_yylex(pTHX)
else {
c = Perl_form(aTHX_ "\\x%02X", (unsigned char)*s);
}
- len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : (STRLEN) (s - PL_linestart);
- if (len > UNRECOGNIZED_PRECEDE_COUNT) {
- d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - UNRECOGNIZED_PRECEDE_COUNT;
- } else {
+
+ if (s >= PL_linestart) {
d = PL_linestart;
}
+ else {
+ /* somehow (probably due to a parse failure), PL_linestart has advanced
+ * pass PL_bufptr, get a reasonable beginning of line
+ */
+ d = s;
+ while (d > SvPVX(PL_linestr) && d[-1] && d[-1] != '\n')
+ --d;
+ }
+ len = UTF ? Perl_utf8_length(aTHX_ (U8 *) d, (U8 *) s) : (STRLEN) (s - d);
+ if (len > UNRECOGNIZED_PRECEDE_COUNT) {
+ d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)d) : s - UNRECOGNIZED_PRECEDE_COUNT;
+ }
+
Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after %" UTF8f "<-- HERE near column %d", c,
UTF8fARG(UTF, (s - d), d),
(int) len + 1);
--
2.1.4
|
From quangnh89@gmail.comThe attached script triggers a heap-buffer-overflow Perl_sv_vcatpvfn ================================================================= 0x602000000fa8 is located 8 bytes to the left of 10-byte region SUMMARY: AddressSanitizer: heap-buffer-overflow toke.c:5161:9: len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : if `UTF` is equal to false, the `len` will be `(STRLEN) (s - *Best regards,* *Nguyễn Hồng Quang* |
From quangnh89@gmail.com |
From @tonycozOn Tue, 15 Aug 2017 19:44:10 -0700, quangnh89@gmail.com wrote:
This is a duplicate of #131793 and is fixed by my patch there. As with #131793 this isn't a security issue and is now public. Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @tonycozOn Wed, 16 Aug 2017 17:58:23 -0700, tonyc wrote:
Which I've now applied to blead as 36000cd. Tony |
From perl@profvince.com
This has probably been fixed by commit 36000cd, which was included in Vincent |
From @tonycozOn Tue, 22 Aug 2017 05:42:52 -0700, perl@profvince.com wrote:
Yes, I forgot to close it. Tony |
@tonycoz - Status changed from 'open' to 'pending release' |
From @khwilliamsonThank you for filing this report. You have helped make Perl better. With the release yesterday of Perl 5.28.0, this and 185 other issues have been Perl 5.28.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#131793 (status was 'resolved')
Searchable as RT131793$
The text was updated successfully, but these errors were encountered: