[Question] Memory corruption in apk_changeset/apk_solver_solve
Hello,
I'm currently trying to get a list of packages from libapk. For that I'm currently getting a changeset like so (sorry that it's in D, I hope it's understandable nonetheless):
apk_changeset getAllUpgradeChangeset(ushort solverFlags = 0)
{
apk_changeset changeset;
enforce(apk_db_check_world(&this.db, this.db.world) == 0,
"Missing repository tags; can't continue the upgrade!");
const auto solverSolveRes = apk_solver_solve(&this.db,
APK_SOLVERF_UPGRADE | solverFlags, this.db.world, &changeset);
enforce!ApkSolverException(solverSolveRes == 0,
format("Failed to calculate dependency graph due to error '%s'!",
apk_error_str(solverSolveRes).to!string));
return changeset;
}
I then use that changeset like so:
ApkPackage[] getUpgradablePackages()
{
ApkPackage[] packages;
auto changeset = this.getAllUpgradeChangeset();
for (auto iter = &changeset.changes.item[0]; iter < &changeset.changes
.item[changeset.changes.num]; iter++)
{
if (iter.new_pkg is null || iter.old_pkg is null)
{
continue;
}
if (apk_pkg_version_compare(iter.new_pkg,
iter.old_pkg) & (APK_VERSION_GREATER | APK_VERSION_EQUAL)
&& (iter.new_pkg != iter.old_pkg))
{
auto newPackage = iter.new_pkg;
auto oldPackage = iter.old_pkg;
auto apkPackage = ApkPackage(*oldPackage, *newPackage);
packages ~= apkPackage;
}
}
return packages;
}
However, even though I check that both iter.new_pkg and iter.old_pkg aren't null my program is SIGSEGVing as of now. Valgrind tells me this:
==26671== Invalid read of size 8
==26671== at 0x56A3767: apk_pkg_version_compare (package.c:1168)
==26671== by 0x4CD733E: _D4apkd11ApkDataBaseQn21getUpgradablePackagesMFZASQBw10ApkPackageQm (ApkDataBase.d:128)
==26671== by 0x16F237: _D16apkd_dbus_server10DBusServer13ApkInterfacer21getUpgradablePackagesFZAS4apkd10ApkPackageQm (DbusServer.d:317)
==26671== by 0x16A581: _D16apkd_dbus_server10DBusServerQm13methodHandlerUPS3gio1c5types15GDBusConnectionxPaxQdxQgxQjPS4glibQBsQBt8GVariantPSQCnQCmQCn21GDBusMethodInvocationPvZv (DbusServer.d:102)
==26671== by 0x590252F: call_in_idle_cb (gdbusconnection.c:4888)
==26671== by 0x570CB71: g_main_dispatch (gmain.c:3309)
==26671== by 0x570CB71: g_main_context_dispatch (gmain.c:3974)
==26671== by 0x570CDD9: g_main_context_iterate.isra.0 (gmain.c:4047)
==26671== by 0x570D11F: g_main_loop_run (gmain.c:4241)
==26671== by 0x4F0D168: _D4glib8MainLoopQj3runMFZv (in /usr/lib/libglibd-2.0.so.2.1.0)
==26671== by 0x151C55: _Dmain (main.d:52)
==26671== by 0x561688F: _D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv (in /usr/lib/libdruntime-ldc-shared.so.2.0.90)
==26671== by 0x561669E: _d_run_main2 (in /usr/lib/libdruntime-ldc-shared.so.2.0.90)
==26671== Address 0x9 is not stack'd, malloc'd or (recently) free'd
==26671==
==26671==
==26671== Process terminating with default action of signal 11 (SIGSEGV)
==26671== Access not within mapped region at address 0x9
==26671== at 0x56A3767: apk_pkg_version_compare (package.c:1168)
==26671== by 0x4CD733E: _D4apkd11ApkDataBaseQn21getUpgradablePackagesMFZASQBw10ApkPackageQm (ApkDataBase.d:128)
==26671== by 0x16F237: _D16apkd_dbus_server10DBusServer13ApkInterfacer21getUpgradablePackagesFZAS4apkd10ApkPackageQm (DbusServer.d:317)
==26671== by 0x16A581: _D16apkd_dbus_server10DBusServerQm13methodHandlerUPS3gio1c5types15GDBusConnectionxPaxQdxQgxQjPS4glibQBsQBt8GVariantPSQCnQCmQCn21GDBusMethodInvocationPvZv (DbusServer.d:102)
==26671== by 0x590252F: call_in_idle_cb (gdbusconnection.c:4888)
==26671== by 0x570CB71: g_main_dispatch (gmain.c:3309)
==26671== by 0x570CB71: g_main_context_dispatch (gmain.c:3974)
==26671== by 0x570CDD9: g_main_context_iterate.isra.0 (gmain.c:4047)
==26671== by 0x570D11F: g_main_loop_run (gmain.c:4241)
==26671== by 0x4F0D168: _D4glib8MainLoopQj3runMFZv (in /usr/lib/libglibd-2.0.so.2.1.0)
==26671== by 0x151C55: _Dmain (main.d:52)
==26671== by 0x561688F: _D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv (in /usr/lib/libdruntime-ldc-shared.so.2.0.90)
==26671== by 0x561669E: _d_run_main2 (in /usr/lib/libdruntime-ldc-shared.so.2.0.90)
In package.c
line 1168 apk tries to do return apk_version_compare_blob(*a->version, *b->version);
, so I suppose a/b->version can't is an invalid pointer.