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.
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;
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;
}