mirror of
https://github.com/python/cpython.git
synced 2025-08-19 00:00:48 +00:00
Merged revisions 87834 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r87834 | antoine.pitrou | 2011-01-07 22:43:59 +0100 (ven., 07 janv. 2011) | 5 lines 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. ........
This commit is contained in:
parent
1f1613f0cc
commit
5a72e76b69
3 changed files with 34 additions and 6 deletions
|
@ -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 controls. Since this test is needed at every entry point, it's
|
||||
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) \
|
||||
((POOL)->arenaindex < maxarenas && \
|
||||
(uptr)(P) - arenas[(POOL)->arenaindex].address < (uptr)ARENA_SIZE && \
|
||||
arenas[(POOL)->arenaindex].address != 0)
|
||||
((arenaindex_temp = (POOL)->arenaindex) < maxarenas && \
|
||||
(uptr)(P) - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && \
|
||||
arenas[arenaindex_temp].address != 0)
|
||||
|
||||
|
||||
/* This is only useful when running memory debuggers such as
|
||||
|
@ -945,6 +953,9 @@ PyObject_Free(void *p)
|
|||
block *lastfree;
|
||||
poolp next, prev;
|
||||
uint size;
|
||||
#ifndef Py_USING_MEMORY_DEBUGGER
|
||||
uint arenaindex_temp;
|
||||
#endif
|
||||
|
||||
if (p == NULL) /* free(NULL) has no effect */
|
||||
return;
|
||||
|
@ -1167,6 +1178,9 @@ PyObject_Realloc(void *p, size_t nbytes)
|
|||
void *bp;
|
||||
poolp pool;
|
||||
size_t size;
|
||||
#ifndef Py_USING_MEMORY_DEBUGGER
|
||||
uint arenaindex_temp;
|
||||
#endif
|
||||
|
||||
if (p == NULL)
|
||||
return PyObject_Malloc(nbytes);
|
||||
|
@ -1865,8 +1879,10 @@ _PyObject_DebugMallocStats(void)
|
|||
int
|
||||
Py_ADDRESS_IN_RANGE(void *P, poolp pool)
|
||||
{
|
||||
return pool->arenaindex < maxarenas &&
|
||||
(uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE &&
|
||||
arenas[pool->arenaindex].address != 0;
|
||||
uint arenaindex_temp = pool->arenaindex;
|
||||
|
||||
return arenaindex_temp < maxarenas &&
|
||||
(uptr)P - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE &&
|
||||
arenas[arenaindex_temp].address != 0;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue