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
[PATCH v5.12.4-1-gea42574] large repeat count causes heap corruption #11495
Comments
From jim@meyering.netI first noticed this using Fedora 15's perl-5.12.4-159.fc15.x86_64, Using a large string repeat count makes perl overrun a heap buffer: $ ./perl -le 'print "v"x(2**31+1)' If you use an approx. doubled count (s/31/32), you can make Perl $ ./perl -le 'print "v"x(2**32+1)' > out Why? Because the caller of Perl_repeatcpy uses a type of IV util.c:3037: memset(to, *from, count); sign-extends to SIZE_MAX, and no one has that much memory, As for fixing it, I've included a patch that works for me, but it's -- >8 -- E.g., this overflows INT_MAX and overruns heap memory: $ perl -le 'print "v"x(2**31+1)' (Perl_repeatcpy): Use the same type for "count" as our sole Inline Patchdiff --git a/proto.h b/proto.h
index 3306ab0..e402ac2 100644
--- a/proto.h
+++ b/proto.h
@@ -2801,7 +2801,7 @@ PERL_CALLCONV void Perl_regprop(pTHX_ const regexp *prog, SV* sv, const regnode*
#define PERL_ARGS_ASSERT_REGPROP \
assert(sv); assert(o)
-PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, I32 count)
+PERL_CALLCONV void Perl_repeatcpy(char* to, const char* from, I32 len, IV count)
__attribute__nonnull__(1)
__attribute__nonnull__(2);
#define PERL_ARGS_ASSERT_REPEATCPY \
diff --git a/util.c b/util.c
index 89fea23..1518a95 100644
--- a/util.c
+++ b/util.c
@@ -3029,7 +3029,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
#define PERL_REPEATCPY_LINEAR 4
void
-Perl_repeatcpy(register char *to, register const char *from, I32 len, register I32 count)
+Perl_repeatcpy(register char *to, register const char *from, I32 len, register IV count)
{
PERL_ARGS_ASSERT_REPEATCPY;
@@ -3037,19 +3037,19 @@ Perl_repeatcpy(register char *to, register const char *from, I32 len, register I
memset(to, *from, count);
else if (count) {
register char *p = to;
- I32 items, linear, half;
+ IV items, linear, half;
linear = count < PERL_REPEATCPY_LINEAR ? count : PERL_REPEATCPY_LINEAR;
for (items = 0; items < linear; ++items) {
register const char *q = from;
- I32 todo;
+ IV todo;
for (todo = len; todo > 0; todo--)
*p++ = *q++;
}
half = count / 2;
while (items <= half) {
- I32 size = items * len;
+ IV size = items * len;
memcpy(p, to, size);
p += size;
items *= 2;
--
1.7.6.430.g34be2 Perl Info
|
From @cpansproutOn Mon Jul 11 11:47:03 2011, meyering wrote:
See also <https://rt-archive.perl.org/perl5/Ticket/Display.html?id=72784>.
Why IV and not UV? Should we perhaps introduce a new function with a |
The RT System itself - Status changed from 'new' to 'open' |
From jim@meyering.netOn Sun Sep 18 13:31:24 2011, sprout wrote:
An unsigned type is better, but would have made the patch more invasive. If you create a new function, there should be no need for a |
From @cpansproutOn Mon Jul 11 11:47:03 2011, meyering wrote:
I’m no C expert, but if IV is bigger than I32, then isn’t it OK to In other words: Can other perl porters tell me whether this patch can be |
From perl@profvince.com
I believe it could cause some conversion warnings when extra flags are
This is easy : no, it can't. The prototype of Perl_repeatcpy should be Vincent. |
From @cpansproutOn Mon Jul 11 11:47:03 2011, meyering wrote:
Thank you. Applied as 26e1303. |
@cpansprout - Status changed from 'open' to 'resolved' |
Migrated from rt.perl.org#94560 (status was 'resolved')
Searchable as RT94560$
The text was updated successfully, but these errors were encountered: