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
Stuck at "Performing pilot run" #20
Comments
Ok, so it seems I wasn't patient enough... After 15 minutes the AFL screen popped up. But it doesn't really update at all:
I'm actually missing the -t flag, can I somehow specify the timeout it should use? |
The GUI hasn't moved for half an hour. I mean there will for sure be files that could DoS and hang the application, so I don't know how you tackle hangs, but this doesn't seem to work for me. |
Hi Floyd, You do not need to be so patient; something is definitely wrong. Typically, it takes like 1-2 seconds for the AFL screen to pop up on most benchmarks for me. I'm not sure if this is related, but I pushed a change 3 days ago to prevent some issues with getting stuck for true random bytes from As for verbosity, you can give the For debugging your issue I'd ask you to try two things:
/opt/jqf/bin/jqf-afl-fuzz -vc $(/opt/jqf/scripts/classpath.sh) edu.berkeley.cs.jqf.examples.jdk.DateFormatterTest fuzzSimple Date-format fuzzing should run at anywhere between 500/sec to 4,000/sec depending on your hardware and OS. If you get "zzz" for this let me know.
public void main(byte @Size(max=200)[] arg) throws IOException, CustomExceptionOne, CustomExceptionTwo {
/*.. or simply prevent the parser from reading more than X bytes some other way ..*/
} If item 1 works but item 2 does not, then it could just be the parser taking a very long time to execute. JQF does not handle hangs at all at this point, which is a limitation (mainly because we are interested in unit tests and not long-running programs). I'm trying to find good ways to kill running threads preemptively without breaking too much ( |
Thanks for the detailed response! First of all the good news, I let the "stuck" fuzzer run for a couple of days and it seems to have worked kind of. Also the UI seems to update every other minute or so:
But something went wrong with the "paths", it doesn't seem to find any paths. Also, the crashes are not crashing the target, so it didn't work properly. I actually wonder where these crashes are coming from, maybe some high CPU load glitches. Then another information I forgot to say: I'm running on ARM (odroid u3, quad core 1.7GHz with 2GB ram, CPU cores are idling before I start jqf). Although that shouldn't matter because we are fuzzing java and fuzz/src/main/c/afl-proxy.c seems to compile just fine. Let me know if anything else architecture dependent comes to mind. I went on and git pulled your changes as you suggested and ran make and mvn package -DskipTests. Then I ran my fuzzing run again, but with -v argument. However, jqf was just stuck for several minutes and didn't write a jqf.log during that time, I searched everywhere for it :( . When I aborted I got:
So I ran the test you suggested:
Although it works it took about 6 minutes until the AFL UI came up (I stopped it right away when it came up). That's far away from the 1-2 seconds you have. I could imagine that it would take a couple of seconds more on an ARM, but 6 minutes is really surprising. I reran the tests to see how the AFL speed is and I got only about 4.00/sec. At the moment I don't have a clue why the performance is so ridiculously bad, even when only one CPU core is used. Maybe the JVM ARM implementation is simply that bad. Maybe I'll try the Oracle JVM or so and I would let you know. |
Just did a quick check and actually the DateFormatterTest and my target run just fine on my macbook, without any modifications. Ok, my target is still slow (around 5 execs/s), but it comes up really quickly. So it must be something on that ARM machine that makes it suuuper slow. |
Ahh, thanks for the feedback. I do not have access to any ARM-based machines at this time (other than smartphones), so I have not tested JQF on that platform. I don't think there is anything specifically in JQF that is x86-specific. As you mentioned, it is possibly the difference in the JVM implementation. JQF obviously performs lots of bytecode instrumentation, whose performance overheads can only be alleviated by an aggressively optimizing JIT compiler (e.g. HotSpot on x86). I do not know if the ARM-backend of HotSpot has some surprising gotchas. |
Wow, ok, the problem is OpenJDK rather than ARM probably. Or a combination of OpenJDK+ARM. So basically I uninstalled OpenJDK and installed Oracle Java and it works fine on ARM! So the only things I tested so far: Bad: ARM+OpenJDK So maybe you want to write it in your documentation that Oracle Java should be used? Anyone successfully used OpenJDK on a regular x86 Linux before? |
Ok so now that the performance problems are fixed, I still have the issue that it doesn't find any paths:
When I check jqf.log I only see hundreds of:
I think my target is simply too complicated and something goes wrong in the instrumentation? |
Hi Floyd. Regarding performance: all my tests have been run on OpenJDK on Linux/x86 (which is also how we found bugs in OpenJDK 9). To augment your findings:
So I guess the only bad combination that we know of is ARM/OpenJDK -- perhaps OpenJDK is not optimized for ARM? I know that Oracle Java uses basically the same source code as OpenJDK plus some OS/hardware-specific tweaks. Maybe that makes a much bigger difference on ARM. I'll try to look into this in more detail. |
Since we are now using synchronous instrumentation since e88c800, we do not need to maintain a per-thread call stack. However, removing the single-thread assumption makes this guidance thread-unsafe as we do not use synchronization to coordinate coverage across difference threads. The removal of volatile fields may speed up some issues reported in #20.
Regarding your other issue of no paths and invalid entry points, I believe the root cause is that your test program is multi-threaded. The exceptions you were seeing were a result of a bug in JQF for not correctly finding the However, while my fix gets rid of the exceptions you were seeing and also instruments the child thread, there are some issues with using multi-threading and AFL that you should be aware of:
Some of my recent changes may also improve performance of multi-threaded targets a bit (due to removal of a |
Ok, so I've pulled the changes and the Thread error messages are gone. I'm actually fuzzing a Java library and only wrote the SilentDriver.java myself that is using the library. So I wasn't aware that the library was using multiple threads. So I could try to The error I get now:
About the performance: I don't think the speed is correct when the above problem occurs, but it seemed to be a little faster now (around 20 execs/s) |
Good to know that the thread-running exceptions are gone. Did you see any increase in the number of paths after the last change? Unfortunately, the final error you see appears to be an instrumentation issue that would be quite challenging for me to debug without access to the actual class file that caused it, but I'm sure that this is platform independent (i.e. that particular class file will reliably error out this way). I haven't been able to reproduce that error with any of the libraries I've instrumented so far (such as subsets of OpenJDK, Apache Commons, Maven, Struts and Tomcat, among others). If you cannot share the class file for which this occurred, it may take some time before I can get to the bottom of this. I'll update this thread if I do manage to reproduce it (and hopefully fix it). As always, thanks for your continued feedback! |
Unfortunately I saw no new paths discovered after the last change. The error that appears is probably the same as the Kelinci fuzzer had, as both your project and Kelinci use this org.objectweb.asm for instrumentation. There are certain limitations there, such as https://github.com/isstac/kelinci/blob/master/instrumentor/src/main/java/edu/cmu/sv/kelinci/instrumentor/Instrumentor.java#L67 and already discussed here as well: isstac/kelinci#2 Is there any possibility that you could catch instrumentation errors, warn the user that certain classes could not be instrumented, but then simply go on and use the non-instrumented classes? The issue is I haven't done coordinated disclosure for various bugs I already found with Kelinci and therefore I would not like to disclose the target for now... and unfortunately I have another research project I have to do first... I hope you understand. |
Ok, so here's the challenge for you I'm now able to disclose: Instrument tika-app.jar of the Apache Tika project https://tika.apache.org/ |
Addresses "no paths found" reported in #20.
That's very useful info! I'm testing a driver with the It's a very interesting benchmark because there are 3 distinct problems which I have not encountered in any other target so far:
I've added the TIKA parser benchmark to the JQF repository, and I can see steady progress in the coverage and number of paths when using AFL's bundled seeds of all formats:
The above can be run with the following BASH command: ./bin/jqf-afl-fuzz -i examples/src/test/seeds/afl-all-testcases/ -v -c $(./scripts/examples_classpath.sh) edu.berkeley.cs.jqf.examples.tika.TikaParserTest fuzz It's still quite slow, but that's to be expected from a large code-base such as TIKA. Thanks for helping me find so many bugs! If you don't mind I'd like to add you to the list of contributors for the project :-) |
Thanks for the response and the amazing fast bug fixes! I'm running the benchmark test you added and it works! But it is even much slower on my older ARM boxes (1.26/sec). I'm currently running the benchmark, but with a much larger corpus. Oh btw. if you are interested what was found with Kelinci for Tika 1.17, this should be feasible for JQF to find if it would use Tika 1.17: Thanks for including me in the contributors, of course I don't mind. I opened a couple of other issues for things I would like to discuss, but I think it is time now to close this issue as you managed to get Tika working, thanks for that again. |
Due to several bugs reported in #20 and other issues.
Hi there,
I seem to be stuck when trying to do a fuzzing run. My class to fuzz:
How it gets stuck:
I know that the SomeParser isn't the fastest, so it might take a while (a second or two per invocation). However, it seems stuck.
afl-fuzz is by default very verbose and talks to me what it's trying to do, while jqf-afl-fuzz is very quiet. "Performing pilot run" doesn't mean anything to me. Can I enable logging? Can I run it verbosely? What is happening?
The text was updated successfully, but these errors were encountered: