Skip to content

Commit 0b3da58

Browse files
tonycozH.Merijn Brand
authored and
H.Merijn Brand
committed
-Dmad: double free or corruption
> If your perl has -Dmad, the following program crashes: > > $ bleadperl -we '$x="x" x 257; eval "for $x"' > *** glibc detected *** bleadperl: double free or corruption (!prev): 0x0000000001dca670 *** Change 6136c70 changed S_scan_ident from: e = d + destlen - 3; to: register char * const e = d + destlen + 3; where e is used to mark the end of the buffer, this meant that the various buffer end checks allowed the various buffers supplied S_scan_ident to overflow. Attached is a fix, various tests with fencepost checks on different identifier lengths, and the specific case mentioned in the ticket. Tony Signed-off-by: H.Merijn Brand <[email protected]>
1 parent 2352781 commit 0b3da58

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

t/comp/parser.t

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Checks if the parser behaves correctly in edge cases
44
# (including weird syntax errors)
55

6-
print "1..104\n";
6+
print "1..117\n";
77

88
sub failed {
99
my ($got, $expected, $name) = @_;
@@ -285,6 +285,54 @@ like($@, qr/BEGIN failed--compilation aborted/, 'BEGIN 6' );
285285
eval q[ BEGIN {\&foo4; die } ] for 1..10;
286286
like($@, qr/BEGIN failed--compilation aborted/, 'BEGIN 7' );
287287

288+
{
289+
# RT #70934
290+
# check both the specific case in the ticket, and a few other paths into
291+
# S_scan_ident()
292+
# simplify long ids
293+
my $x100 = "x" x 256;
294+
my $xFE = "x" x 254;
295+
my $xFD = "x" x 253;
296+
my $xFC = "x" x 252;
297+
my $xFB = "x" x 251;
298+
299+
eval qq[ \$#$xFB ];
300+
is($@, "", "251 character \$# sigil ident ok");
301+
eval qq[ \$#$xFC ];
302+
like($@, qr/Identifier too long/, "too long id in \$# sigil ctx");
303+
304+
eval qq[ \$$xFB ];
305+
is($@, "", "251 character \$ sigil ident ok");
306+
eval qq[ \$$xFC ];
307+
like($@, qr/Identifier too long/, "too long id in \$ sigil ctx");
308+
309+
eval qq[ %$xFB ];
310+
is($@, "", "251 character % sigil ident ok");
311+
eval qq[ %$xFC ];
312+
like($@, qr/Identifier too long/, "too long id in % sigil ctx");
313+
314+
eval qq[ \\&$xFC ]; # take a ref since I don't want to call it
315+
is($@, "", "252 character & sigil ident ok");
316+
eval qq[ \\&$xFD ];
317+
like($@, qr/Identifier too long/, "too long id in & sigil ctx");
318+
319+
eval qq[ *$xFC ];
320+
is($@, "", "252 character glob ident ok");
321+
eval qq[ *$xFD ];
322+
like($@, qr/Identifier too long/, "too long id in glob ctx");
323+
324+
eval qq[ for $xFD ];
325+
like($@, qr/Missing \$ on loop variable/,
326+
"253 char id ok, but a different error");
327+
eval qq[ for $xFE; ];
328+
like($@, qr/Identifier too long/, "too long id in for ctx");
329+
330+
# the specific case from the ticket
331+
my $x = "x" x 257;
332+
eval qq[ for $x ];
333+
like($@, qr/Identifier too long/, "too long id ticket case");
334+
}
335+
288336
# Add new tests HERE:
289337

290338
# More awkward tests for #line. Keep these at the end, as they will screw

toke.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11366,7 +11366,7 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL
1136611366
char *bracket = NULL;
1136711367
char funny = *s++;
1136811368
register char *d = dest;
11369-
register char * const e = d + destlen + 3; /* two-character token, ending NUL */
11369+
register char * const e = d + destlen - 3; /* two-character token, ending NUL */
1137011370

1137111371
PERL_ARGS_ASSERT_SCAN_IDENT;
1137211372

0 commit comments

Comments
 (0)