Skip to content

Commit c4ed3c4

Browse files
authored
Various UAFs & cosmetic fixes in Python/{bltinmodule,bytecode,ceval}.c (#33)
* fix UAF in `bltinmodule.c` * fix UAF in `bytecode.c` * run `make regen-all` * various improvements to `ceval.c` * fix CI
1 parent f96a99c commit c4ed3c4

File tree

5 files changed

+61
-36
lines changed

5 files changed

+61
-36
lines changed

Python/bltinmodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ builtin___lazy_import___impl(PyObject *module, PyObject *name,
332332
PyErr_SetString(PyExc_AttributeError, "builtins module has no dict");
333333
return NULL;
334334
}
335-
Py_DECREF(builtins);
336-
builtins = builtins_dict;
335+
Py_SETREF(builtins, builtins_dict);
337336
}
338337

339338
PyObject *res = _PyImport_LazyImportModuleLevelObject(tstate, name, builtins,

Python/bytecodes.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,8 +1760,7 @@ dummy_func(
17601760

17611761
if (PyLazyImport_CheckExact(v_o)) {
17621762
PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o);
1763-
Py_DECREF(v_o);
1764-
v_o = l_v;
1763+
Py_SETREF(v_o, l_v);
17651764
ERROR_IF(v_o == NULL);
17661765
}
17671766
}
@@ -1783,8 +1782,7 @@ dummy_func(
17831782
}
17841783
if (PyLazyImport_CheckExact(v_o)) {
17851784
PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o);
1786-
Py_DECREF(v_o);
1787-
v_o = l_v;
1785+
Py_SETREF(v_o, l_v);
17881786
ERROR_IF(v_o == NULL);
17891787
}
17901788
}
@@ -1798,14 +1796,18 @@ dummy_func(
17981796
ERROR_IF(v_o == NULL);
17991797
if (PyLazyImport_CheckExact(v_o)) {
18001798
PyObject *l_v = _PyImport_LoadLazyImportTstate(tstate, v_o);
1801-
Py_DECREF(v_o);
1802-
ERROR_IF(l_v == NULL);
1799+
// cannot early-decref v_o as it may cause a side-effect on l_v
1800+
if (l_v == NULL) {
1801+
Py_DECREF(v_o);
1802+
ERROR_IF(true);
1803+
}
18031804
int err = _PyModule_ReplaceLazyValue(GLOBALS(), name, l_v);
18041805
if (err < 0) {
1806+
Py_DECREF(v_o);
18051807
Py_DECREF(l_v);
18061808
ERROR_IF(true);
18071809
}
1808-
v_o = l_v;
1810+
Py_SETREF(v_o, l_v);
18091811
}
18101812

18111813
v = PyStackRef_FromPyObjectSteal(v_o);
@@ -2946,7 +2948,8 @@ dummy_func(
29462948
PyStackRef_AsPyObjectBorrow(level),
29472949
oparg & 0x01);
29482950

2949-
} else {
2951+
}
2952+
else {
29502953
res_o = _PyEval_ImportName(tstate, BUILTINS(), GLOBALS(), LOCALS(), name,
29512954
PyStackRef_AsPyObjectBorrow(fromlist),
29522955
PyStackRef_AsPyObjectBorrow(level));
@@ -2961,7 +2964,8 @@ dummy_func(
29612964
PyObject *res_o;
29622965
if (PyLazyImport_CheckExact(PyStackRef_AsPyObjectBorrow(from))) {
29632966
res_o = _PyEval_LazyImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name);
2964-
} else {
2967+
}
2968+
else {
29652969
res_o = _PyEval_ImportFrom(tstate, PyStackRef_AsPyObjectBorrow(from), name);
29662970
}
29672971

Python/ceval.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,25 +3471,28 @@ _PyEval_ImportNameWithImport(PyThreadState *tstate, PyObject *import_func, PyObj
34713471
ilevel);
34723472
}
34733473

3474-
PyObject* args[5] = {name, globals, locals, fromlist, level};
3474+
PyObject *args[5] = {name, globals, locals, fromlist, level};
34753475
PyObject *res = PyObject_Vectorcall(import_func, args, 5, NULL);
34763476
return res;
34773477
}
34783478

