Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PickleBINSTRING incorrect data type for size #135321

Closed
Labels
stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error
@Legoclones

Description

@Legoclones

Bug report

Bug description:

TheBINSTRING opcode in Pickle has two arguments: a "4-byte little-endian signed int" length, and a string of that many bytes (see thecode comment forBINSTRING inpickletools). Since it is signed, this means that any provided value over0x7fffffff would be interpreted as a negative number. The Python pickle implementation specifically treats it as a signed 32-bit length and checks to see if the length is < 0:

cpython/Lib/pickle.py

Lines 1454 to 1458 in754e7c9

defload_binstring(self):
# Deprecated BINSTRING uses signed 32-bit length
len,=unpack('<i',self.read(4))
iflen<0:
raiseUnpicklingError("BINSTRING pickle has negative byte count")

However, the C pickle implementation runscalc_binsize(s, 4) forBINSTRING and returns aPy_ssize_t. SincePy_ssize_t data types are the same size as the compiler'ssize_t type (PEP0353), this means aPy_ssize_t is 64-bits long on 64-bit systems. Since thesize variable here is also aPy_ssize_t, that means the threshold for negative values is much higher.

cpython/Modules/_pickle.c

Lines 5546 to 5558 ina58026a

Py_ssize_tsize;
char*s;
if (_Unpickler_Read(self,st,&s,nbytes)<0)
return-1;
size=calc_binsize(s,nbytes);
if (size<0) {
PyErr_Format(st->UnpicklingError,
"BINSTRING exceeds system's maximum size of %zd bytes",
PY_SSIZE_T_MAX);
return-1;
}

This is all just the background to illustrate that becausesize is not anint, a pickle with theBINSTRING opcode using a length > 0x7fffffff will fail in the Python implementation (since it's negative), but deserialize just fine in the C implementation.

The following payload will demonstrate the difference:

payload:      b'T\x00\x00\x00\x80'+b'a'*0x80000000 + b'.'pickle:       FAILURE BINSTRING pickle has negative byte count_pickle.c:    aaaaaaaaaaaaaaaaaaa....pickletools:  pickletools failed string4 byte count < 0: -2147483648

The required payload does need to be 2GB in size which is very large, but not impossible on modern systems.

Note that theLONG4 opcode is in a similar situation, except the output forcalc_binint() is anint data type so this issue does not exist there.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp