diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-04-11 09:33:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-11 09:33:27 (GMT) |
commit | 2b00db68554422ec37faba2a80179a0172df6349 (patch) | |
tree | 164b39074b3563200714215ea8273c59f173feb5 /Include | |
parent | 57b1a2862a99677f09614e9e456d36aae9ddd87c (diff) | |
download | cpython-2b00db68554422ec37faba2a80179a0172df6349.zip cpython-2b00db68554422ec37faba2a80179a0172df6349.tar.gz cpython-2b00db68554422ec37faba2a80179a0172df6349.tar.bz2 |
bpo-36389: _PyObject_IsFreed() now also detects uninitialized memory (GH-12770)
Replace _PyMem_IsFreed() function with _PyMem_IsPtrFreed() inline
function. The function is now way more efficient, it became a simple
comparison on integers, rather than a short loop. It detects also
uninitialized bytes and "forbidden bytes" filled by debug hooks
on memory allocators.
Add unit tests on _PyObject_IsFreed().
Diffstat (limited to 'Include')
-rw-r--r-- | Include/internal/pycore_pymem.h | 25 | ||||
-rw-r--r-- | Include/pymem.h | 2 |
2 files changed, 25 insertions, 2 deletions
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index 1e7da87..78d457d 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -155,6 +155,31 @@ PyAPI_FUNC(int) _PyMem_SetDefaultAllocator( PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc); +/* Heuristic checking if a pointer value is newly allocated + (uninitialized) or newly freed. The pointer is not dereferenced, only the + pointer value is checked. + + The heuristic relies on the debug hooks on Python memory allocators which + fills newly allocated memory with CLEANBYTE (0xCB) and newly freed memory + with DEADBYTE (0xDB). Detect also "untouchable bytes" marked + with FORBIDDENBYTE (0xFB). */ +static inline int _PyMem_IsPtrFreed(void *ptr) +{ + uintptr_t value = (uintptr_t)ptr; +#if SIZEOF_VOID_P == 8 + return (value == (uintptr_t)0xCBCBCBCBCBCBCBCB + || value == (uintptr_t)0xDBDBDBDBDBDBDBDB + || value == (uintptr_t)0xFBFBFBFBFBFBFBFB + ); +#elif SIZEOF_VOID_P == 4 + return (value == (uintptr_t)0xCBCBCBCB + || value == (uintptr_t)0xDBDBDBDB + || value == (uintptr_t)0xFBFBFBFB); +#else +# error "unknown pointer size" +#endif +} + #ifdef __cplusplus } #endif diff --git a/Include/pymem.h b/Include/pymem.h index 23457ad..93243f8 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -23,8 +23,6 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt); /* Try to get the allocators name set by _PyMem_SetupAllocators(). */ PyAPI_FUNC(const char*) _PyMem_GetAllocatorsName(void); - -PyAPI_FUNC(int) _PyMem_IsFreed(void *ptr, size_t size); #endif /* !defined(Py_LIMITED_API) */ |