[PATCH] [Patch] UBsan: Type-based blacklisting

Richard Smith richard at metafoo.co.uk
Tue Jul 8 17:12:42 PDT 2014


The code change looks fine to me, but needs a testcase.


On Mon, Jul 7, 2014 at 9:04 AM, Byoungyoung Lee <byoungyoung at chromium.org>
wrote:

> Hi samsonov, rsmith, kcc,
>
> This is a Clang side patch for type-based blacklisting in Ubsan. As this
> patch is depending on llvm-side patch, please see
> http://reviews.llvm.org/D4406 for more details.
>
> Although the diff looks more complicated than it has to be, this patch
> only adds a simple branch  ---- if
> (!CGM.getSanitizerBlacklist().isIn(Out.str())).
>
> http://reviews.llvm.org/D4407
>
> Files:
>   lib/CodeGen/CGExpr.cpp
>
> Index: lib/CodeGen/CGExpr.cpp
> ===================================================================
> --- lib/CodeGen/CGExpr.cpp
> +++ lib/CodeGen/CGExpr.cpp
> @@ -539,44 +539,47 @@
>      llvm::raw_svector_ostream Out(MangledName);
>
>  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(),
>                                                       Out);
> -    llvm::hash_code TypeHash = hash_value(Out.str());
>
> -    // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
> -    llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
> -    llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
> -    llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
> -    llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
> -    llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
> +    // Blacklist based on the mangled types
> +    if (!CGM.getSanitizerBlacklist().isIn(Out.str())) {
> +      llvm::hash_code TypeHash = hash_value(Out.str());
>
> -    llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
> -    Hash = Builder.CreateTrunc(Hash, IntPtrTy);
> +      // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
> +      llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
> +      llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
> +      llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
> +      llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
> +      llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
>
> -    // Look the hash up in our cache.
> -    const int CacheSize = 128;
> -    llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
> -    llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
> -
> "__ubsan_vptr_type_cache");
> -    llvm::Value *Slot = Builder.CreateAnd(Hash,
> -                                          llvm::ConstantInt::get(IntPtrTy,
> -
> CacheSize-1));
> -    llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
> -    llvm::Value *CacheVal =
> -      Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
> +      llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
> +      Hash = Builder.CreateTrunc(Hash, IntPtrTy);
>
> -    // If the hash isn't in the cache, call a runtime handler to perform
> the
> -    // hard work of checking whether the vptr is for an object of the
> right
> -    // type. This will either fill in the cache and return, or produce a
> -    // diagnostic.
> -    llvm::Constant *StaticData[] = {
> -      EmitCheckSourceLocation(Loc),
> -      EmitCheckTypeDescriptor(Ty),
> -      CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
> -      llvm::ConstantInt::get(Int8Ty, TCK)
> -    };
> -    llvm::Value *DynamicData[] = { Address, Hash };
> -    EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
> -              "dynamic_type_cache_miss", StaticData, DynamicData,
> -              CRK_AlwaysRecoverable);
> +      // Look the hash up in our cache.
> +      const int CacheSize = 128;
> +      llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
> +      llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
> +
> "__ubsan_vptr_type_cache");
> +      llvm::Value *Slot =
> +        Builder.CreateAnd(Hash,llvm::ConstantInt::get(IntPtrTy,
> CacheSize-1));
> +      llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
> +      llvm::Value *CacheVal =
> +        Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
> +
> +      // If the hash isn't in the cache, call a runtime handler to
> perform the
> +      // hard work of checking whether the vptr is for an object of the
> right
> +      // type. This will either fill in the cache and return, or produce a
> +      // diagnostic.
> +      llvm::Constant *StaticData[] = {
> +        EmitCheckSourceLocation(Loc),
> +        EmitCheckTypeDescriptor(Ty),
> +        CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
> +        llvm::ConstantInt::get(Int8Ty, TCK)
> +      };
> +      llvm::Value *DynamicData[] = { Address, Hash };
> +      EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
> +                "dynamic_type_cache_miss", StaticData, DynamicData,
> +                CRK_AlwaysRecoverable);
> +    }
>    }
>
>    if (Done) {
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140708/a67f92b9/attachment.html>


More information about the cfe-commits mailing list