Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-126119: fix some crashes in code objects if co_stacksize is absurdly large #126122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dbf3d61
fix overflow in frame's stacksizes
picnixz Oct 29, 2024
a566469
blurb
picnixz Oct 29, 2024
222de28
blurb v2
picnixz Oct 29, 2024
303109b
fix more cases
picnixz Oct 29, 2024
d743a3d
improve test coverage!
picnixz Oct 29, 2024
6b34c22
improve test coverage!
picnixz Oct 29, 2024
044d1a5
fix logic
picnixz Oct 31, 2024
d6f3bc4
remove un-necessary assertion
picnixz Oct 31, 2024
31f36de
skip a test on free-threaded builds to avoid crash
picnixz Oct 31, 2024
b26dd72
fix tests on 32-bit platforms
picnixz Oct 31, 2024
fe0b04e
fix casts
picnixz Oct 31, 2024
1fe8e28
fix boundary conditions
picnixz Oct 31, 2024
40d8b91
Merge remote-tracking branch 'upstream/main' into fix/overflow-in-fra…
picnixz Oct 31, 2024
8c7ce9c
Update Lib/test/test_frame.py
picnixz Nov 7, 2024
f8a0eef
Update Misc/NEWS.d/next/Core_and_Builtins/2024-10-29-11-47-19.gh-issu…
picnixz Nov 7, 2024
3130f94
change co_stacksize upper limit
picnixz Nov 8, 2024
91f95de
remove test that cannot overflow now
picnixz Nov 8, 2024
c5d7596
fix tests
picnixz Nov 8, 2024
a0b85d4
remove unused imports
picnixz Nov 8, 2024
04abc46
update comment
picnixz Nov 9, 2024
0187b72
remove assertions from `gen_sizeof` and `frame_sizeof`
picnixz Nov 9, 2024
c9969a4
update test
picnixz Nov 9, 2024
6c0e1a6
update test
picnixz Nov 9, 2024
a498df9
Merge branch 'main' into fix/overflow-in-frame-sizeof-126119
picnixz Feb 23, 2025
6284de6
Merge branch 'main' into fix/overflow-in-frame-sizeof-126119
picnixz May 11, 2025
fdb2e89
address review
picnixz May 15, 2025
990a69c
Merge remote-tracking branch 'upstream/main' into fix/code/overflow-1…
picnixz Jun 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,12 @@
import ctypes
except ImportError:
ctypes = None

try:
import _testcapi
except ImportError:
_testcapi = None

from test.support import (cpython_only,
check_impl_detail, requires_debug_ranges,
gc_collect, Py_GIL_DISABLED)
Expand Down Expand Up @@ -1159,6 +1165,25 @@ def test_stateless(self):
with self.assertRaises(Exception):
_testinternalcapi.verify_stateless_code(func)

@unittest.skipUnless(ctypes, "requires ctypes")
@unittest.skipUnless(_testcapi, "requires _testcapi")
def test_co_framesize_overflow(self):
# See: https://github.com/python/cpython/issues/126119.

def foo(a, b):
x = a * b
return x

c = foo.__code__

# The exact limit depends on co_nlocalsplus, so we do not hardcode it.
too_large_stacksize = _testcapi.INT_MAX // 16
ok_stacksize = too_large_stacksize // 2

with self.assertRaisesRegex(OverflowError, "stack size is too large"):
c.__replace__(co_stacksize=too_large_stacksize)
c.__replace__(co_stacksize=ok_stacksize)


def isinterned(s):
return s is sys.intern(('_' + s + '_')[1:-1])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix a crash in DEBUG builds due to a lack of overflow checks when setting
the :attr:`co_stacksize <codeobject.co_stacksize>` field of a :ref:`code
object <code-objects>` via :meth:`~object.__replace__`.
Reported by Valery Fedorenko. Patch by Bénédikt Tran.
17 changes: 16 additions & 1 deletion Objects/codeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,22 @@ _PyCode_Validate(struct _PyCodeConstructor *con)
PyErr_SetString(PyExc_ValueError, "code: co_varnames is too small");
return -1;
}

/*
* Since framesize = stacksize + nlocalsplus + FRAME_SPECIALS_SIZE is used
* as framesize * sizeof(PyObject *) and assumed to be < INT_MAX in many
* other places, we need to limit stacksize + nlocalsplus in order to
* avoid overflows.
*
* See https://github.com/python/cpython/issues/126119 for details
* and corresponding PR for the rationale on the upper limit value.
*/
Py_ssize_t limit = (Py_ssize_t)(INT_MAX / 16);
Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(con->localsplusnames);
if (nlocalsplus >= limit || con->stacksize >= limit - nlocalsplus) {
PyErr_SetString(PyExc_OverflowError,
"code: locals + stack size is too large");
return -1;
}
return 0;
}

Expand Down
Loading