Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qlop: Properly handle atom_compar_cb when called from qsort #26

Merged
merged 1 commit into from
Mar 29, 2024

Conversation

bstaletic
Copy link
Contributor

This pull request resolves an improper call to qsort when invoking qlop -p.
On current master it can lead to SEGFAULTs.

Detailed description is in the commit message.

Specific example of the SEGFAULT:

bstaletic@Gallifrey ~ % head -n 15 /var/lib/portage/world
app-admin/doas
app-admin/eclean-kernel
app-admin/sysklogd
app-alternatives/sh
app-arch/zip
app-editors/vim
app-eselect/eselect-python
app-eselect/eselect-repository
app-misc/asciinema
app-misc/jq
app-misc/tmux
app-portage/cpuid2cpuflags
app-portage/eix
app-portage/gentoolkit
app-portage/pfl
bstaletic@Gallifrey ~ % qlop -p `head -n 15 /var/lib/portage/world`
zsh: segmentation fault  qlop -p `head -n 15 /var/lib/portage/world`

It should be easier to hit the SEGFAULT with atoms that have versions. Or that might have been just my luck.

Not sure what the proper test would look like. Ideally, ASAN would be used in CI, but I see that #19 is still in progress.

`qsort` passes pointers to elements ("iterators" in C++ lingo) to the
callback, not elements directly.
Hence `l` and `r` in `atom_compar_cb` actually receives `depend_atom**`,
but only when called from `qsort`. The other two call sites
(`tree_pkg_compar` and `pkg_sort_cb`) actually apssed `depend_atom*`.

This leads to type casting confusion and undefined behaviour for any
invocation of `qlop -p`.

First discovered by SEGFAULT-ing with the following invocation:

    qlop -p `cat /var/lib/portage/world`

Valgrind and ASAN made triggering the SEGFAULT easier - any invocation
with two or more atoms triggered a NULL dereference.

This commit addresses the above problem:

1. Expect that `atom_compar_cb` is actually called with two
   `depend_atom**`.
2. Make `tree_pkg_compar` and `pkg_sort_cb` comply with the above
   change, by passing  `&al` and `&ar`, instead of `al` and `ar`.
@bstaletic bstaletic mentioned this pull request Mar 28, 2024
@bstaletic
Copy link
Contributor Author

The coverity failure in CI seems unrelated to my changes.

bstaletic added a commit to bstaletic/portage-utils that referenced this pull request Mar 28, 2024
Previously, `values_set(merge_averages, avgs)` would allocate `avgs`,
then it would be used in `array_for_each(atoms, i, atom)`, but a call to
`xarrayfree_int(avgs)` was missing after the loop.

Hopefully, this, along with gentoo#26, will solve the issues from gentoo#19.
@grobian
Copy link
Member

grobian commented Mar 29, 2024

nice catch

@grobian grobian merged commit 6d70873 into gentoo:master Mar 29, 2024
11 of 12 checks passed
gentoo-bot pushed a commit that referenced this pull request Mar 29, 2024
Previously, `values_set(merge_averages, avgs)` would allocate `avgs`,
then it would be used in `array_for_each(atoms, i, atom)`, but a call to
`xarrayfree_int(avgs)` was missing after the loop.

Hopefully, this, along with #26, will solve the issues from #19.

Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants