diff options
author | Mark Shannon <mark@hotpy.org> | 2021-11-03 16:22:32 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-03 16:22:32 (GMT) |
commit | acc89db9233abf4d903af9a7595a2ed7478fe7d3 (patch) | |
tree | fb08e91bc2dab4db12daace28c778749a293a20f /Objects/longobject.c | |
parent | 5a14929a6e4fab672e2f83a86773618e973b22a6 (diff) | |
download | cpython-acc89db9233abf4d903af9a7595a2ed7478fe7d3.zip cpython-acc89db9233abf4d903af9a7595a2ed7478fe7d3.tar.gz cpython-acc89db9233abf4d903af9a7595a2ed7478fe7d3.tar.bz2 |
bpo-45691: Make array of small ints static to fix use-after-free error. (GH-29366)
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index b7392e5..a4d90b1 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4,8 +4,8 @@ #include "Python.h" #include "pycore_bitutils.h" // _Py_popcount32() -#include "pycore_interp.h" // _PY_NSMALLPOSINTS -#include "pycore_long.h" // __PyLong_GetSmallInt_internal() +#include "pycore_runtime.h" // _PY_NSMALLPOSINTS +#include "pycore_long.h" // _Py_SmallInts #include "pycore_object.h" // _PyObject_InitVar() #include "pycore_pystate.h" // _Py_IsMainInterpreter() @@ -20,9 +20,6 @@ class int "PyObject *" "&PyLong_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ -#define NSMALLNEGINTS _PY_NSMALLNEGINTS -#define NSMALLPOSINTS _PY_NSMALLPOSINTS - _Py_IDENTIFIER(little); _Py_IDENTIFIER(big); @@ -37,8 +34,8 @@ medium_value(PyLongObject *x) return ((stwodigits)Py_SIZE(x)) * x->ob_digit[0]; } -#define IS_SMALL_INT(ival) (-NSMALLNEGINTS <= (ival) && (ival) < NSMALLPOSINTS) -#define IS_SMALL_UINT(ival) ((ival) < NSMALLPOSINTS) +#define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS) +#define IS_SMALL_UINT(ival) ((ival) < _PY_NSMALLPOSINTS) static inline int is_medium_int(stwodigits x) { @@ -51,7 +48,7 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyObject *v = __PyLong_GetSmallInt_internal(ival); + PyObject *v = (PyObject *)&_PyRuntime.small_ints[_PY_NSMALLNEGINTS + ival]; Py_INCREF(v); return v; } @@ -5830,17 +5827,18 @@ PyLong_GetInfo(void) void _PyLong_Init(PyInterpreterState *interp) { - for (Py_ssize_t i=0; i < NSMALLNEGINTS + NSMALLPOSINTS; i++) { - sdigit ival = (sdigit)i - NSMALLNEGINTS; - int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); - interp->small_ints[i].ob_base.ob_base.ob_refcnt = 1; - interp->small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type; - interp->small_ints[i].ob_base.ob_size = size; - interp->small_ints[i].ob_digit[0] = (digit)abs(ival); + if (_PyRuntime.small_ints[0].ob_base.ob_base.ob_refcnt == 0) { + for (Py_ssize_t i=0; i < _PY_NSMALLNEGINTS + _PY_NSMALLPOSINTS; i++) { + sdigit ival = (sdigit)i - _PY_NSMALLNEGINTS; + int size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1); + _PyRuntime.small_ints[i].ob_base.ob_base.ob_refcnt = 1; + _PyRuntime.small_ints[i].ob_base.ob_base.ob_type = &PyLong_Type; + _PyRuntime.small_ints[i].ob_base.ob_size = size; + _PyRuntime.small_ints[i].ob_digit[0] = (digit)abs(ival); + } } } - int _PyLong_InitTypes(void) { |