Added --simulate-keep-chroot option to keep the changes chroot after a run - #6293
Added --simulate-keep-chroot option to keep the changes chroot after a run#6293djbclark wants to merge 1 commit into
Conversation
0ff86ae to
00c98bc
Compare
…ut three SHAs
Chasing one stale SHA in the P-3 row turned up a much larger error: this
register opened by asserting that every upstream channel was closed and
that "nothing is filed on an upstream tracker yet". Both were false.
Verified against the GitHub API, not restated from these notes:
- NorthernTechHQ/libntech has issues ENABLED (has_issues: true). The
claim that they were disabled was simply wrong, and our own issue
#290 has been sitting there since 2026-08-15.
- Three items are already live upstream, all opened by the operator
on the evening of 2026-08-15 and never recorded here: P-1 as
cfengine/core#6293, P-2 as #6294, P-3 as libntech#290 (issue) plus
#291 (PR). All open, mergeable, CLA signed.
- cfengine/core issues really are disabled; that part was right.
So the premise behind the fork-plus-email workaround does not hold for
ordinary bug reporting. Email stays correct for security-relevant items
and the fork stays correct for work not ready for maintainers, but "we
cannot file upstream" is no longer a reason available to us.
All three P-item SHAs were stale in the same way: the commit was amended
after the SHA was written down, leaving the citation pointing at a commit
no branch reaches. Content was identical every time -- only the message
differed -- so every diff-based check passed. P-1 5dbd295f6 -> 00c98bc8b,
P-2 071f85987 -> 8ee015c42, P-3 da7d3d9 -> dc85a6f. Recorded the
`git branch --contains` check that catches it.
Two further findings, both recorded rather than acted on:
- P-1 and P-2 carry `Ticket: #6295` and `Ticket: #6296`, and neither
number exists (both 404). Repairing it means force-pushing branches
that live upstream PRs are built on, so it needs the operator.
- libntech#291 has a mender-test-bot pipeline error but no check
status at all, so it is not evidence our patch passes CI either way.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ea439e0 to
64e2ac1
Compare
|
Apologies for the force-push churn on this branch — the commit metadata is now correct, and this is what moved and why. The commit originally carried So No code changed in either direction. The tree is byte-identical to what you have already seen; both rewrites touched only the commit message, and I verified the tree hashes match before pushing. Still one commit. |
|
Please hold off merging this — a review I commissioned has found a buffer overflow in it, and a correction is coming. Flagging now rather than waiting until I have the fix written, so nobody spends time merging it meanwhile. The defect. The only validation on strncpy(chrooted_path + chroot_len + offset, orig_path,
(PATH_MAX - chroot_len - offset - 1));With The Below that threshold the same bound truncates silently, so two distinct source paths can map to the same chroot path — which matters here specifically, because the tree holds permission-mirrored copies of real system files. Two other things in the same change that I got wrong, which I'll fix in the same correction:
I'd rather say all of this myself than have a reviewer find it. The correction will be a force-push to this branch with the fix and tests; I'll comment again when it's up. |
|
Now tracked in Jira as CFE-4715. We couldn't reach the CFE tracker when this PR went up, which is why the commit trailer points at discussion #6295. That's now resolved (creating the Atlassian account wasn't sufficient on its own — I also needed permission in the project itself; thanks to @nickanderson for sorting that out). The Going forward all our CFEngine/libntech reports will go to Jira rather than email or new discussions. |
…a run The changes chroot created by a --simulate run was always deleted by a cleanup handler on exit, so the files as they would be after the run could never be inspected by the user or consumed by another program. With --simulate-keep-chroot=PATH, cf-agent creates the changes chroot at PATH instead of in the state directory and keeps it after the run. The path has to be absolute and is required to not exist yet, and it is created by cf-agent itself with mode 0700 enforced by an explicit chmod() -- mkdir()'s mode argument is masked by umask, so under a restrictive umask mkdir(path, 0700) alone yields a directory the operator cannot even enter. The copies of potentially sensitive system files can therefore neither mix with the contents of a previous run nor be made anywhere but in a directory this process created. cf-agent additionally refuses to create the tree inside a parent directory writable by group or others without the sticky bit set, so that another user cannot swap the directory for one of their own or pre-seed its contents. Requiring an explicit destination also means that no PID-named trees can pile up in the state directory behind the operator's back, and that a calling program knows where the retained tree is without parsing any output. The keep path is bounded so that roughly half of the PATH_MAX budget stays available for the paths mapped into the chroot, and mapping a path that still does not fit aborts the run instead of truncating it: a truncated path would place the copy somewhere other than the location recorded and reported for it, and two long paths could be mapped onto the same copy. The retained tree itself is the artifact of record: the files under it as they would be on the host after the run. The record files at the root of the chroot (changed_files, renamed_files, kept_files and pkgs_ops) remain an internal, unstable format. Retention is announced with a notice-level message at the very end of the run. The default behavior without the new option is unchanged: the chroot is created in the state directory and deleted on exit. Changelog: Title Ticket: CFE-4715
64e2ac1 to
f6c06f9
Compare
|
The fixes are up — this supersedes the hold-off-merging notice above. Force-pushed to Every defect listed in that notice is fixed, and the review that produced it found two more things on the way in:
Two further defects found while fixing the above, neither of them in the original report:
TestsThree new acceptance tests in They were checked for discrimination rather than assumed: with the source changes stashed, all three acceptance tests fail and the unit case reports Full suite: On the ASan verification, preciselyThe pre-fix The |
Added --simulate-keep-chroot option to keep the changes chroot after a run
The changes chroot created by a --simulate run was always deleted by a
cleanup handler on exit, so the files as they would be after the run
could never be inspected by the user or consumed by another program.
With --simulate-keep-chroot=PATH, cf-agent creates the changes chroot
at PATH instead of in the state directory and keeps it after the run.
The path has to be absolute and is required to not exist yet, and it
is created with mode 0700, so that the permission-mirrored copies of
potentially sensitive system files can neither land in a directory
prepared with looser permissions nor mix with the contents of a
previous run. Requiring an explicit destination also means that no
PID-named trees can pile up in the state directory behind the
operator's back, and that a calling program knows where the retained
tree is without parsing any output.
The retained tree itself is the artifact of record: the files under it
as they would be on the host after the run. The record files at the
root of the chroot (changed_files, renamed_files, kept_files and
pkgs_ops) remain an internal, unstable format.
Retention is announced with a notice-level message at the very end of
the run. The default behavior without the new option is unchanged: the
chroot is created in the state directory and deleted on exit.
Requested in #6295.