mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
bpo-45691: Make array of small ints static to fix use-after-free error. (GH-29366)
This commit is contained in:
parent
5a14929a6e
commit
acc89db923
4 changed files with 31 additions and 45 deletions
|
@ -247,14 +247,6 @@ struct type_cache {
|
|||
|
||||
/* interpreter state */
|
||||
|
||||
#define _PY_NSMALLPOSINTS 257
|
||||
#define _PY_NSMALLNEGINTS 5
|
||||
|
||||
// _PyLong_GetZero() and _PyLong_GetOne() must always be available
|
||||
#if _PY_NSMALLPOSINTS < 2
|
||||
# error "_PY_NSMALLPOSINTS must be greater than 1"
|
||||
#endif
|
||||
|
||||
// The PyInterpreterState typedef is in Include/pystate.h.
|
||||
struct _is {
|
||||
|
||||
|
@ -330,12 +322,6 @@ struct _is {
|
|||
|
||||
PyObject *audit_hooks;
|
||||
|
||||
/* Small integers are preallocated in this array so that they
|
||||
can be shared.
|
||||
The integers that are preallocated are those in the range
|
||||
-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
|
||||
*/
|
||||
PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
|
||||
struct _Py_bytes_state bytes;
|
||||
struct _Py_unicode_state unicode;
|
||||
struct _Py_float_state float_state;
|
||||
|
|
|
@ -11,28 +11,15 @@ extern "C" {
|
|||
#include "pycore_interp.h" // PyInterpreterState.small_ints
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
|
||||
// Don't call this function but _PyLong_GetZero() and _PyLong_GetOne()
|
||||
static inline PyObject* __PyLong_GetSmallInt_internal(int value)
|
||||
{
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
assert(-_PY_NSMALLNEGINTS <= value && value < _PY_NSMALLPOSINTS);
|
||||
size_t index = _PY_NSMALLNEGINTS + value;
|
||||
PyObject *obj = (PyObject*)&interp->small_ints[index];
|
||||
// _PyLong_GetZero(), _PyLong_GetOne() and get_small_int() must not be
|
||||
// called before _PyLong_Init() nor after _PyLong_Fini().
|
||||
assert(obj != NULL);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Return a borrowed reference to the zero singleton.
|
||||
// The function cannot return NULL.
|
||||
static inline PyObject* _PyLong_GetZero(void)
|
||||
{ return __PyLong_GetSmallInt_internal(0); }
|
||||
{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS]; }
|
||||
|
||||
// Return a borrowed reference to the one singleton.
|
||||
// The function cannot return NULL.
|
||||
static inline PyObject* _PyLong_GetOne(void)
|
||||
{ return __PyLong_GetSmallInt_internal(1); }
|
||||
{ return (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS+1]; }
|
||||
|
||||
PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
|
||||
PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
|
||||
|
|
|
@ -11,6 +11,14 @@ extern "C" {
|
|||
#include "pycore_atomic.h" /* _Py_atomic_address */
|
||||
#include "pycore_gil.h" // struct _gil_runtime_state
|
||||
|
||||
#define _PY_NSMALLPOSINTS 257
|
||||
#define _PY_NSMALLNEGINTS 5
|
||||
|
||||
// _PyLong_GetZero() and _PyLong_GetOne() must always be available
|
||||
#if _PY_NSMALLPOSINTS < 2
|
||||
# error "_PY_NSMALLPOSINTS must be greater than 1"
|
||||
#endif
|
||||
|
||||
/* ceval state */
|
||||
|
||||
struct _ceval_runtime_state {
|
||||
|
@ -100,6 +108,13 @@ typedef struct pyruntimestate {
|
|||
|
||||
unsigned long main_thread;
|
||||
|
||||
/* Small integers are preallocated in this array so that they
|
||||
* can be shared.
|
||||
* The integers that are preallocated are those in the range
|
||||
*-_PY_NSMALLNEGINTS (inclusive) to _PY_NSMALLPOSINTS (not inclusive).
|
||||
*/
|
||||
PyLongObject small_ints[_PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS];
|
||||
|
||||
#define NEXITFUNCS 32
|
||||
void (*exitfuncs[NEXITFUNCS])(void);
|
||||
int nexitfuncs;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue