From: VMware, Inc <> Date: Mon, 15 Oct 2012 04:54:23 +0000 (-0700) Subject: vmmemctl: fix a double free on linux balloon driver X-Git-Tag: 2012.10.14-874563~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c6a36174116bef0e934797da5bbd041f00a8ed6;p=thirdparty%2Fopen-vm-tools.git vmmemctl: fix a double free on linux balloon driver On unload when using the unbatched commands, b->pageHandle would be free two times. The first one when releasing all the pages of the balloon, and the second time when releasing the batch structures. This was causing OOPS and sometimes panic when rmmod the driver. The fix is to set b->pageHandle to PAGE_HANDLE_INVALID when it's added to the chunks or when the page is released. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/modules/shared/vmmemctl/vmballoon.c b/open-vm-tools/modules/shared/vmmemctl/vmballoon.c index 1289fd64b..cb62a8c2c 100644 --- a/open-vm-tools/modules/shared/vmmemctl/vmballoon.c +++ b/open-vm-tools/modules/shared/vmmemctl/vmballoon.c @@ -1000,7 +1000,8 @@ BalloonLock(Balloon *b, // IN chunk = BalloonGetChunk(b); if (chunk == NULL) { OS_ReservedPageFree(b->pageHandle); - return BALLOON_PAGE_ALLOC_FAILURE; + status = BALLOON_PAGE_ALLOC_FAILURE; + goto out; } /* inform monitor via backdoor */ @@ -1012,17 +1013,18 @@ BalloonLock(Balloon *b, // IN if (status == BALLOON_ERROR_RESET || status == BALLOON_ERROR_PPN_NOTNEEDED) { OS_ReservedPageFree(b->pageHandle); - return status; + goto out; } /* place on list of non-balloonable pages, retry allocation */ status = BalloonErrorPageStore(b, b->pageHandle); if (status != BALLOON_SUCCESS) { OS_ReservedPageFree(b->pageHandle); - return status; + goto out; } - return old_status; + status = old_status; + goto out; } /* track allocated page */ @@ -1031,6 +1033,8 @@ BalloonLock(Balloon *b, // IN /* update balloon size */ b->nPages++; +out: + b->pageHandle = PAGE_HANDLE_INVALID; return status; } @@ -1071,6 +1075,7 @@ BalloonUnlock(Balloon *b, // IN b->nPages--; out: + b->pageHandle = PAGE_HANDLE_INVALID; if (b->fallbackChunk != NULL) { BalloonChunk_Destroy(b->fallbackChunk); b->fallbackChunk = NULL; @@ -1099,6 +1104,7 @@ BalloonAddPage(Balloon *b, // IN uint16 idx, // IN PageHandle page) // IN { + ASSERT(b->pageHandle == PAGE_HANDLE_INVALID); b->pageHandle = page; } @@ -1252,6 +1258,8 @@ Balloon_Init(BalloonGuest guestType) /* initialize reset flag */ b->resetFlag = TRUE; + b->hypervisorCapabilities = 0; + b->pageHandle = PAGE_HANDLE_INVALID; b->batchPageMapping = MAPPING_INVALID; b->batchPage = NULL;