summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-03-07 14:12:08 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-03-07 14:12:51 -0800
commit5af88345d9b73adc26765854070a07f429ae112d (patch)
tree58f85af858fe3c6d1507055e26d175f43b0aed90
parenteef6290d07de3f52b42c2570878665af9511bcf8 (diff)
downloadperl-5af88345d9b73adc26765854070a07f429ae112d.tar.gz
Stop warning hint-checking from doing bad reads
Setting ${^WARNING_BITS} should not allow perl to read past the end of a mallocked buffer. Previously the internal warning buffer would be copied straight from ${^WARNING_BITS}, so a short value assigned to that variable would cause the internal warning-checking code to read past the end of the buffer (probably not in actual practice, due to malloc’s rounding up, but theoretically). Now, the buffer that is allocated for storing the warning bits is padded with nulls to make it long enough to prevent bad reads. The stored length is still the same as what was assigned to ${^WARNING_BITS}, so that the value that comes out of it is the same length (UTF8-ness aside)--not that it makes much difference in prac- tice though, since only warnings.pm should care about this. This came up as part of perl #111500.
-rw-r--r--util.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/util.c b/util.c
index 1ff591353c..e6b5fa582e 100644
--- a/util.c
+++ b/util.c
@@ -2002,7 +2002,8 @@ S_ckwarn_common(pTHX_ U32 w)
STRLEN *
Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits,
STRLEN size) {
- const MEM_SIZE len_wanted = sizeof(STRLEN) + size;
+ const MEM_SIZE len_wanted =
+ sizeof(STRLEN) + (size > WARNsize ? size : WARNsize);
PERL_UNUSED_CONTEXT;
PERL_ARGS_ASSERT_NEW_WARNINGS_BITFIELD;
@@ -2012,6 +2013,8 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits,
PerlMemShared_realloc(buffer, len_wanted));
buffer[0] = size;
Copy(bits, (buffer + 1), size, char);
+ if (size < WARNsize)
+ Zero((char *)(buffer + 1) + size, WARNsize - size, char);
return buffer;
}