4 ms·
You're probably using a different definition of 100% than any impossibility proof would use. Consider some code: --- a=malloc(1); needfree=true; if (hashfn
by nullc 7y ago
You're probably using a different definition of 100% than any impossibility proof would use.
Consider some code:
---
a=malloc(1);
needfree=true;
if (hashfn(first_factor(huge_static_rsanum1))&1){needfree=false;free(a);}
if (hashfn(first_factor(huge_static_rsanum2))&1){needfree=false;free(a);}
if(needfree)free(a);
---
The decision if this has a double free or not depends on the factorizations of two huge difficult to factor constants. It either double-frees or not depending on those constants.
Surely your software cannot decide that...
What you probably mean is something like "100% on real programs rather than contrived cases". Of course, in that case, your definition of 'real programs' is the catch. :P
Sometimes things that seem like they should always work except on contrived junk like the above example actually run into limitations in practice because macros and machine code generation produce ... well ... contrived junk from time to time.
- jjnoakes 7y agoI personally would want code like this flagged by static analysis. I would fix the code by not calling free in the second 'if' body if needfree was already false (just like the call at the end of the function is guarded).
- nullc 7y agoYou might want it flagged-- I would--, but it would still be a false positive if it did so (assuming the constants didn't result in a double-free). :)
- kccqzy 7y agoI think the argument is that static analyzers don't have to work on completely unchanged code, but rather rely on humans to structure the code in a way to avoid issues. Many years ago people regularly wrote things like "if (retval = f())" but after compilers started to complain about it people changed to write "if ((retval = f()))" instead, if they want an assignment and truthfulness testing at the same time.
- deleted 7y ago[deleted]
- WalterBright 7y ago> Surely your software cannot decide that... The D implementation would reject such code. The DFA assumes all control paths are executed. For example, if (c) free(p); *p = 3; is rejected as use-after-free. if (c) free(p); if (!c) *p = 3; is also rejected as use-after-free. If the DFA is done properly, you will not be able to trick it.
- Ygg2 7y agoOk. And if you call into non-D code, like C or assembly? I think this is just moving potential problem under rug, which is best it can do, given Rice Theorem
- WalterBright 7y agoCalling non-D functions means the compiler cannot check them, and will rely on the user having correctly specified and annotated the function signature. I.e. you can have "unsafe" annotated code which the compiler doesn't check, which is indeed where the dirty deeds get swept. For example, I doubt someone could write a guaranteed safe implementation of malloc(). The idea, naturally, is to specifically mark such sections so that your crack QA team knows what to focus on, and to minimize the amount of such code. The trick is to make the safe sections expressive enough that it is practical to write the bulk of the code in safe sections, thereby minimizing the "threat surface".
- UncleMeat 7y agoThen that doesn't mean "0% of the negatives".
- bonzini 7y agoNo, it means you have false positives. But no false negatives.
- UncleMeat 7y agoAnd that's a "negative" in a practical sense. An abstract interpretation that outputs Top for all programs is sound but useless. In practice, most sound static analyses for complex problems aren't too far from that.
- rq1 7y agoThere’s definitely a double free, provided that nowhere you proved that your conditions can’t be simultaneously true.