Skip to content
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

Lazy static alternatives #406

Open
lrubasze opened this issue Oct 22, 2023 · 7 comments
Open

Lazy static alternatives #406

lrubasze opened this issue Oct 22, 2023 · 7 comments

Comments

@lrubasze
Copy link
Contributor

Since the resettable lazy_static has been unsupported fuzz tests using lazy_static suffer from low stability.
What do you recommend to use instead of lazy_static when implementing some fuzz tests in afl and to not decrease the stability?

(I tried to use OnceLock but the stability as low as for lazy_static.)

@alex
Copy link
Member

alex commented Oct 22, 2023 via email

@lrubasze
Copy link
Contributor Author

lrubasze commented Oct 22, 2023

Thanks for the reply.
What about afl stability metric when using OnceCell? Is it better than lazy_static?

@lrubasze
Copy link
Contributor Author

Thanks for the reply. What about afl stability metric when using OnceCell? Is it better than lazy_static?

Ok, I've checked the once_cell::sync::Lazy and it actually behaves the same as lazy_static - AFL stability metric is really low.

So is there any other alternative that works fine with AFL?
Do you consider introducing a resettable once_cell similar to resettable lazy_static?

@smoelius
Copy link
Member

Ok, I've checked the once_cell::sync::Lazy and it actually behaves the same as lazy_static - AFL stability metric is really low.

@lrubasze Thanks very much for doing these experiments.

So is there any other alternative that works fine with AFL? Do you consider introducing a resettable once_cell similar to resettable lazy_static?

I'm wondering if we should try to build something more general.

For example, maybe the fuzz macro could accept a reset closure argument that gets called periodically. Then, if a user wanted to build a resettable_whatever, they could. They would simply have to pass an appropriate reset argument to the fuzz macro.

I'm open to other ideas though.

@lrubasze
Copy link
Contributor Author

lrubasze commented Oct 25, 2023

@smoelius thanks for reply.
Yeah, adding a more general reset closure makes perfect sense.

Firstly, I am actually in need of it right now (not only because of lazy_static) :)
And I am workarounding it in a following way:

fn main() {
    let mut fuzzer = Fuzzer::new(); // Costly initialisation of the fuzzer, which we'd like to avoid in the fuzz loop
    fuzz!(|data: &[u8]| {
        fuzzer.fuzz_func(data);     // It modifies an internal state of the fuzzer
        fuzzer.reset();             // Restore the fuzzer to the original state
    });
}

Above approach is convenient, because a reset method has access to the fuzzer internals, which might need a reset.

Just wondering if it would be possible to use that reset closure to achieve above...
Or maybe we should just use reset for some really generic stuff (not directly related to the fuzzer internals, eg. lazy_static). And for more complicated cases such as above let developers implement their own way.

Secondly, since once_cell is a successor of the lazy_static I think it would be really useful to have resettable once_cell. No matter if we call it in reset closure or in afl internally.

@smoelius
Copy link
Member

Just wondering if it would be possible to use that reset closure to achieve above...

There may be some technical impediment that I am not seeing, but in my head, the new feature could be used like this:

    fuzz_with_reset!(|data: &[u8]|, || fuzzer.reset()) {
        fuzzer.fuzz_func(data); 
    });

And, similarly, if we had a resettable_once_cell, one might write:

    fuzz_with_reset!(|data: &[u8]|, || resettable_once_cell::reset()) {
        ...
    });

The fuzz_with_reset macro would call the reset closure somewhere around here. which is where resettable_lazy_static::lazy::reset() was called before.

Secondly, since once_cell is a successor of the lazy_static I think it would be really useful to have resettable once_cell. No matter if we call it in reset closure or in afl internally.

Your point is well taken.

Here's a note just in case someone decides to build that crate. The lazy_static maintainers did not want to incorporate a reset function directly into lazy_static, which was the right decision, IMHO. But that decision necessitated forking lazy_static.

When I built the resettable_lazy_static fork, I tried to make it perfect, independent of everything else. That was a mistake---my priorities were wrong.

If we fork once_cell to make resettable_once_cell, we should try to keep the changes to their files minimal. That way, it will be easy to rebase the fork's changes onto new releases of once_cell as they are published.*

* I know, to many, this will seem obvious.

@lrubasze
Copy link
Contributor Author

Sounds good, I like the proposition :)

The note for the future builder of the resettable_once_cell is really valuable! 👍
Though, not sure but maybe it'd be worth adding a reset optional feature into the original once_cell. But agree it might be concerning.

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

No branches or pull requests

3 participants