The cost
Both helpers now audit twice per package, and after #6 that is a change for yay users in particular:
| helper |
phase |
argv |
before #6 |
after #6 |
| yay |
fetch |
--nobuild -f -C |
skip |
audit |
| yay |
build |
-f --noconfirm --noextract --noprepare --holdver -c |
audit |
audit |
| paru |
fetch |
-ofA -C |
audit |
audit |
| paru |
build |
-feA --noconfirm --noprepare --holdver -c |
audit |
audit |
So yay goes from one audit per package to two, and paru stays at two. #6 closed a real hole to get there — the fetch phase runs prepare() and pkgver(), and skipping it meant the audit landed after maintainer code had already executed — but the second audit is pure waste and should go.
Why the second audit is provably redundant
maintainer_files() is git ls-files on the AUR clone. Extraction into src/ does not change the review set, so the fetch-phase audit and the build-phase audit read a byte-identical file set, send an identical prompt, and bill twice for the same answer. Auditing the earliest code-executing invocation is sufficient: later phases introduce no maintainer file the first pass did not already see.
Shape
Key on the package directory plus a hash of the maintainer file contents, with a short TTL. The hash is what makes it safe for the package under audit: changing any reviewed file changes the key and forces a re-audit, so a maintainer cannot edit past a cached pass.
The objection raised on #6 is worth recording: a cache the user can write is a cache a malicious package() can write, since package() runs under fakeroot, which fakes uid without confining the filesystem — so a previously-installed hostile package could plant a "safe" entry for a package it anticipates. True, but that attacker already has arbitrary code execution as the user and can equally overwrite aur-sleuth, the wrapper, or PATH. The cache is not surface they lack. Worth stating explicitly in whatever lands, because it will be asked again.
Not this
Do not solve it by widening the skip list again. Which makepkg invocations may skip is settled in bench/test-makepkg-wrapper.sh against the real argv both helpers pass, and the answer is "only what exits before extraction". Deduplication has to sit beside that decision, not inside it.
Separately
bench/synthetics/ has no fixture for the wrapper's end-to-end path, so nothing catches a regression in which invocation gets audited on a real helper run. The new suite covers the decision; it does not cover the plumbing.
The cost
Both helpers now audit twice per package, and after #6 that is a change for yay users in particular:
--nobuild -f -C-f --noconfirm --noextract --noprepare --holdver -c-ofA -C-feA --noconfirm --noprepare --holdver -cSo yay goes from one audit per package to two, and paru stays at two. #6 closed a real hole to get there — the fetch phase runs
prepare()andpkgver(), and skipping it meant the audit landed after maintainer code had already executed — but the second audit is pure waste and should go.Why the second audit is provably redundant
maintainer_files()isgit ls-fileson the AUR clone. Extraction intosrc/does not change the review set, so the fetch-phase audit and the build-phase audit read a byte-identical file set, send an identical prompt, and bill twice for the same answer. Auditing the earliest code-executing invocation is sufficient: later phases introduce no maintainer file the first pass did not already see.Shape
Key on the package directory plus a hash of the maintainer file contents, with a short TTL. The hash is what makes it safe for the package under audit: changing any reviewed file changes the key and forces a re-audit, so a maintainer cannot edit past a cached pass.
The objection raised on #6 is worth recording: a cache the user can write is a cache a malicious
package()can write, sincepackage()runs under fakeroot, which fakes uid without confining the filesystem — so a previously-installed hostile package could plant a "safe" entry for a package it anticipates. True, but that attacker already has arbitrary code execution as the user and can equally overwriteaur-sleuth, the wrapper, or PATH. The cache is not surface they lack. Worth stating explicitly in whatever lands, because it will be asked again.Not this
Do not solve it by widening the skip list again. Which makepkg invocations may skip is settled in
bench/test-makepkg-wrapper.shagainst the real argv both helpers pass, and the answer is "only what exits before extraction". Deduplication has to sit beside that decision, not inside it.Separately
bench/synthetics/has no fixture for the wrapper's end-to-end path, so nothing catches a regression in which invocation gets audited on a real helper run. The new suite covers the decision; it does not cover the plumbing.