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

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 26 19:08:39 PST 2016


On Thu, Feb 25, 2016 at 9:59 AM, Sanjoy Das
<sanjoy at playingwithpointers.com> wrote:
> Couple of other examples:
>
>   void @foo(i32* %ptr) available_externally {
>     %discard = load i32, i32* %ptr
>   }
>   void bar() {
>     call @foo(i32* %x)
>   }
>
> ==>
>
>   void @foo(i32* %ptr) available_externally {
>   }
>   void bar() {
>     call @foo(i32* %x)
>   }
>
> ==>
>
>   void @foo(i32* %ptr) available_externally {
>   }
>   void bar() {
>     call @foo(i32* undef) ;; non optimized @foo will crash
>   }
>
>   ;; Similar example if @foo was dividing something by an integer
>   ;; argument
>
> We've actually seen the above in our VM (though back then we
> didn't realize that the problem was more general than the one
> case above).

^ This particular case above is already fixed in DeadArgElim:

bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
{
  // We cannot change the arguments if this TU does not define the function or
  // if the linker may choose a function body from another TU, even if the
  // nominal linkage indicates that other copies of the function have the same
  // semantics. In the below example, the dead load from %p may not have been
  // eliminated from the linker-chosen copy of f, so replacing %p with undef
  // in callers may introduce undefined behavior.
  //
  // define linkonce_odr void @f(i32* %p) {
  //   %v = load i32 %p
  //   ret void
  // }
  if (!Fn.isStrongDefinitionForLinker())
    return false;

-- Sanjoy


More information about the llvm-dev mailing list