-
-
Notifications
You must be signed in to change notification settings - Fork 323
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
ForkserverExecutor #111
ForkserverExecutor #111
Conversation
ehm, the commit log went messy when I rebased |
libafl/src/executors/forkserver.rs
Outdated
.setlimit(memlimit) | ||
.setsid() | ||
.setstdin(out_filefd, use_stdin) | ||
.setpipe(st_pipe.clone(), ctl_pipe.clone()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need Arc
here, read and write ends are independent of each other
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but if we don't wrap it in Arc then Pipe's drop() would be prematurely called after setpipe
, and following communication through the ctl_pipe and st_pipe won't work.
(and we can't pass normal reference & to Pipe
either)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, ok.
I guess it would simpler to pass 4 RawFds (st_pipe.read_end, st_pipe.write_end, ctl_pipe.read_end, ctl_pipe.write_end) to setpipe, then no Arc is needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it on drop the pipe in the parent after the child got spawned, in which case it is fine, though? Or does it drop before exec, too?
Maybe we need to ManuallyDrop
, then?
In any case we shouldn't need Arc
since we don't have more than 1 access to each side of the pipe I think (worst case, Rc
?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it drops after the forkserver is spawned (so after the match Command::new(target) line) for the parent,
unsafe {
libc::close(ctl_pipe.read_end);
libc::close(st_pipe.write_end);
}
these 2 are safe to close for the parent, but if the Pipe::drop() is called here, the remaining two ends (ctl_pipe.write_end, st_pipe.read_end) would also be closed, and we don't want that.
what we want instead is calling Pipe::drop() when the forkserver dies.
I'll look into ManuallyDrop
.
I tried to use Rc
, but pre_exec
in std::os::unix::process::CommandExt
wants std::marker::Send
, so it didn't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change the Pipe
interface to anything that makes sense.
I feel like we should move out the two ends for the forkserver, so they get dropped in the parent, and keep the respective other ends around in the fs parent, right?
libafl/src/executors/forkserver.rs
Outdated
|
||
fn setpipe(&mut self, st_pipe: Arc<Pipe>, ctl_pipe: Arc<Pipe>) -> &mut Self { | ||
let func = move || { | ||
let ret = unsafe { libc::dup2(ctl_pipe.read_end, FORKSRV_FD) }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a wrapper for dup2
in bolts::os
.
libafl/src/executors/forkserver.rs
Outdated
use crate::inputs::NopInput; | ||
#[test] | ||
fn test_forkserver() { | ||
let command = "/home/toka/work/aflsimple/test"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be cool to have a testcase, but this one can't work, sadly :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes 😄, I think I'll add a simple example binary file and a c source code file along with a example fuzzer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add a libafl-tests
project that can have more complex testcases, such as a short fuzz session, etc.
Committing binaries will break on various platforms, and in various colors. :)
… but trying to figure out other solutions
ah.. I'm sorry, I did not notice that the test code hung up.. (and it has run for around 80 minutes..) |
Hi, thanks for the help andrea!
Yes I was expecting around 3k exec/sec. |
--release |
😲 |
I'd like to add a feature like |
Just add minimial tests to forkserver.rs and do the "real" testing in |
* add Forkserver, Pipe Outfile struct * add forkserver executor struct, and shmem init * close pipes in the destructor of Forkserver * fill pre_exec to write out the inputs * fix * read_st, write_ctl * more handshakes * wrap Pipe in Arc, fill post_exec * add Forkserver, Pipe Outfile struct * add forkserver executor struct, and shmem init * close pipes in the destructor of Forkserver * fill pre_exec to write out the inputs * fix * read_st, write_ctl * more handshakes * wrap Pipe in Arc, fill post_exec * fix for the lastest HasExecHooks trait * use Dominik's pipe, remove Arc and temporarily pass RawFd to setstdin but trying to figure out other solutions * add libafl_tests, put a very simple vulnerable program * fix * added forkserver_simple (mostly copy-pasted from babyfuzzer) * fix test * handle crash in post_exec * add README.md * check exec time to see why it's so slow * remove double invokation of is_interesting for the obejctive * make forkserver_simple AFL-like and improve speed * some debugging help * do not evaluate feedback if solution * speedup the things * working input placement via stdin in Forkserver * don't call panic! but return errors, rewrite some comments * use AFLplusplus/afl-cc instead of AFL * use .cur_input like AFL * bring the test for forkserver back * add better README.md message * failing the initial handshake should return an error * delete some commented-out code * format * format * ForkserverExecutor needs std and is unix-only for now * clippy * OutFile error handling * fmt * clippy * don't build libafl_tests on windows * fix * keep test in forkserver.rs simple * add forkserver_test feature for libafl_tests * format * some doc Co-authored-by: Andrea Fioraldi <[email protected]>
#82
Only the ForkserverExecutor, still WIP
TODO:
Pipe
made by Dominik.StdShMemProvider::new()
) outside theExecutor
?, because the Observer needs that address.ForkserverExecutor