commit: 293754acdf7c60616a7298ecfa21dc2d8124849e
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 26 19:07:12 2026 +0000
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
CommitDate: Mon Jan 26 19:49:53 2026 +0000
URL: https://gitweb.gentoo.org/proj/portage-utils.git/commit/?id=293754ac
qlop: fix possible leak when unsuccessfully running -r, CID 557213
Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
qlop.c | 27 ++++++++++++++++++---------
1 file changed, 18 insertions(+), 9 deletions(-)
diff --git a/qlop.c b/qlop.c
index b7f77698..eabf1ddc 100644
--- a/qlop.c
+++ b/qlop.c
@@ -1518,6 +1518,7 @@ static array *probe_proc(array *atoms)
} else {
/* flag /proc doesn't exist */
warn("/proc doesn't exist, running merges are based on
heuristics");
+ array_deepfree(ret_atoms, (array_free_cb *)atom_implode);
return NULL;
}
@@ -1529,29 +1530,37 @@ static array *probe_proc(array *atoms)
if (geteuid() != 0) {
warn("insufficient privileges for full /proc access, "
"running merges are based on
heuristics");
+ array_deepfree(ret_atoms, (array_free_cb
*)atom_implode);
return NULL;
}
}
if (array_cnt(atoms) > 0) {
- size_t j;
depend_atom *atomr;
+ size_t j;
+ bool found;
/* calculate intersection */
- array_for_each(atoms, i, atom) {
- array_for_each(ret_atoms, j, atomr) {
- if (atom_compare(atomr, atom) != EQUAL) {
- array_remove(ret_atoms, j);
- atom_implode(atomr);
+ array_for_each_rev(atoms, i, atom)
+ {
+ found = false;
+ array_for_each(ret_atoms, j, atomr)
+ {
+ if (atom_compare(atomr, atom) == EQUAL)
+ {
+ found = true;
break;
}
}
- atom_implode(atom);
+ if (found)
+ array_delete(ret_atoms, j, (array_free_cb
*)atom_implode);
+ else
+ array_delete(atoms, i, (array_free_cb
*)atom_implode);
}
}
- /* ret_atoms is allocated on the stack, so copy into atoms which is
- * empty at this point */
+ /* caller expects us to return atoms or NULL, so copy ret_atoms
+ * contents to atoms */
array_for_each(ret_atoms, i, atom)
{
/* bug #731122: match running packages without version */