From: Paul Durrant Date: Thu, 30 May 2019 10:19:24 +0000 (+0100) Subject: Avoid double-free hazard in XENBUS_CACHE X-Git-Tag: 9.0.0-rc1~20 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=478738be1d14819e04c47d118a03c05f49462e44;p=pvdrivers%2Fwin%2Fxenbus.git Avoid double-free hazard in XENBUS_CACHE Currently CachePut() calls CachePutObjectToSlab() without holding the cache lock. This allows two concurrent calls to subsequently serialize on the lock and both find Slab->Allocated == 0 (the second one actually testing freed memory), leading to a double-free. Moving the lock acquisition to before the call to CachePutObjectToSlab() fixes this problem. For consistency, this patch also makes it a requirement that CachePutObjectToSlab() is called with the lock held, and adjusts __CacheFlushMagazines() accordingly. Signed-off-by: Paul Durrant --- diff --git a/src/xenbus/cache.c b/src/xenbus/cache.c index a0f4135..877b395 100644 --- a/src/xenbus/cache.c +++ b/src/xenbus/cache.c @@ -355,7 +355,7 @@ CacheGetObjectFromSlab( return (PVOID)&Slab->Buffer[Index * Cache->Size]; } -// May be called with or without lock held +// Must be called with lock held static VOID CachePutObjectToSlab( IN PXENBUS_CACHE_SLAB Slab, @@ -460,11 +460,11 @@ CachePut( Slab = (PXENBUS_CACHE_SLAB)PAGE_ALIGN(Object); ASSERT3U(Slab->Magic, ==, XENBUS_CACHE_SLAB_MAGIC); - CachePutObjectToSlab(Slab, Object); - if (!Locked) __CacheAcquireLock(Cache); + CachePutObjectToSlab(Slab, Object); + if (Slab->Allocated == 0) { CacheDestroySlab(Cache, Slab); } else { @@ -554,8 +554,12 @@ __CacheFlushMagazines( IN PXENBUS_CACHE Cache ) { + KIRQL Irql; ULONG Index; + KeRaiseIrql(DISPATCH_LEVEL, &Irql); + __CacheAcquireLock(Cache); + for (Index = 0; Index < Cache->MagazineCount; Index++) { PXENBUS_CACHE_MAGAZINE Magazine = &Cache->Magazine[Index]; PVOID Object; @@ -569,6 +573,9 @@ __CacheFlushMagazines( CachePutObjectToSlab(Slab, Object); } } + + __CacheReleaseLock(Cache); + KeLowerIrql(Irql); } static NTSTATUS