This is a live mirror of the Perl 5 development currently hosted at
Stop warning hint-checking from doing bad reads
authorFather Chrysostomos <>
Wed, 7 Mar 2012 22:12:08 +0000 (14:12 -0800)
committerFather Chrysostomos <>
Wed, 7 Mar 2012 22:12:51 +0000 (14:12 -0800)
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 should care about this.

This came up as part of perl #111500.


diff --git a/util.c b/util.c
index 1ff5913..e6b5fa5 100644 (file)
--- a/util.c
+++ b/util.c
@@ -2002,7 +2002,8 @@ S_ckwarn_common(pTHX_ U32 w)
 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);
@@ -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;