diff options
author | Mark Shannon <mark@hotpy.org> | 2021-11-03 16:22:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-03 16:22:32 +0000 |
commit | acc89db9233abf4d903af9a7595a2ed7478fe7d3 (patch) | |
tree | fb08e91bc2dab4db12daace28c778749a293a20f /Include | |
parent | 5a14929a6e4fab672e2f83a86773618e973b22a6 (diff) | |
download | cpython-git-acc89db9233abf4d903af9a7595a2ed7478fe7d3.tar.gz |
bpo-45691: Make array of small ints static to fix use-after-free error. (GH-29366)
Diffstat (limited to 'Include')
-rw-r--r-- | Include/internal/pycore_interp.h | 14 | ||||
-rw-r--r-- | Include/internal/pycore_long.h | 17 | ||||
-rw-r--r-- | Include/internal/pycore_runtime.h | 15 |
3 files changed, 17 insertions, 29 deletions
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 8bd3dc064e..18f2143200 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -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; diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 773025b4a5..2f786083e4 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -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); diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index bcd710c449..9df833c270 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -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; |