59 lines
2.3 KiB
Diff
59 lines
2.3 KiB
Diff
|
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||
|
Date: Tue, 16 Mar 2021 17:44:56 +0400
|
||
|
Subject: util: fix use-after-free in module_load_one
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
Git-commit: 64e16fbbf49ce81b37841480d14b0caf5753c98e
|
||
|
|
||
|
g_hash_table_add always retains ownership of the pointer passed in as
|
||
|
the key. Its return status merely indicates whether the added entry was
|
||
|
new, or replaced an existing entry. Thus key must never be freed after
|
||
|
this method returns.
|
||
|
|
||
|
Spotted by ASAN:
|
||
|
|
||
|
==2407186==ERROR: AddressSanitizer: heap-use-after-free on address 0x6020003ac4f0 at pc 0x7ffff766659c bp 0x7fffffffd1d0 sp 0x7fffffffc980
|
||
|
READ of size 1 at 0x6020003ac4f0 thread T0
|
||
|
#0 0x7ffff766659b (/lib64/libasan.so.6+0x8a59b)
|
||
|
#1 0x7ffff6bfa843 in g_str_equal ../glib/ghash.c:2303
|
||
|
#2 0x7ffff6bf8167 in g_hash_table_lookup_node ../glib/ghash.c:493
|
||
|
#3 0x7ffff6bf9b78 in g_hash_table_insert_internal ../glib/ghash.c:1598
|
||
|
#4 0x7ffff6bf9c32 in g_hash_table_add ../glib/ghash.c:1689
|
||
|
#5 0x5555596caad4 in module_load_one ../util/module.c:233
|
||
|
#6 0x5555596ca949 in module_load_one ../util/module.c:225
|
||
|
#7 0x5555596ca949 in module_load_one ../util/module.c:225
|
||
|
#8 0x5555596cbdf4 in module_load_qom_all ../util/module.c:349
|
||
|
|
||
|
Typical C bug...
|
||
|
|
||
|
Fixes: 90629122d2e ("module: use g_hash_table_add()")
|
||
|
Cc: qemu-stable@nongnu.org
|
||
|
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||
|
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||
|
Message-Id: <20210316134456.3243102-1-marcandre.lureau@redhat.com>
|
||
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
|
||
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
||
|
---
|
||
|
util/module.c | 3 ++-
|
||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/util/module.c b/util/module.c
|
||
|
index cbe89fede628c3674e49194ee688..7661d0f6234d952f375ad09f67d7 100644
|
||
|
--- a/util/module.c
|
||
|
+++ b/util/module.c
|
||
|
@@ -230,10 +230,11 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- if (!g_hash_table_add(loaded_modules, module_name)) {
|
||
|
+ if (g_hash_table_contains(loaded_modules, module_name)) {
|
||
|
g_free(module_name);
|
||
|
return true;
|
||
|
}
|
||
|
+ g_hash_table_add(loaded_modules, module_name);
|
||
|
|
||
|
search_dir = getenv("QEMU_MODULE_DIR");
|
||
|
if (search_dir != NULL) {
|