提交 5dc6169b 编写于 作者: M Michal Privoznik

virmacmap: Don't use hash table dataFree callback

Due to nature of operations we do over the string list (more
precisely due to how virStringListRemove() works), it is not the
best idea to use dataFree callback. Problem is, on MAC address
remove, the string list remove function modifies the original
list in place. Then, virHashUpdateEntry() is called which frees
all the data stored in the list rendering @newMacsList point to
freed data.

==16002== Invalid read of size 8
==16002==    at 0x50BC083: virFree (viralloc.c:582)
==16002==    by 0x513DC39: virStringListFree (virstring.c:251)
==16002==    by 0x51089B4: virMacMapHashFree (virmacmap.c:67)
==16002==    by 0x50EF30B: virHashAddOrUpdateEntry (virhash.c:352)
==16002==    by 0x50EF4FD: virHashUpdateEntry (virhash.c:415)
==16002==    by 0x5108BED: virMacMapRemoveLocked (virmacmap.c:129)
==16002==    by 0x51092D5: virMacMapRemove (virmacmap.c:346)
==16002==    by 0x402F02: testMACRemove (virmacmaptest.c:107)
==16002==    by 0x403F15: virTestRun (testutils.c:180)
==16002==    by 0x4032C4: mymain (virmacmaptest.c:205)
==16002==    by 0x405A3B: virTestMain (testutils.c:992)
==16002==    by 0x403D87: main (virmacmaptest.c:237)
==16002==  Address 0xdd5a4d0 is 0 bytes inside a block of size 24 free'd
==16002==    at 0x4C2AD6F: realloc (vg_replace_malloc.c:693)
==16002==    by 0x50BB99B: virReallocN (viralloc.c:245)
==16002==    by 0x513DC0B: virStringListRemove (virstring.c:235)
==16002==    by 0x5108BA6: virMacMapRemoveLocked (virmacmap.c:124)
==16002==    by 0x51092D5: virMacMapRemove (virmacmap.c:346)
==16002==    by 0x402F02: testMACRemove (virmacmaptest.c:107)
==16002==    by 0x403F15: virTestRun (testutils.c:180)
==16002==    by 0x4032C4: mymain (virmacmaptest.c:205)
==16002==    by 0x405A3B: virTestMain (testutils.c:992)
==16002==    by 0x403D87: main (virmacmaptest.c:237)
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
上级 806582a5
...@@ -53,18 +53,22 @@ struct virMacMap { ...@@ -53,18 +53,22 @@ struct virMacMap {
static virClassPtr virMacMapClass; static virClassPtr virMacMapClass;
static void static int
virMacMapDispose(void *obj) virMacMapHashFree(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{ {
virMacMapPtr mgr = obj; virStringListFree(payload);
virHashFree(mgr->macs); return 0;
} }
static void static void
virMacMapHashFree(void *payload, const void *name ATTRIBUTE_UNUSED) virMacMapDispose(void *obj)
{ {
virStringListFree(payload); virMacMapPtr mgr = obj;
virHashForEach(mgr->macs, virMacMapHashFree, NULL);
virHashFree(mgr->macs);
} }
...@@ -88,19 +92,20 @@ virMacMapAddLocked(virMacMapPtr mgr, ...@@ -88,19 +92,20 @@ virMacMapAddLocked(virMacMapPtr mgr,
const char *mac) const char *mac)
{ {
int ret = -1; int ret = -1;
const char **macsList = NULL; char **macsList = NULL;
char **newMacsList = NULL; char **newMacsList = NULL;
if ((macsList = virHashLookup(mgr->macs, domain)) && if ((macsList = virHashLookup(mgr->macs, domain)) &&
virStringListHasString(macsList, mac)) { virStringListHasString((const char**) macsList, mac)) {
ret = 0; ret = 0;
goto cleanup; goto cleanup;
} }
if (!(newMacsList = virStringListAdd(macsList, mac)) || if (!(newMacsList = virStringListAdd((const char **) macsList, mac)) ||
virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0) virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0)
goto cleanup; goto cleanup;
newMacsList = NULL; newMacsList = NULL;
virStringListFree(macsList);
ret = 0; ret = 0;
cleanup: cleanup:
...@@ -303,8 +308,7 @@ virMacMapNew(const char *file) ...@@ -303,8 +308,7 @@ virMacMapNew(const char *file)
return NULL; return NULL;
virObjectLock(mgr); virObjectLock(mgr);
if (!(mgr->macs = virHashCreate(VIR_MAC_HASH_TABLE_SIZE, if (!(mgr->macs = virHashCreate(VIR_MAC_HASH_TABLE_SIZE, NULL)))
virMacMapHashFree)))
goto error; goto error;
if (file && if (file &&
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册