Use-after-free bugs are a particular class of memory safety bugs. How often are they exploitable, in practice? When you find a use-after-free bug in a program, is it often exploitable, rarely exploitable, or does it vary based upon some other factor I'm overlooking?
I'm particularly interested in how often use-after-free bugs in C programs are exploitable (specifically, C, rather than C++). How often are use-after-free bugs in C programs exploitable? If I discover a use-after-free bug in a C program I'm testing, what should I estimate as the likelihood it is exploitable? 90%? 50%? 10%? When triaging bugs (e.g., fuzzer crashes, Valgrind warnings, warnings from static analysis tools), how highly should I prioritize fixing use-after-free bugs, compared to other kinds of memory safety bugs?
Research I've done. I have been doing some research. It looks like use-after-free bugs in C++ programs are often exploitable (because the memory layout of a C++ object always contains a pointer to a vtable, and overwriting this leads easily to code injection). OK, good. Now what about C programs?
I can also see how use-after-free bugs can be exploited in certain special cases. For instance, use-after-free bugs in browsers or other programs with user-controllable scripting seem to often be exploitable, because of the ease of doing heap spraying and the great deal of control over the contents of objects stored in memory. And, yes I've seen some sophisticated methods of exploiting use-after-free bugs in certain special cases (e.g., using them for information disclosure, which then lets you derandomize ASLR, after which....), but those seem pretty application-specific and like you might need to get lucky for the attack to work and even then it'd take a bunch of work to build the exploit. But I'm interesting in knowing what the "typical case" usually looks like, rather than the special cases where the attacker gets lucky.