34793479
static int
3480-
check_lazy_import_comatibility(PyThreadState *tstate, PyObject *globals,
3480+
check_lazy_import_compatibility(PyThreadState *tstate, PyObject *globals,
34813481
PyObject *name, PyObject *level)
34823482
{
3483-
// Check if this module should be imported lazily due to the compatbility mode support via
3484-
// __lazy_modules__.
3483+
// Check if this module should be imported lazily due to
3484+
// the compatibility mode support via __lazy_modules__.
34853485
PyObject *lazy_modules = NULL;
34863486
PyObject *abs_name = NULL;
34873487
int res = -1;
34883488

34893489
if (globals != NULL &&
3490-
PyMapping_GetOptionalItem(globals, &_Py_ID(__lazy_modules__), &lazy_modules) < 0) {
3490+
PyMapping_GetOptionalItem(globals, &_Py_ID(__lazy_modules__), &lazy_modules) < 0)
3491+
{
34913492
return -1;
3492-
} else if (lazy_modules == NULL) {
3493+
}
3494+
if (lazy_modules == NULL) {
3495+
assert(!PyErr_Occurred());
34933496
return 0;
34943497
}
34953498

@@ -3530,7 +3533,7 @@ _PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *glob
35303533

35313534
if (!lazy) {
35323535
// see if __lazy_imports__ forces this to be lazy
3533-
lazy = check_lazy_import_comatibility(tstate, globals, name, level);
3536+
lazy = check_lazy_import_compatibility(tstate, globals, name, level);
35343537
if (lazy < 0) {
35353538
return NULL;
35363539
}
@@ -3544,7 +3547,9 @@ _PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *glob
35443547
PyObject *lazy_import_func;
35453548
if (PyMapping_GetOptionalItem(builtins, &_Py_ID(__lazy_import__), &lazy_import_func) < 0) {
35463549
goto error;
3547-
} else if (lazy_import_func == NULL) {
3550+
}
3551+
if (lazy_import_func == NULL) {
3552+
assert(!PyErr_Occurred());
35483553
_PyErr_SetString(tstate, PyExc_ImportError, "__lazy_import__ not found");
35493554
goto error;
35503555
}
@@ -3565,7 +3570,7 @@ _PyEval_LazyImportName(PyThreadState *tstate, PyObject *builtins, PyObject *glob
35653570
goto error;
35663571
}
35673572

3568-
PyObject* args[6] = {name, globals, locals, fromlist, level, builtins};
3573+
PyObject *args[6] = {name, globals, locals, fromlist, level, builtins};
35693574
res = PyObject_Vectorcall(lazy_import_func, args, 6, NULL);
35703575
error:
35713576
Py_XDECREF(lazy_import_func);
@@ -3744,7 +3749,8 @@ PyObject *
37443749
_PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
37453750
{
37463751
assert(PyLazyImport_CheckExact(v));
3747-
assert(name && PyUnicode_Check(name));
3752+
assert(name);
3753+
assert(PyUnicode_Check(name));
37483754
PyObject *ret;
37493755
PyLazyImportObject *d = (PyLazyImportObject *)v;
37503756
PyObject *mod = PyImport_GetModule(d->lz_from);
@@ -3756,7 +3762,8 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
37563762
if (PyDict_GetItemRef(mod_dict, name, &ret) < 0) {
37573763
Py_DECREF(mod);
37583764
return NULL;
3759-
} else if (ret != NULL) {
3765+
}
3766+
if (ret != NULL) {
37603767
Py_DECREF(mod);
37613768
return ret;
37623769
}
@@ -3775,8 +3782,11 @@ _PyEval_LazyImportFrom(PyThreadState *tstate, PyObject *v, PyObject *name)
37753782
Py_DECREF(from);
37763783
return ret;
37773784
}
3778-
} else {
3779-
Py_ssize_t dot = PyUnicode_FindChar(d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1);
3785+
}
3786+
else {
3787+
Py_ssize_t dot = PyUnicode_FindChar(
3788+
d->lz_from, '.', 0, PyUnicode_GET_LENGTH(d->lz_from), 1
3789+
);
37803790
if (dot >= 0) {
37813791
PyObject *from = PyUnicode_Substring(d->lz_from, 0, dot);
37823792
if (from == NULL) {

Python/executor_cases.c.h

Lines changed: 11 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 13 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)