[Python-checkins] r87834 - in python/branches/py3k: Misc/ACKS Misc/NEWS Objects/obmalloc.c

antoine.pitrou python-checkins at python.org
Fri Jan 7 22:44:05 CET 2011


Author: antoine.pitrou
Date: Fri Jan 7 22:43:59 2011
New Revision: 87834
Log:
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.
Modified:
 python/branches/py3k/Misc/ACKS
 python/branches/py3k/Misc/NEWS
 python/branches/py3k/Objects/obmalloc.c
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Fri Jan 7 22:43:59 2011
@@ -46,6 +46,7 @@
 Greg Ball
 Luigi Ballabio
 Jeff Balogh
+Matt Bandy
 Michael J. Barber
 Chris Barker
 Nick Barnes
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jan 7 22:43:59 2011
@@ -36,6 +36,10 @@
 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
 function will now format any year when ``time.accept2dyear`` is
 false and will accept years >= 1000 otherwise. The year range
Modified: python/branches/py3k/Objects/obmalloc.c
==============================================================================
--- python/branches/py3k/Objects/obmalloc.c	(original)
+++ python/branches/py3k/Objects/obmalloc.c	Fri Jan 7 22:43:59 2011
@@ -682,11 +682,19 @@
 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 @@
 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 @@
 void *bp;
 poolp pool;
 size_t size;
+#ifndef Py_USING_MEMORY_DEBUGGER
+ uint arenaindex_temp;
+#endif
 
 if (p == NULL)
 return PyObject_Malloc(nbytes);
@@ -1867,8 +1881,10 @@
 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


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /