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
Feature request: timeout -t #26
Comments
As you said in another issue:
My first suggestion is to try implementing Thread.interrupt as suggested in the docs, for some cases that might help. I would implement this as a first attempt to stop the thread. My second suggestion is maybe a little uncommon, but I would say let's just ignore the deprecation and call stop(). While not very nice, this is fuzzing-land where we simply need this kind of control, because AFL fuzzing will always find a way to hang Java. As the same doc link suggest, it's probably best to catch ThreadDeath, even if that's not optimal. There are also suggestions to use the new JDK 9 spinWait(), but I'm not sure that method would help. A different approach would be using ExecutorService. This is also how Kelinci does it or also explained on stackoverflow. |
I've added some limited support for the Note: You will have to re-run the The default value for timeout is The implementation does not use either This trick means that JQF can detect hangs due to infinite loops fairly efficiently, but not hangs due to deadlocks where no branches are being executed. For now, I will say this is sufficient as most fuzzing targets are not I/O intensive. In the future, we can possible interrupt deadlocks using |
This is still not working as expected. Although the first hang gets detected, throwing a I'm still working on it... the issue remains open. |
This change allows guidances to throw RuntimeException(s) such as TimeoutException without breaking the instrumentation and tracing logic. Addresses #26.
I just removed the -t argument for one of my runs, and while it seems to be running fine it says in the process list |
@floyd-fuh Don't worry about that. We always give AFL a 50ms timeout regardless of what the actual timeout is. This is so that AFL sets its timeout flag for every single input. In practice, AFL only marks a run as a "hang" if the timeout flag is set AND the return value of |
Ah, perfect, thanks for the pointers! I think I just thought it wouldn't work correctly, but everything is fine. Btw. I ran into new problems with the timeouts. JQF classified the Java bug found in #27 as a crash. As you described above not what you intended, but perfectly fine in my use case. So a miss-classification as crash or hang is fine for me. However, finding a similar bug in a Java library JQF actually got stuck. I think the reason is that the endless loop is in a part of the code that was not instrumented, so JQF won't be able to measure time and throw a run-time exception after the elapsed time. So at the moment I have to recheck on my fuzzers from time to time. Today they were running for 5 days, but got stuck after the first 7 hours. I wasn't too unhappy because that meant a new finding, but it's obviously not optimal having to check on them and restart fuzzers often. So I guess a And sorry for asking for so many features, I kind of feel bad, but JQF is really improving a lot and I clearly prefer it over Kelinci and java-afl at the moment. Keep up the good work |
Timouts during call events create some problems due to the bubbling of the TimeoutException up the stack in the presence of instrumentation that expects all method throws to be caught and reported, so as to maintain a valid shadow stack. We also throw the TimeoutException directly instead of setting a flag and re-throwing every time, to prevent exceptions from being thrown in the exception-handling instructions and events generated from finally-blocks and so on. Partially addresses #26.
Timeouts are working fine in AFL-mode for now. Please re-open if issues persist. |
I updated the version of JQF I'm using to the latest github version and started fuzzing Apache Tika again. However, as you said AFL timeout should work fine now, I ran JQF with lower timeouts, such as 1000 or even 300. It runs fine and also the execs/s seem to show that it is going faster. However, stock AFL would usually put a lot of files in the "hangs" directory and would very quickly find hangs. However, JQF never puts any file in the "hangs" directory for me now, which is very weird with these timeout settings. So when I run with -t 300 I expect every file that takes more than 300ms of processing to be put in the hangs directory. This doesn't seem to be the case. So my guess is at the moment JQF is not able to find endless loops as it doesn't fill the hangs directory. Can you confirm this? Can you elaborate a little on how the timeout setting is applied? |
Hi Floyd, I think this could be because of Tika's multi-threaded parsers. The last commit changed the behavior to throw TimeoutException(s) only for the first branch-event after the time limit instead of for every event after the time limit, since in some other benchmarks we were seeing timeouts being continuously re-thrown from finally{} blocks that surrounded the (possibly infinite) loops. As much as possible, we would like to execute the finally blocks even if the enclosed loop was infinite. However, this means that if the timeout occurs in not-the-main-thread, it may not get reported. I think I can attempt a fix that reports a timeout in the first branch-event per-thread after the time limit is reached. |
If a timeout occurrs in a thread other than the thread that has invoked the test method, then the TimeoutException does not propagate to the FuzzStatement and can remain uncaught. Therefore, this commit adds a flag that is set once per test run whenever a timeout is detected in any thread. If the flag is set at the end of the run, then the result is forcibly changed to TIMEOUT. This commit also bundles a test for verifying that the result is a TIMEOUT when the exception is actually caught. Addresses #26.
Pushed an attempted fix. Please let me know if this changes anything. If you still do not see any timeouts (or misclassified crashes), I may have to debug specifically with Tika. |
Perfect! Looks much better now... At least I get hangs now, obviously I cannot be sure if it is really detecting all of them :) Thanks a lot for the fix |
Hi Rohan, I am currently using fuzzing with Zest driver and after some iterations it hangs for long time. Many thanks in advance for your time and support. |
Hi Rohan, Just to keep you updated I have tried to define the timeout with a global Rule and it seems to not hang anymore i.e.
|
Hi @Ahmedfir, In Zest, you can set timeout for individual runs via the system property |
Reopening as |
thank you for the quick answer. It's a nice idea, I think. I didn't use the CLI before. I have only run zest with the maven plugin so-far but I will try CLI with the jqf.ei.TIMEOUT and keep you updated. Thanks again. |
It should also work with the maven plugin. The maven plugin runs the same code. Simply give `-Djqf.ei.timeout` when running `mvn jqf:fuzz`.
The maven plugin is the preferred way of running Zest. The command line script is mainly for trying out experimental features and/or fuzzing the JDK classes.
|
Hi @rohanpadhye, |
@Ahmedfir Do you know what is causing the hangs? In both the AFL and Zest guidances, we check the timeout during each code coverage event. This means that we can detect timeouts due to potentially infinite loops in instrumented app classes. If the app is timing out because it is waiting for I/O or if it is looping in an uninstrumented class, then JQF cannot detect it. In Java, it is not safe to stop a thread while it is waiting on I/O or compute. Since all of this is essentially in-process fuzzing, we cannot send SIGKILL either. Can you please confirm the source of your app hangs? Maybe try |
Hi @rohanpadhye, indeed it is timing out because of a thread running further inside of the test. thank you anyway, I will try to avoid such uses in the future. Cheers |
I've added options for both |
thank you very much! I am simply trying to not using any extra thread in the test execution. |
Perhaps the test is not running in the main thread? Zest currently only traces the main thread. |
It is in the main thread. but now I am doubting about something else. The test is executing code in a jar file that might be invisible to the tracer... hmm I will dive further in this direction and let you know. :) thank you as always for your quick answers! |
More undocumented features that may be useful: try setting |
Thanks, that' great to know! |
I was just wondering why Zest has no "hangs" directory in its output directory? Or is it just by default not using any timeout configuration? I think for Java security analysis it is as important to get all the hangs as the failures, as infinite loops might be really bad. |
I believe that timeouts currently get saved in the failures directory
itself, marked with TineoutException in the logs.
I'm open to the idea of adding another "timeouts" directory to the results,
if you think this is an important distinction.
…On Wed, Oct 2, 2019, 11:04 PM floyd ***@***.***> wrote:
I was just wondering why Zest has no "hangs" directory in its output
directory? Or is it just by default not using any timeout configuration?
I think for Java security analysis it is as important to get all the hangs
as the failures, as infinite loops might be really bad.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#26>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABAJQMW4CJTCQQAOX3TCYITQMWDPLANCNFSM4E6Y73QQ>
.
|
Ah, no, that's perfectly fine then. I was just wondering. I just haven't seen any being stored in the failures directory. |
so-far I am not seeing any timeout scenario happening. |
Thanks for the update! |
Would it be possible to get the -t switch to specify a timeout for a testcase? Fuzzing is only efficient when the inputs do not take too long. I'm currently trying to do another run with Tika, but alredy the fourth input dry run is just stuck for several minutes...
The text was updated successfully, but these errors were encountered: