Kaydet (Commit) 5b6fc639 authored tarafından Antoine Pitrou's avatar Antoine Pitrou

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.
........
üst ff17385f
......@@ -39,6 +39,7 @@ Stig Bakken
Greg Ball
Luigi Ballabio
Jeff Balogh
Matt Bandy
Michael J. Barber
Chris Barker
Nick Barnes
......
......@@ -10,6 +10,10 @@ What's New in Python 3.1.4?
Core and Builtins
-----------------
- 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 #8278: On Windows and with a NTFS filesystem, os.stat() and os.utime()
can now handle dates after 2038.
......
......@@ -667,11 +667,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
......@@ -923,6 +931,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;
......@@ -1137,6 +1148,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);
......@@ -1758,8 +1772,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
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