Skip to content

Remove *_child variants of pre_exec/post_exec hooks#3817

Open
0xmuon wants to merge 2 commits intoAFLplusplus:mainfrom
0xmuon:duplicate
Open

Remove *_child variants of pre_exec/post_exec hooks#3817
0xmuon wants to merge 2 commits intoAFLplusplus:mainfrom
0xmuon:duplicate

Conversation

@0xmuon
Copy link
Copy Markdown
Contributor

@0xmuon 0xmuon commented Apr 23, 2026

Description

Removed all duplicates that I could find.(can you point out other duplicates that I missed? @addisoncrump )
After removing a duplicate implementation, build started failing because run_target was no longer invoking the observers’ pre_exec/post_exec callbacks, which meant things relying on those hooks (stdout/stderr capture observers that finalize reads in post_exec) break. So, I explicitly added the missing pre_exec_all and post_exec_all calls around execute_input_with_command, so observers are always notified at the right time and executor behaves correctly.
fix: #2445

Checklist

  • I have run ./scripts/precommit.sh and addressed all comments

Copy link
Copy Markdown
Member

@addisoncrump addisoncrump left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some parts of this are wrong in ways I'm not sure how to handle, because the _child functions are all seemingly misused.

@tokatoka, I see no evidence that we have any _child functions in the whole codebase that do anything. Safe to remove this from the API? It seems to be just incorrectly used everywhere.

Comment thread crates/libafl/src/executors/command.rs Outdated
Comment on lines +447 to +451
self.observers_mut().pre_exec_all(state, input)?;
let exit_kind = self.execute_input_with_command(fuzzer, state, input)?;
self.observers_mut()
.post_exec_all(state, input, &exit_kind)?;
Ok(exit_kind)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not correct; the fuzzer is responsible for invoking pre_ and post_exec on observers. This should be pre_ and post_exec_child, but confusingly, these would not be executed in a child process anyways...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah,will revert to just calling execute_input_with_command since the fuzzer handles observer pre/post.

Comment on lines -1537 to -1540
self.observers_mut().pre_exec_child_all(state, input)?;
let exit = self.execute_input(state, bytes.as_slice())?;
self.observers_mut()
.post_exec_child_all(state, input, &exit)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is also not correct; pre_ and post_exec_child is to be executed by the child. However, the original code also appears to be wrong because this code gets executed in the parent. @domenukk / @tokatoka / @andreafioraldi, can you give indication here as to the intended behaviour?

) -> Result<ExitKind, Error> {
use wait_timeout::ChildExt;

self.observers_mut().pre_exec_all(state, input)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... was this ever correct? I presume this is meant to be pre_exec_child_all, but has the same problem as the other region I highlighted.

@addisoncrump
Copy link
Copy Markdown
Member

Following a conversation with the other LibAFL folks, we've decided to entirely remove the _child variants of pre_ and post_exec.

@0xmuon
Copy link
Copy Markdown
Contributor Author

0xmuon commented Apr 23, 2026

oh sure, I will remove _child variants from observer trait, ObserversTuple, all the override sites in stdio, stacktrace, map, hitcount_map, oom, differential + the inprocess_fork child-side call sites,as of what i see.
Need a lil time to work through it and verify across the affected executors.

@addisoncrump
Copy link
Copy Markdown
Member

Are you sure you want to handle that? I was planning to do so myself, but if you think you've got it, go for it.

@0xmuon
Copy link
Copy Markdown
Contributor Author

0xmuon commented Apr 23, 2026

I will try my best and will ask wherever needed...

@0xmuon
Copy link
Copy Markdown
Contributor Author

0xmuon commented Apr 24, 2026

after the removal, command.rs::tests::test_capture failed: executor.observers.0.output was None.
my take is that StdOutObserver uses an fd-backed capture on linux and macos and only copies bytes into output during post_exec. The old CommandExecutor::run_target was calling pre_exec_all / post_exec_child_all itself, inconsistent with every other executor, where the fuzzer drives observer.So, I removed those internal calls so CommandExecutor matches the rest. test_capture is the only caller that invokes run_target directly without a fuzzer, so nothing was running the hooks anymore.

@0xmuon
Copy link
Copy Markdown
Contributor Author

0xmuon commented Apr 25, 2026

hmm, i don't think the forkserver/libafl-fuzz test fail has occured due to removal of _child observer variant.

thread 'main' panicked at src/main.rs:201:19:
internal error: entered unreachable code

let res = run_client(None, mgr, &fuzzer_dir, CoreId(0), &opt, true);
res
};
match res {
Ok(()) => unreachable!(),
Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."),
Err(err) => panic!("Failed to run launcher: {err:?}"),
}

and the test_unicorn_mode (gitlab.com 503 during AFL++ submodule clone) failed due to gitly outage

@0xmuon 0xmuon changed the title Draft: Review code duplication between {pre,post}_exec{,_child} Remove *_child variants of pre_exec/post_exec hooks Apr 25, 2026
@0xmuon 0xmuon marked this pull request as ready for review April 25, 2026 12:04
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.

Review code duplication between {pre,post}_exec{,_child}

2 participants