[llvm-dev] Possible soundness issue with available_externally (split from "RFC: Add guard intrinsics")

Mehdi Amini via llvm-dev llvm-dev at lists.llvm.org
Mon Feb 29 10:42:07 PST 2016


> On Feb 29, 2016, at 10:38 AM, Xinliang David Li via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> 
> ok thanks.  A more reduced test case can show different behavior between O2 and O0.
> 
> Say we have
> 
> unsigned maybe_divide (unsigned *ptr) {
>    int flag = false;
>    unsigned val = 500/ptr[0];
>    if (flag)
>        return val;
>    return (unsigned)(intptr_t)ptr);
> }
> 
> int main() {
>    unsigned g = 0;
>     return maybe_divide(&g);
> }
>    
> 
> At O2, it runs fine, but at O0 it core dumps.

I believe this program has a divide by zero and is not correct.
By luck the optimization removes the faulty instruction, which does not mean the program is well formed.

IMO this is different from Sanjoy's example, where a wrong optimization introduces the error.

-- 
Mehdi


> 
> what is the right behavior?
> 
> David
> 
> 
> On Sat, Feb 27, 2016 at 5:21 PM, Sanjoy Das <sanjoy at playingwithpointers.com <mailto:sanjoy at playingwithpointers.com>> wrote:
> On Sat, Feb 27, 2016 at 4:21 PM, Xinliang David Li <xinliangli at gmail.com <mailto:xinliangli at gmail.com>> wrote:
> > So in this case, ptr[0] = 10 is propagated into one copy of maybe_devide (in
> > source a), and ptr[0]=10 in caller_a is DSEed ?
> 
> `ptr[0] = 10` is not really propagated anywhere.  What happens is that
> `source-a` 's copy of `maybe_divide` gets optimized to a `ret
> (unsigned) ptr` (after inlining in the body of `always_false`)[1], so
> it is able to DSE the store `ptr[0] = 10`.  But `source-b` s copy of
> `maybe_divide` still has the load and the division (since it does not
> have access to `always_false` 's body), so if `caller_a` ends up
> calling that implementation of `maybe_divide`, we get a `SIGFPE`.
> 
> [1]: For reference, after inlining `always_false`, the `maybe_divide`
>   becomes
> 
>     unsigned maybe_divide(unsigned *ptr) {
>       unsigned val = 500 / ptr[0]; // dead value
>       if (false)
>         return val;
>       return (unsigned)((intptr_t)ptr);
>     }
> 
> -- Sanjoy
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160229/3fe38ca9/attachment.html>


More information about the llvm-dev mailing list