Skip to content

Potential use-after-free in Py_SetPythonHome and its siblings #98978

Description

@filmor

Bug report

void
Py_SetPythonHome(constwchar_t*home)
{
inthas_value=home&&home[0];
PyMemAllocatorExold_alloc;
_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
PyMem_RawFree(_Py_path_config.home);
if (has_value) {
_Py_path_config.home=_PyMem_RawWcsdup(home);
}
PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
if (has_value&&_Py_path_config.home==NULL) {
path_out_of_memory(__func__);
}
}

If Py_SetPythonHome was called with a non-empty string and is subsequently called with an empty one, it will always run PyMem_RawFree but only actually reset the pointer in .home if has_value is set, so if home && home[0] (i.e. non-empty string).

Minimal example:

Py_SetPythonHome(L"/non-empty");
Py_SetPythonHome(L"");
// After this, the memory region in .home is freed but the pointer is not overwritten

Your environment

The issue occurs in our (Python.NET) test-suite: pythonnet/pythonnet#1955

  • CPython versions tested on: 3.7 - 3.11, only occurs in 3.11
  • Operating system and architecture: Windows (x86, amd64), macOS (amd64), Linux (amd64)

Additional notes

This bug was introduced in #29041, in the initial commit: a63f5d8

It's a regression, the first faulty version was 3.11.0a3.

@vstinner@zooba

Metadata

Metadata

Assignees

Labels

3.11only security fixes3.12only security fixestype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions