Skip to content

log: avoid recursive deletion-message overflow - #1130

Merged
steadytao merged 3 commits into
RsyncProject:masterfrom
tridge:pr-delete-segv
Oct 15, 2026
Merged

steadytao merged 3 commits into
RsyncProject:masterfrom
tridge:pr-delete-segv

Conversation

@tridge

@tridge tridge commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

A quiet daemon receiver queued one MSG_DELETED per path until the generator hit --max-alloc, so skip names the client did not request. If requested output legitimately fills the queue, keep allocator error reporting from re-entering the same buffer and exhausting the stack. Preserve explicit deletion requests across the daemon max-verbosity clamp.

I hit this bug during a large backup that needed to delete a few million files

A quiet daemon receiver queued one MSG_DELETED per path until the generator hit --max-alloc, so skip names the client did not request. If requested output legitimately fills the queue, keep allocator error reporting from re-entering the same buffer and exhausting the stack. Preserve explicit deletion requests across the daemon max-verbosity clamp.
@tridge
tridge requested a review from steadytao October 13, 2026 23:13
@steadytao

Copy link
Copy Markdown
Member

Thank you Andrew.

@AP-Review

Copy link
Copy Markdown

Automated review note — AI-generated (Claude+Codex), validated against the live diff. Please sanity-check before acting.
Verdict: REQUEST CHANGES

Reviewed at head a1455fb797.
Full report: https://firmware.ardupilot.org/Tools/APReview/DevCallReviews/PRReviews/rsyncproject/rsync/1130/1.html#prrsync-1130

Thanks for this. The crash fix works: the new test segfaults on the base commit and passes with the PR, and a verbose --max-alloc overflow now logs one error and exits where base recursed and hung.

One regression needs fixing before merge. The new gate in log_delete() (https://github.com/RsyncProject/rsync/pull/1130/files#diff-cac4c5e540bb96b16908efb139929424aa8065d1acaa0af3791e19aa775bbf42R998) means a server only sends MSG_DELETED when the client asked for stdout deletion output. But the client also uses those messages to write '*deleting' lines to its own --log-file. So a plain rsync -a --delete --log-file=X src/ dst/ (or -q) still deletes files but no longer logs them. I reproduced this against the base commit for local copies, rsh pushes and daemon pushes. Adding -v or --info=del brings the entries back. An unmodified 3.4.1 client talking to a patched server loses them too. Sending the existing --log-format marker from server_options() when --log-file is set fixes new clients on remote pushes only. Local copies (local_child() clears logfile_name) and older clients still lose the entries. So the gate probably needs to keep forwarding deletions whenever the client may be logging to a file, or bound the queue differently. A quiet --log-file deletion test would be worth adding. The NEWS text (https://github.com/RsyncProject/rsync/pull/1130/files#diff-51920e95310ebfbc1ae31709f3b95f89afffbf4f1a6e38e8b2b406e2fb6197eaR6) also limits the change to daemon transfers, but rsh and local copies are affected too.

Minor, no action needed: once the guard at https://github.com/RsyncProject/rsync/pull/1130/files#diff-92194f057884b3287a3a6bf84e6e3b2bf433a556b68562799252a091744e7854R1099 trips on a fatal allocation it stays set, so the client sees a generic code 12 while the daemon log shows the real code 22. It's still a clear improvement on the crash.

@steadytao
steadytao merged commit b70a61f into RsyncProject:master Oct 15, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants