Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Perl_repeatcpy() arg 4 "IV count" has overflow on 32b CPUs #23243

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

Open
bulk88 opened this issue May 2, 2025 · 0 comments
Open

Perl_repeatcpy() arg 4 "IV count" has overflow on 32b CPUs #23243

bulk88 opened this issue May 2, 2025 · 0 comments

Comments

@bulk88
Copy link
Contributor

bulk88 commented May 2, 2025

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant