Description
Description
#define PERL_REPEATCPY_LINEAR 4
void
Perl_repeatcpy(char *to, const char *from, SSize_t len, IV count)
{
PERL_ARGS_ASSERT_REPEATCPY;
assert(len >= 0);
if (count < 0)
croak_memory_wrap();
if (len == 1)
memset(to, *from, count);
else if (count) {
Most related commits that I found:
26e1303 don't segfault given string repeat count larger than 2^31
2709980 avoid calling memset with a negative count
https://nvd.nist.gov/vuln/detail/CVE-2012-5195
Steps to Reproduce
Perl_repeatcpy() arg 4 bug is not reachable from PP from my limited test, through 1 of 2 libperl funcs that use Perl_repeatcpy(). I didn't try func 2. Fact check and verify this yourself, but all callers, 2 func, 3 call sites total, are doing their own bounds checking, which makes the bound checking attempts in Perl_repeatcpy()
pointless or inappropriate API design or inappropriate delegation and abstraction of responsibilities.
5.41.7 Win64
C:\sources\perl5>perl -E" sub mks { return 'a' x 0xFFFFFFFFFFFFFFFF} print(mks()
);" > t3.txt
Out of memory in perl:util:safesysrealloc
panic: fold_constants JMPENV_PUSH returned 2 at -e line 1.
Free to wrong pool 4303b8 not 4275c0 at (null) line 1 during global destruction.
strawberry `uname='Win32 strawberry-perl 5.32.1.1 #1 Sun Jan 24 12:17:47 2021 i386'
C:\sources>perl -E" sub mks { return 'a' x 0x80000000} print(mks());" > t3.txt
Out of memory!
panic: fold_constants JMPENV_PUSH returned 2 at -e line 1.
Free to wrong pool 6cc780 not 6cc7b0 at (null) line 1 during global destruction.
got SEGV popup on windows ^^^
C:\sources>perl -E" sub mks { return 'abcdefgh' x 0x80000000} print(mks());" > t
3.txt
Out of memory during string extend at -e line 1.
C:\sources>perl -E" sub mks { return 'abcdefgh' x 0x8000000} print(mks());" > t3
.txt
Out of memory!
C:\sources>perl -E" sub mks { return @{$_[0]} x 0x100000000;} foreach(mks(['a'])
) {print $_};" > t3.txt
Out of memory during string extend at -e line 1.
C:\sources>perl -E" sub mks { return (@{$_[0]}) x 0x100000000;} foreach(mks(['a'
])) {print $_};" > t3.txt
Out of memory during list extend at -e line 1.
Expected behavior
Use Size_t
type for arg 4 on all builds configs, the way it should've been written from day 1.
I don't have any opinion or proposal on how to correctly fix arg 4. Many questions:
but statement if (i64_count < 0) croak_memory_wrap();
is useless on a 32b CPU.
Which call frame/context does the 64b IV -> 32b size_t cast or truncate and bounds check logic? 64b IVs/int64_t
on 32b CPUs is always emulated by the C compiler using multiple instructions 4 byte/32bit CPU ops.
Make a PvREPEATCPY()
macro to do the bounds check and truncate in the caller?
Perl_repeatcpy is marked as public API, now what? What is the policy on breaking DarkPAN?
NOTE: 2 callers in libperl
, 0 hits on grepcpan. Someone else should repeat my search attempts.
Deprecate, mathom, "no warning" delete the function by renaming to Perl_repeatcpy2
or Perl_repeatcpyn
, etc?
Keep overflow hazard broken version as a libperl export under current name, Perl_repeatcpy
and make a non exported Perl_repeatcpy_p
for PERL_CORE?
I was happy to find Perl_repeatcpy
exists in libperl's toolkit and had a thought of maybe using it myself in a future perl FOSS patch, vs DIYing it the traditional way with for(;;i++) {size_t[i] = size_t[i];}
, but that plan changed after reading Perl_repeatcpy
's src code.
Perl configuration
Summary of my perl5 (revision 5 version 41 subversion 12) configuration:
Derived from: ec918d82932a068cc3f73beb4658a99acc1556e0
Platform:
osname=MSWin32
osvers=6.1.7601
archname=MSWin32-x64-multi-thread
uname=''
config_args='undef'
hint=recommended
useposix=true
d_sigaction=undef
useithreads=define
usemultiplicity=define
use64bitint=define
use64bitall=undef
uselongdouble=undef
usemymalloc=n
default_inc_excludes_dot=define
Compiler:
cc='cl'
ccflags ='-nologo -GF -W3 -MD -DWIN32 -D_CONSOLE -DNO_STRICT -DWIN64 -D_CRT_
SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WINSOCK_DEPRECATED_NO_WARNING
S -DPERL_TEXTMODE_SCRIPTS -DMULTIPLICITY -DPERL_IMPLICIT_SYS -DUSE_PERLIO'
optimize='-O1 -Zi -GL -fp:precise'
cppflags='-DWIN32'
ccversion='19.36.32535'
gccversion=''
gccosandvers=''
intsize=4
longsize=4
ptrsize=8
doublesize=8
byteorder=12345678
doublekind=3
d_longlong=undef
longlongsize=8
d_longdbl=define
longdblsize=8
longdblkind=0
ivtype='__int64'
ivsize=8
nvtype='double'
nvsize=8
Off_t='__int64'
lseeksize=8
alignbytes=8
prototype=define
Linker and Libraries:
ld='link'
ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:\perl\
lib\CORE" -machine:AMD64 -subsystem:console,"5.02"'
libpth="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSV
C\14.36.32532\\lib\x64"
libs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.li
b advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_32.l
ib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
vcruntime.lib ucrt.lib
perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg3
2.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib ws2_
32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt
.lib vcruntime.lib ucrt.lib
libc=ucrt.lib
so=dll
useshrplib=true
libperl=perl541.lib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_win32.xs
dlext=dll
d_dlsymun=undef
ccdlflags=' '
cccdlflags=' '
lddlflags='-dll -nologo -nodefaultlib -debug -opt:ref,icf -ltcg -libpath:"c:
\perl\lib\CORE" -machine:AMD64 -subsystem:console,"5.02"'
Characteristics of this binary (from libperl):
Compile-time options:
HAS_LONG_DOUBLE
HAS_TIMES
HAVE_INTERP_INTERN
MULTIPLICITY
PERLIO_LAYERS
PERL_COPY_ON_WRITE
PERL_DONT_CREATE_GVSV
PERL_HASH_FUNC_SIPHASH13
PERL_HASH_USE_SBOX32
PERL_IMPLICIT_SYS
PERL_MALLOC_WRAP
PERL_OP_PARENT
PERL_PRESERVE_IVUV
PERL_USE_SAFE_PUTENV
USE_64_BIT_INT
USE_ITHREADS
USE_LARGE_FILES
USE_LOCALE
USE_LOCALE_COLLATE
USE_LOCALE_CTYPE
USE_LOCALE_NUMERIC
USE_LOCALE_TIME
USE_PERLIO
USE_PERL_ATOF
USE_THREAD_SAFE_LOCALE
Locally applied patches:
uncommitted-changes
Built under MSWin32
Compiled at May 2 2025 12:21:18
%ENV:
PERL_JSON_BACKEND="Cpanel::JSON::XS"
PERL_YAML_BACKEND="YAML::XS"
@INC:
C:/sources/perl5/lib