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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 14 additions & 3 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy