Commit b7fb2e25 authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #8020: Avoid a crash where the small objects allocator would read

non-Python managed memory while it is being modified by another thread.
Patch by Matt Bandy.
parent 1122fa2e
...@@ -46,6 +46,7 @@ Stig Bakken ...@@ -46,6 +46,7 @@ Stig Bakken
Greg Ball Greg Ball
Luigi Ballabio Luigi Ballabio
Jeff Balogh Jeff Balogh
Matt Bandy
Michael J. Barber Michael J. Barber
Chris Barker Chris Barker
Nick Barnes Nick Barnes
......
...@@ -36,6 +36,10 @@ Core and Builtins ...@@ -36,6 +36,10 @@ Core and Builtins
Library Library
------- -------
- Issue #8020: Avoid a crash where the small objects allocator would read
non-Python managed memory while it is being modified by another thread.
Patch by Matt Bandy.
- Issue #10827: Changed the rules for 2-digit years. The time.asctime - Issue #10827: Changed the rules for 2-digit years. The time.asctime
function will now format any year when ``time.accept2dyear`` is function will now format any year when ``time.accept2dyear`` is
false and will accept years >= 1000 otherwise. The year range false and will accept years >= 1000 otherwise. The year range
......
...@@ -682,11 +682,19 @@ that this test determines whether an arbitrary address is controlled by ...@@ -682,11 +682,19 @@ that this test determines whether an arbitrary address is controlled by
obmalloc in a small constant time, independent of the number of arenas obmalloc in a small constant time, independent of the number of arenas
obmalloc controls. Since this test is needed at every entry point, it's obmalloc controls. Since this test is needed at every entry point, it's
extremely desirable that it be this fast. extremely desirable that it be this fast.
Since Py_ADDRESS_IN_RANGE may be reading from memory which was not allocated
by Python, it is important that (POOL)->arenaindex is read only once, as
another thread may be concurrently modifying the value without holding the
GIL. To accomplish this, the arenaindex_temp variable is used to store
(POOL)->arenaindex for the duration of the Py_ADDRESS_IN_RANGE macro's
execution. The caller of the macro is responsible for declaring this
variable.
*/ */
#define Py_ADDRESS_IN_RANGE(P, POOL) \ #define Py_ADDRESS_IN_RANGE(P, POOL) \
((POOL)->arenaindex < maxarenas && \ ((arenaindex_temp = (POOL)->arenaindex) < maxarenas && \
(uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \ (uptr)(P) - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && \
arenas[(POOL)->arenaindex].address != 0) arenas[arenaindex_temp].address != 0)
/* This is only useful when running memory debuggers such as /* This is only useful when running memory debuggers such as
...@@ -945,6 +953,9 @@ PyObject_Free(void *p) ...@@ -945,6 +953,9 @@ PyObject_Free(void *p)
block *lastfree; block *lastfree;
poolp next, prev; poolp next, prev;
uint size; uint size;
#ifndef Py_USING_MEMORY_DEBUGGER
uint arenaindex_temp;
#endif
if (p == NULL) /* free(NULL) has no effect */ if (p == NULL) /* free(NULL) has no effect */
return; return;
...@@ -1167,6 +1178,9 @@ PyObject_Realloc(void *p, size_t nbytes) ...@@ -1167,6 +1178,9 @@ PyObject_Realloc(void *p, size_t nbytes)
void *bp; void *bp;
poolp pool; poolp pool;
size_t size; size_t size;
#ifndef Py_USING_MEMORY_DEBUGGER
uint arenaindex_temp;
#endif
if (p == NULL) if (p == NULL)
return PyObject_Malloc(nbytes); return PyObject_Malloc(nbytes);
...@@ -1867,8 +1881,10 @@ _PyObject_DebugMallocStats(void) ...@@ -1867,8 +1881,10 @@ _PyObject_DebugMallocStats(void)
int int
Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_ADDRESS_IN_RANGE(void *P, poolp pool)
{ {
return pool->arenaindex < maxarenas && uint arenaindex_temp = pool->arenaindex;
(uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE &&
arenas[pool->arenaindex].address != 0; return arenaindex_temp < maxarenas &&
(uptr)P - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE &&
arenas[arenaindex_temp].address != 0;
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment