-
Notifications
You must be signed in to change notification settings - Fork 560
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 ptr deref -> Perl_ck_shift (op.c:10857) #14739
Comments
From @geeknikThe attached "script" causes a null ptr deref and seg fault in Perl v5.23.0 (v5.22.0-63-g216b41c): Program received signal SIGSEGV, Segmentation fault. ==51781== Invalid read of size 8 It also causes a null ptr deref and seg fault in Perl v5.21.7 (v5.21.6-602-ge9d2bd8), albeit in a different location and file: Program received signal SIGSEGV, Segmentation fault. ==12210== Invalid read of size 8 This bug was found with AFL (http://lcamtuf.coredump.cx/afl/). |
From @geeknik |
From @tonycozOn Sun Jun 07 12:36:52 2015, brian.carpenter@gmail.com wrote:
This looks like it has the same base cause as 124187. Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @geeknikFYI, this issue is still present in v5.23.1-213-g4b06b8d. On Tue Jun 09 22:52:01 2015, tonyc wrote:
|
From @geeknikperl -e 'qq{@{sub{]]}}}}-shift' triggers a null ptr deref and segfault in perl v5.21.7 (v5.21.6-602-ge9d2bd8). S_pad_findlex (namepv=namepv@entry=0x7fffffffdb30 "&shift", namelen=namelen@entry=6, ==46065== Invalid read of size 8 This same script also triggers a completely different null ptr deref and segfault in perl v5.23.4 (v5.23.3-7-ge120c24): 0x00000000004a07c7 in Perl_ck_shift () at op.c:10710 ==24849== Invalid read of size 8 |
From @geeknikThis issue is still present in v5.23.7 (v5.23.6-109-g388b516). |
From [Unknown Contact. See original ticket]This issue is still present in v5.23.7 (v5.23.6-109-g388b516). |
From @geeknikFrom v5.25.4 (v5.25.3-305-g8c6b0c7): ./perl -e 'qq{@{sub{q}}]]}};s0{shift' ASAN:SIGSEGV==31752==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055ff13 bp 0x7ffda0f99310 sp 0x7ffda0f99110 T0) AddressSanitizer can not provide additional info. |
From [Unknown Contact. See original ticket]From v5.25.4 (v5.25.3-305-g8c6b0c7): ./perl -e 'qq{@{sub{q}}]]}};s0{shift' ASAN:SIGSEGV==31752==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055ff13 bp 0x7ffda0f99310 sp 0x7ffda0f99110 T0) AddressSanitizer can not provide additional info. |
From @geeknikOn Fri Sep 25 19:47:03 2015, brian.carpenter@gmail.com wrote:
v5.25.5 (v5.25.4-110-g95c0a76) ==9144==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055fdf3 bp 0x7ffcd79efc10 sp 0x7ffcd79efa30 T0) AddressSanitizer can not provide additional info. |
From [Unknown Contact. See original ticket]On Fri Sep 25 19:47:03 2015, brian.carpenter@gmail.com wrote:
v5.25.5 (v5.25.4-110-g95c0a76) ==9144==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000055fdf3 bp 0x7ffcd79efc10 sp 0x7ffcd79efa30 T0) AddressSanitizer can not provide additional info. |
From @geeknikperl -e 'qq{@{sub{]]}}}}*shift' triggers this crash in v5.25.6 (v5.25.5-104-gaff2be5). |
From @hvdsThe original case is still crashing as before: It seems clear that as mooted this is essentially the same underlying issue as [perl #124187], but that one has been resolved so they should not be merged. I'll copy Dave's commit message from there, since it will be more useful here for the future (particularly the bit about PL_compcv): commit de0885d null ptr deref in Perl_cv_forget_slab |
From @hvdsThis looks to be the same as [perl #125351], I'll merge them. Hugo |
The RT System itself - Status changed from 'new' to 'open' |
From zefram@fysh.orgLooks to be the same mechanism as [perl #126191]. -zefram |
From sraums2498@gmail.com================================================================= 0x60300000e8e0 is located 0 bytes to the right of 32-byte region [0x60300000e8c0,0x60300000e8e0) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/asan_perl/Documents/perl-5.26.1/pad.c:397 Perl_cv_undef_flags -- |
From sraums2498@gmail.com |
From @hvdsThis appears similar to rt131836, but is not fixed by its fix. It reduces at least to: I'll come back to this after completing triage on the current batch of new tickets if nobody else gets to it, but I anticipate it'll need more knowledge of the lex/parse phase than I can bring to bear. Hugo |
The RT System itself - Status changed from 'new' to 'open' |
From @tonycozOn Mon, 08 Jan 2018 16:41:35 -0800, hv wrote:
This looks like another case of #125351 and other similar sublex recovery issues. Tony |
From @tonycozOn Wed, 17 Jan 2018 16:24:03 -0800, tonyc wrote:
And so it is. Since it requires feedng code to the interpreter it isn't a security issue, so it's now public. Since it duplicates #125351 I'm merging it into that ticket. Tony |
From @tonycozOn Mon, 29 Jan 2018 21:29:37 -0800, tonyc wrote:
And here is hopefully a patch for this long-standing issue. Tony |
From @tonycoz0001-perl-125351-abort-parsing-if-parse-errors-happen-in-.patchFrom abf27f937c988e96bf65c6be92ac4edc188e31c3 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 30 Jan 2018 16:40:53 +1100
Subject: (perl #125351) abort parsing if parse errors happen in a sub lex
We've had a few reports of segmentation faults and other misbehaviour
when sub-parsing, such as within interpolated expressions, fails.
This change aborts compilation if anything complex enough to not be
parsed by the lexer is compiled in a sub-parse *and* an error
occurs within the sub-parse.
An earlier version of this patch failed on simpler expressions,
which caused many test failures, which this version doesn't (which may
just mean we need more tests...)
---
parser.h | 2 ++
t/base/lex.t | 11 ++++++++++-
toke.c | 18 ++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/parser.h b/parser.h
index 4187e0a93d..216e9deca8 100644
--- a/parser.h
+++ b/parser.h
@@ -58,6 +58,7 @@ typedef struct yy_parser {
1 = @{...} 2 = ->@ */
U8 expect; /* how to interpret ambiguous tokens */
bool preambled;
+ bool sub_no_recover; /* can't recover from a sublex error */
I32 lex_formbrack; /* bracket count at outer format level */
OP *lex_inpat; /* in pattern $) and $| are special */
OP *lex_op; /* extra info to pass back on op */
@@ -95,6 +96,7 @@ typedef struct yy_parser {
U16 in_my; /* we're compiling a "my"/"our" declaration */
U8 lex_state; /* next token is determined */
U8 error_count; /* how many compile errors so far, max 10 */
+ U8 sub_error_count; /* the number of errors before sublexing */
HV *in_my_stash; /* declared class of this "my" declaration */
PerlIO *rsfp; /* current source file pointer */
AV *rsfp_filters; /* holds chain of active source filters */
diff --git a/t/base/lex.t b/t/base/lex.t
index de33e7a688..414aa1fceb 100644
--- a/t/base/lex.t
+++ b/t/base/lex.t
@@ -1,6 +1,6 @@
#!./perl
-print "1..117\n";
+print "1..120\n";
$x = 'x';
@@ -557,6 +557,15 @@ eval q|s##[}#e|;
eval ('/@0{0*->@*/*]');
print "ok $test - 128171\n"; $test++;
}
+{
+ # various sub-parse recovery issues that crashed perl
+ eval 's//${sub{b{]]]{}#$/ sub{}';
+ print "ok $test - 132640\n"; $test++;
+ eval 'qq{@{sub{]]}}}};shift';
+ print "ok $test - 125351\n"; $test++;
+ eval 'qq{@{sub{]]}}}}-shift';
+ print "ok $test - 126192\n"; $test++;
+}
$foo = "WRONG"; $foo:: = "bar"; $bar = "baz";
print "not " unless "$foo::$bar" eq "barbaz";
diff --git a/toke.c b/toke.c
index 5959bc3e9e..3dcc7e9f86 100644
--- a/toke.c
+++ b/toke.c
@@ -2390,6 +2390,8 @@ S_sublex_start(pTHX)
PL_parser->lex_super_state = PL_lex_state;
PL_parser->lex_sub_inwhat = (U16)op_type;
PL_parser->lex_sub_op = PL_lex_op;
+ PL_parser->sub_no_recover = FALSE;
+ PL_parser->sub_error_count = PL_error_count;
PL_lex_state = LEX_INTERPPUSH;
PL_expect = XTERM;
@@ -2569,6 +2571,20 @@ S_sublex_done(pTHX)
else {
const line_t l = CopLINE(PL_curcop);
LEAVE;
+ if (PL_parser->sub_error_count != PL_error_count) {
+ const char * const name = OutCopFILE(PL_curcop);
+ if (PL_parser->sub_no_recover) {
+ const char * msg = "";
+ if (PL_in_eval) {
+ SV *errsv = ERRSV;
+ if (SvCUR(ERRSV)) {
+ msg = Perl_form(aTHX_ "%" SVf, SVfARG(errsv));
+ }
+ }
+ abort_execution(msg, name);
+ NOT_REACHED;
+ }
+ }
if (PL_multi_close == '<')
PL_parser->herelines += l - PL_multi_end;
PL_bufend = SvPVX(PL_linestr);
@@ -4157,6 +4173,7 @@ S_intuit_more(pTHX_ char *s, char *e)
return TRUE;
if (*s != '{' && *s != '[')
return FALSE;
+ PL_parser->sub_no_recover = TRUE;
if (!PL_lex_inpat)
return TRUE;
@@ -9580,6 +9597,7 @@ S_scan_ident(pTHX_ char *s, char *dest, STRLEN destlen, I32 ck_uni)
CopLINE_set(PL_curcop, orig_copline);
PL_parser->herelines = herelines;
*dest = '\0';
+ PL_parser->sub_no_recover = TRUE;
}
}
else if ( PL_lex_state == LEX_INTERPNORMAL
--
2.11.0
|
@tonycoz - Status changed from 'open' to 'pending release' |
From sraums2498@gmail.comHi,
On Tue, Feb 27, 2018 at 6:09 AM, Tony Cook via RT <perlbug-followup@perl.org
-- |
From @iabynOn Tue, Mar 27, 2018 at 12:38:50PM +0530, SRAUMS JN wrote:
The perl interpreter has two main sources of input: code and data. The data is highly likely to be under the control of an attacker. If a bug in perl requires the attacker to supply specially-crafted source system "rm -rf /" or similar to the interpreter. -- |
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#125351 (status was 'resolved')
Searchable as RT125351$
The text was updated successfully, but these errors were encountered: