Skip to content

Commit 427e7fc

Browse files
authored
gh-132399: ensure correct alignment of PyInterpreterState (#132428)
1 parent 8a9c6c4 commit 427e7fc

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

Include/internal/pycore_interp_structs.h

+6
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,12 @@ struct _is {
754754
* and should be placed at the beginning. */
755755
struct _ceval_state ceval;
756756

757+
/* This structure is carefully allocated so that it's correctly aligned
758+
* to avoid undefined behaviors during LOAD and STORE. The '_malloced'
759+
* field stores the allocated pointer address that will later be freed.
760+
*/
761+
void *_malloced;
762+
757763
PyInterpreterState *next;
758764

759765
int64_t id;

Python/pystate.c

+14-3
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,19 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
569569
return _PyStatus_OK();
570570
}
571571

572-
573572
static PyInterpreterState *
574573
alloc_interpreter(void)
575574
{
576-
return PyMem_RawCalloc(1, sizeof(PyInterpreterState));
575+
size_t alignment = _Alignof(PyInterpreterState);
576+
size_t allocsize = sizeof(PyInterpreterState) + alignment - 1;
577+
void *mem = PyMem_RawCalloc(1, allocsize);
578+
if (mem == NULL) {
579+
return NULL;
580+
}
581+
PyInterpreterState *interp = _Py_ALIGN_UP(mem, alignment);
582+
assert(_Py_IS_ALIGNED(interp, alignment));
583+
interp->_malloced = mem;
584+
return interp;
577585
}
578586

579587
static void
@@ -587,12 +595,15 @@ free_interpreter(PyInterpreterState *interp)
587595
PyMem_RawFree(interp->obmalloc);
588596
interp->obmalloc = NULL;
589597
}
590-
PyMem_RawFree(interp);
598+
assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState)));
599+
PyMem_RawFree(interp->_malloced);
591600
}
592601
}
602+
593603
#ifndef NDEBUG
594604
static inline int check_interpreter_whence(long);
595605
#endif
606+
596607
/* Get the interpreter state to a minimal consistent state.
597608
Further init happens in pylifecycle.c before it can be used.
598609
All fields not initialized here are expected to be zeroed out,

0 commit comments

Comments
 (0)