opkg version is v0.8.0. The test command is: opkg install test/pack_name_0.0.1_aarch64.ipk --force-reinstall The call stack looks like this: ================================================================= ==22017==ERROR: LeakSanitizer: detected memory leaks Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7fb09c8760 in __interceptor_calloc (/lib64/libasan.so.8+0xc8760) #1 0x55675c1734 in xcalloc opkg-master/libopkg/xfuncs.c:56 #2 0x55675b29bc in pkg_vec_alloc opkg-master/libopkg/pkg_vec.c:33 #3 0x556759833c in pkg_init opkg-master/libopkg/pkg.c:96 #4 0x5567598b8c in pkg_new opkg-master/libopkg/pkg.c:143 #5 0x556758e138 in opkg_prepare_file_for_install opkg-master/libopkg/opkg_download.c:421 #6 0x556758eba0 in opkg_prepare_url_for_install opkg-master/libopkg/opkg_download.c:552 #7 0x55675884bc in opkg_install_cmd opkg-master/libopkg/opkg_cmd.c:420 #8 0x556758c514 in opkg_cmd_exec opkg-master/libopkg/opkg_cmd.c:1310 #9 0x5567585ab4 in main opkg-master/src/opkg.c:544 #10 0x7fad80e368 (/lib/libc.so.6+0x2b368) #11 0x7fad80e444 in __libc_start_main (/lib/libc.so.6+0x2b444) #12 0x55675831ac in _start (/usr/bin/opkg+0x1e1ac) Direct leak of 16 byte(s) in 2 object(s) allocated from: #0 0x7fb09a2884 in __interceptor_strdup (/lib64/libasan.so.8+0xa2884) #1 0x55675c1818 in xstrdup opkg-master/libopkg/xfuncs.c:71 #2 0x55675b75b0 in file_info_init opkg-master/libopkg/file_list.c:30 #3 0x55675b790c in file_list_append opkg-master/libopkg/file_list.c:78 #4 0x55675a0e30 in pkg_get_installed_files opkg-master/libopkg/pkg.c:1261 #5 0x55675af918 in file_hash_set_file_owner opkg-master/libopkg/pkg_hash.c:923 #6 0x55675d5b34 in update_file_ownership opkg-master/libopkg/opkg_install.c:69 #7 0x55675d9e50 in opkg_install_pkg opkg-master/libopkg/opkg_install.c:964 #8 0x55675d4b84 in libsolv_solver_execute_transaction solvers/libsolv/opkg_solver_libsolv.c:1009 #9 0x55675cf6b8 in opkg_solver_install solvers/libsolv/opkg_solver_libsolv.c:153 #10 0x5567588500 in opkg_install_cmd opkg-master/libopkg/opkg_cmd.c:426 #11 0x556758c514 in opkg_cmd_exec opkg-master/libopkg/opkg_cmd.c:1310 #12 0x5567585ab4 in main opkg-master/src/opkg.c:544 #13 0x7fad80e368 (/lib/libc.so.6+0x2b368) #14 0x7fad80e444 in __libc_start_main (/lib/libc.so.6+0x2b444) #15 0x55675831ac in _start (/usr/bin/opkg+0x1e1ac) Direct leak of 16 byte(s) in 2 object(s) allocated from: #0 0x7fb09a2884 in __interceptor_strdup (/lib64/libasan.so.8+0xa2884) #1 0x55675c1818 in xstrdup opkg-master/libopkg/xfuncs.c:71 #2 0x55675b75b0 in file_info_init opkg-master/libopkg/file_list.c:30 #3 0x55675b790c in file_list_append opkg-master/libopkg/file_list.c:78 #4 0x55675a0e30 in pkg_get_installed_files opkg-master/libopkg/pkg.c:1261 #5 0x55675d8428 in check_data_file_clashes_change opkg-master/libopkg/opkg_install.c:619 #6 0x55675da418 in opkg_install_pkg opkg-master/libopkg/opkg_install.c:1049 #7 0x55675d4b84 in libsolv_solver_execute_transaction solvers/libsolv/opkg_solver_libsolv.c:1009 #8 0x55675cf6b8 in opkg_solver_install solvers/libsolv/opkg_solver_libsolv.c:153 #9 0x5567588500 in opkg_install_cmd opkg-master/libopkg/opkg_cmd.c:426 #10 0x556758c514 in opkg_cmd_exec opkg-master/libopkg/opkg_cmd.c:1310 #11 0x5567585ab4 in main opkg-master/src/opkg.c:544 #12 0x7fad80e368 (/lib/libc.so.6+0x2b368) #13 0x7fad80e444 in __libc_start_main (/lib/libc.so.6+0x2b444) #14 0x55675831ac in _start (/usr/bin/opkg+0x1e1ac) Direct leak of 10 byte(s) in 1 object(s) allocated from: #0 0x7fb09a2884 in __interceptor_strdup (/lib64/libasan.so.8+0xa2884) #1 0x7fad9d0f64 in solv_strdup (/lib/libsolv.so.1+0x44f64) #2 0x7fad9c87d8 in datamatcher_init (/lib/libsolv.so.1+0x3c7d8) #3 0x7fad9c9440 in dataiterator_init (/lib/libsolv.so.1+0x3d440) #4 0x55675cf268 in opkg_solver_install solvers/libsolv/opkg_solver_libsolv.c:110 #5 0x5567588500 in opkg_install_cmd opkg-master/libopkg/opkg_cmd.c:426 #6 0x556758c514 in opkg_cmd_exec opkg-master/libopkg/opkg_cmd.c:1310 #7 0x5567585ab4 in main opkg-master/src/opkg.c:544 #8 0x7fad80e368 (/lib/libc.so.6+0x2b368) #9 0x7fad80e444 in __libc_start_main (/lib/libc.so.6+0x2b444) #10 0x55675831ac in _start (/usr/bin/opkg+0x1e1ac) SUMMARY: AddressSanitizer: 58 byte(s) leaked in 6 allocation(s).
If I install the same pkg over and over again, it goes to libopkg/opkg_download.c:443: if (old_pkg && (pkg_compare_versions(pkg, old_pkg) == 0){ } and doesn't release pkg->provides_str and pkg->replaces_str before return-1. The call stack looks like this: error: opkg_prepare_file_for_install: Refusing to load file 'test/pack_name_0.0.1_aarch64.ipk' as it matches the installed version of pack_name (0.0.1). ================================================================= ==23274==ERROR: LeakSanitizer: detected memory leaks Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7fb332d688 in __interceptor_realloc.part.0 (/lib64/libasan.so.8+0xc7688) #1 0x555cf27974 in xrealloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/xfuncs.c:46 #2 0x555cf25fd4 in parse_list /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:76 #3 0x555cf17f10 in pkg_parse_line /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:256 #4 0x555cf26854 in parse_from_stream_nomalloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:175 #5 0x555cf18b20 in pkg_parse_from_stream /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:351 #6 0x555cf00048 in pkg_init_from_file /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg.c:302 #7 0x555cef4388 in opkg_prepare_file_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:423 #8 0x555cef4de8 in opkg_prepare_url_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:552 #9 0x555ceee6dc in opkg_install_cmd /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:420 #10 0x555cef2754 in opkg_cmd_exec /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:1310 #11 0x555ceebcf4 in main /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/src/opkg.c:544 #12 0x7fb0174368 (/lib/libc.so.6+0x2b368) #13 0x7fb0174444 in __libc_start_main (/lib/libc.so.6+0x2b444) #14 0x555cee93ec in _start (/usr/bin/opkg+0x1e3ec) Direct leak of 16 byte(s) in 1 object(s) allocated from: #0 0x7fb332d688 in __interceptor_realloc.part.0 (/lib64/libasan.so.8+0xc7688) #1 0x555cf27974 in xrealloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/xfuncs.c:46 #2 0x555cf25fd4 in parse_list /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:76 #3 0x555cf18114 in pkg_parse_line /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:269 #4 0x555cf26854 in parse_from_stream_nomalloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:175 #5 0x555cf18b20 in pkg_parse_from_stream /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:351 #6 0x555cf00048 in pkg_init_from_file /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg.c:302 #7 0x555cef4388 in opkg_prepare_file_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:423 #8 0x555cef4de8 in opkg_prepare_url_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:552 #9 0x555ceee6dc in opkg_install_cmd /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:420 #10 0x555cef2754 in opkg_cmd_exec /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:1310 #11 0x555ceebcf4 in main /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/src/opkg.c:544 #12 0x7fb0174368 (/lib/libc.so.6+0x2b368) #13 0x7fb0174444 in __libc_start_main (/lib/libc.so.6+0x2b444) #14 0x555cee93ec in _start (/usr/bin/opkg+0x1e3ec) Indirect leak of 46 byte(s) in 2 object(s) allocated from: #0 0x7fb332e454 in __interceptor_malloc (/lib64/libasan.so.8+0xc8454) #1 0x7fb32f7c40 in __interceptor_strndup.part.0 (/lib64/libasan.so.8+0x91c40) #2 0x555cf27bfc in xstrndup /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/xfuncs.c:89 #3 0x555cf262a8 in parse_list /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:92 #4 0x555cf17f10 in pkg_parse_line /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:256 #5 0x555cf26854 in parse_from_stream_nomalloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:175 #6 0x555cf18b20 in pkg_parse_from_stream /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:351 #7 0x555cf00048 in pkg_init_from_file /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg.c:302 #8 0x555cef4388 in opkg_prepare_file_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:423 #9 0x555cef4de8 in opkg_prepare_url_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:552 #10 0x555ceee6dc in opkg_install_cmd /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:420 #11 0x555cef2754 in opkg_cmd_exec /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:1310 #12 0x555ceebcf4 in main /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/src/opkg.c:544 #13 0x7fb0174368 (/lib/libc.so.6+0x2b368) #14 0x7fb0174444 in __libc_start_main (/lib/libc.so.6+0x2b444) #15 0x555cee93ec in _start (/usr/bin/opkg+0x1e3ec) Indirect leak of 46 byte(s) in 2 object(s) allocated from: #0 0x7fb332e454 in __interceptor_malloc (/lib64/libasan.so.8+0xc8454) #1 0x7fb32f7c40 in __interceptor_strndup.part.0 (/lib64/libasan.so.8+0x91c40) #2 0x555cf27bfc in xstrndup /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/xfuncs.c:89 #3 0x555cf262a8 in parse_list /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:92 #4 0x555cf18114 in pkg_parse_line /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:269 #5 0x555cf26854 in parse_from_stream_nomalloc /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/parse_util.c:175 #6 0x555cf18b20 in pkg_parse_from_stream /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg_parse.c:351 #7 0x555cf00048 in pkg_init_from_file /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/pkg.c:302 #8 0x555cef4388 in opkg_prepare_file_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:423 #9 0x555cef4de8 in opkg_prepare_url_for_install /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_download.c:552 #10 0x555ceee6dc in opkg_install_cmd /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:420 #11 0x555cef2754 in opkg_cmd_exec /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/libopkg/opkg_cmd.c:1310 #12 0x555ceebcf4 in main /home/rk3568/rk3568_linux6.1_b01/buildroot/output/rockchip_rk3568/build/opkg-master/src/opkg.c:544 #13 0x7fb0174368 (/lib/libc.so.6+0x2b368) #14 0x7fb0174444 in __libc_start_main (/lib/libc.so.6+0x2b444) #15 0x555cee93ec in _start (/usr/bin/opkg+0x1e3ec) SUMMARY: AddressSanitizer: 124 byte(s) leaked in 6 allocation(s).
I've fixed it. Please review it. From 96b028cd5eb560928c897adf58903f764d41c914 Mon Sep 17 00:00:00 2001 From: "unintialized@gmail.com" Date: Mon, 3 Mar 2025 16:31:38 +0800 Subject: [PATCH] Fix multiple memory leak issues --- libopkg/file_list.c | 8 +-- libopkg/opkg_download.c | 49 +++++++++++++++++++ libopkg/pkg.c | 6 ++- libopkg/pkg.h | 2 + libopkg/solvers/libsolv/opkg_solver_libsolv.c | 5 +- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/libopkg/file_list.c b/libopkg/file_list.c index 03c3c12..c34758a 100644 --- a/libopkg/file_list.c +++ b/libopkg/file_list.c @@ -90,11 +90,13 @@ static int file_list_cmp(const void *left, const void *right) void file_list_remove_elt(file_list_t *list, const char *path) { - char *str = void_list_remove_elt((void_list_t *)list, + file_info_t *info = void_list_remove_elt((void_list_t *)list, (void *)path, file_list_cmp); - if (str) - free(str); + if (info){ + file_info_deinit(info); + free(info); + } } file_list_elt_t *file_list_first(file_list_t *list) diff --git a/libopkg/opkg_download.c b/libopkg/opkg_download.c index 4086f83..8ed126f 100644 --- a/libopkg/opkg_download.c +++ b/libopkg/opkg_download.c @@ -446,6 +446,55 @@ static int opkg_prepare_file_for_install(const char *path, char **namep) "Refusing to load file '%s' as it matches the installed version of %s (%s).\n", path, old_pkg->name, version); free(version); + if (pkg->provides_count >0){ + for (int i = 0; i < pkg->provides_count; i++) + free(pkg->provides_str[i]); + free(pkg->provides_str); + pkg->provides_count = 0; + } + + if (pkg->conflicts_count >0){ + for (int i = 0; i < pkg->conflicts_count; i++) + free(pkg->conflicts_str[i]); + free(pkg->conflicts_str); + pkg->conflicts_count = 0; + } + + if (pkg->replaces_count >0){ + for (int i = 0; i < pkg->replaces_count; i++) + free(pkg->replaces_str[i]); + free(pkg->replaces_str); + pkg->replaces_count = 0; + } + + if (pkg->pre_depends_count >0){ + for (int i = 0; i < pkg->pre_depends_count; i++) + free(pkg->pre_depends_str[i]); + free(pkg->pre_depends_str); + pkg->pre_depends_count = 0; + } + + if (pkg->depends_count >0){ + for (int i = 0; i < pkg->depends_count; i++) + free(pkg->depends_str[i]); + free(pkg->depends_str); + pkg->depends_count = 0; + } + + if (pkg->recommends_count >0){ + for (int i = 0; i < pkg->recommends_count; i++) + free(pkg->recommends_str[i]); + free(pkg->recommends_str); + pkg->recommends_count = 0; + } + + if (pkg->suggests_count >0){ + for (int i = 0; i < pkg->suggests_count; i++) + free(pkg->suggests_str[i]); + free(pkg->suggests_str); + pkg->suggests_count = 0; + } + pkg_deinit(pkg); free(pkg); return -1; diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 6b1bd8f..5caa8fe 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -93,7 +93,9 @@ static void pkg_init(pkg_t * pkg) pkg->description = NULL; pkg->tags = NULL; pkg->state_want = SW_UNKNOWN; - pkg->wanted_by = pkg_vec_alloc(); +#if HAVE_SOLVER_INTERNAL + // pkg->wanted_by = pkg_vec_alloc(); +#endif pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; pkg->depends_str = NULL; @@ -191,7 +193,9 @@ void pkg_deinit(pkg_t * pkg) pkg->description = NULL; pkg->state_want = SW_UNKNOWN; +#if HAVE_SOLVER_INTERNAL pkg_vec_free(pkg->wanted_by); +#endif pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; diff --git a/libopkg/pkg.h b/libopkg/pkg.h index a62c065..cdbe30c 100644 --- a/libopkg/pkg.h +++ b/libopkg/pkg.h @@ -127,7 +127,9 @@ struct pkg { char *description; char *tags; pkg_state_want_t state_want; +#if HAVE_SOLVER_INTERNAL pkg_vec_t *wanted_by; +#endif pkg_state_flag_t state_flag; pkg_state_status_t state_status; char **depends_str; diff --git a/libopkg/solvers/libsolv/opkg_solver_libsolv.c b/libopkg/solvers/libsolv/opkg_solver_libsolv.c index d152174..dd66a5c 100644 --- a/libopkg/solvers/libsolv/opkg_solver_libsolv.c +++ b/libopkg/solvers/libsolv/opkg_solver_libsolv.c @@ -115,6 +115,8 @@ int opkg_solver_install(int num_pkgs, char **pkg_names) found_match = 1; } + dataiterator_free(&di); + if (!found_match) { /* * pkg wasn't found in repo_available which would be ok if it is present in another repo @@ -130,8 +132,10 @@ int opkg_solver_install(int num_pkgs, char **pkg_names) SOLVABLE_NAME | SOLVABLE_PROVIDES, name, SEARCH_GLOB); if (dataiterator_step(&di)) { found_match = 1; + dataiterator_free(&di); break; } + dataiterator_free(&di); } if (!found_match) { @@ -141,7 +145,6 @@ int opkg_solver_install(int num_pkgs, char **pkg_names) } } - dataiterator_free(&di); free(name); free(version); } -- 2.43.0