Hi Vedant, So this actually broke -fsanitize=function on linux. Han is working up a testcase for it, but letting you know for now that we'll probably need some change here.
-eric On Tue, Sep 12, 2017 at 5:05 PM Vedant Kumar via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: vedantk > Date: Tue Sep 12 17:04:35 2017 > New Revision: 313096 > > URL: http://llvm.org/viewvc/llvm-project?rev=313096&view=rev > Log: > [ubsan] Function Sanitizer: Don't require writable text segments > > This change will make it possible to use -fsanitize=function on Darwin and > possibly on other platforms. It fixes an issue with the way RTTI is stored > into > function prologue data. > > On Darwin, addresses stored in prologue data can't require run-time fixups > and > must be PC-relative. Run-time fixups are undesirable because they > necessitate > writable text segments, which can lead to security issues. And absolute > addresses are undesirable because they break PIE mode. > > The fix is to create a private global which points to the RTTI, and then to > encode a PC-relative reference to the global into prologue data. > > Differential Revision: https://reviews.llvm.org/D37597 > > Modified: > cfe/trunk/lib/CodeGen/CGExpr.cpp > cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > cfe/trunk/lib/CodeGen/CodeGenFunction.h > cfe/trunk/lib/CodeGen/TargetInfo.cpp > cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp > > Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=313096&r1=313095&r2=313096&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 12 17:04:35 2017 > @@ -4409,10 +4409,7 @@ RValue CodeGenFunction::EmitCall(QualTyp > SanitizerScope SanScope(this); > llvm::Constant *FTRTTIConst = > CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), > /*ForEH=*/true); > - llvm::Type *PrefixStructTyElems[] = { > - PrefixSig->getType(), > - FTRTTIConst->getType() > - }; > + llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty}; > llvm::StructType *PrefixStructTy = llvm::StructType::get( > CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true); > > @@ -4433,8 +4430,10 @@ RValue CodeGenFunction::EmitCall(QualTyp > EmitBlock(TypeCheck); > llvm::Value *CalleeRTTIPtr = > Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, > 0, 1); > - llvm::Value *CalleeRTTI = > + llvm::Value *CalleeRTTIEncoded = > Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign()); > + llvm::Value *CalleeRTTI = > + DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded); > llvm::Value *CalleeRTTIMatch = > Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst); > llvm::Constant *StaticData[] = { > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=313096&r1=313095&r2=313096&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Sep 12 17:04:35 2017 > @@ -429,6 +429,43 @@ bool CodeGenFunction::ShouldXRayInstrume > return CGM.getCodeGenOpts().XRayInstrumentFunctions; > } > > +llvm::Constant * > +CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F, > + llvm::Constant *Addr) { > + // Addresses stored in prologue data can't require run-time fixups and > must > + // be PC-relative. Run-time fixups are undesirable because they > necessitate > + // writable text segments, which are unsafe. And absolute addresses are > + // undesirable because they break PIE mode. > + > + // Add a layer of indirection through a private global. Taking its > address > + // won't result in a run-time fixup, even if Addr has linkonce_odr > linkage. > + auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(), > + /*isConstant=*/true, > + llvm::GlobalValue::PrivateLinkage, > Addr); > + > + // Create a PC-relative address. > + auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy); > + auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy); > + auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt); > + return (IntPtrTy == Int32Ty) > + ? PCRelAsInt > + : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty); > +} > + > +llvm::Value * > +CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F, > + llvm::Value *EncodedAddr) { > + // Reconstruct the address of the global. > + auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy); > + auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int"); > + auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, " > global_addr.int"); > + auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, > "global_addr"); > + > + // Load the original pointer through the global. > + return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()), > + "decoded_addr"); > +} > + > /// EmitFunctionInstrumentation - Emit LLVM code to call the specified > /// instrumentation function with the current function and the call site, > if > /// function instrumentation is enabled. > @@ -856,7 +893,10 @@ void CodeGenFunction::StartFunction(Glob > CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { > llvm::Constant *FTRTTIConst = > CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true); > - llvm::Constant *PrologueStructElems[] = { PrologueSig, > FTRTTIConst }; > + llvm::Constant *FTRTTIConstEncoded = > + EncodeAddrForUseInPrologue(Fn, FTRTTIConst); > + llvm::Constant *PrologueStructElems[] = {PrologueSig, > + FTRTTIConstEncoded}; > llvm::Constant *PrologueStructConst = > llvm::ConstantStruct::getAnon(PrologueStructElems, > /*Packed=*/true); > Fn->setPrologueData(PrologueStructConst); > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=313096&r1=313095&r2=313096&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 12 17:04:35 2017 > @@ -1776,6 +1776,15 @@ public: > /// EmitMCountInstrumentation - Emit call to .mcount. > void EmitMCountInstrumentation(); > > + /// Encode an address into a form suitable for use in a function > prologue. > + llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F, > + llvm::Constant *Addr); > + > + /// Decode an address used in a function prologue, encoded by \c > + /// EncodeAddrForUseInPrologue. > + llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F, > + llvm::Value *EncodedAddr); > + > /// EmitFunctionProlog - Emit the target specific LLVM code to load the > /// arguments for the given function. This is also responsible for > naming the > /// LLVM function arguments. > > Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=313096&r1=313095&r2=313096&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Tue Sep 12 17:04:35 2017 > @@ -1086,8 +1086,8 @@ public: > getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { > unsigned Sig = (0xeb << 0) | // jmp rel8 > (0x06 << 8) | // .+0x08 > - ('F' << 16) | > - ('T' << 24); > + ('v' << 16) | > + ('2' << 24); > return llvm::ConstantInt::get(CGM.Int32Ty, Sig); > } > > @@ -2277,17 +2277,10 @@ public: > > llvm::Constant * > getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { > - unsigned Sig; > - if (getABIInfo().has64BitPointers()) > - Sig = (0xeb << 0) | // jmp rel8 > - (0x0a << 8) | // .+0x0c > - ('F' << 16) | > - ('T' << 24); > - else > - Sig = (0xeb << 0) | // jmp rel8 > - (0x06 << 8) | // .+0x08 > - ('F' << 16) | > - ('T' << 24); > + unsigned Sig = (0xeb << 0) | // jmp rel8 > + (0x06 << 8) | // .+0x08 > + ('v' << 16) | > + ('2' << 24); > return llvm::ConstantInt::get(CGM.Int32Ty, Sig); > } > > > Modified: cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp?rev=313096&r1=313095&r2=313096&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/catch-undef-behavior.cpp Tue Sep 12 17:04:35 > 2017 > @@ -16,6 +16,10 @@ struct S { > // Check that type mismatch handler is not modified by ASan. > // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 > }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* > [[TYPE_DESCR]], {{.*}} } > > +// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* > bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > +// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* > bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > +// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* > bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > + > struct T : S {}; > > // CHECK-LABEL: @_Z17reference_binding > @@ -395,23 +399,30 @@ void downcast_reference(B &b) { > // CHECK-NEXT: br i1 [[AND]] > } > > -// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > }> > -// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > }> > -// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) > }> > +// > +// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to > i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to > i64)) to i32) }> > +// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** > [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* > @_Z22indirect_function_callPFviE to i32)) }> > +// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, > i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** > [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* > @_Z22indirect_function_callPFviE to i32)) }> > void indirect_function_call(void (*p)(int)) { > - // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>* > + // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>* > > // Signature check > - // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, > i8* }>* [[PTR]], i32 0, i32 0 > + // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, > i32 }>* [[PTR]], i32 0, i32 0 > // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]] > - // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459 > + // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819 > // CHECK-NEXT: br i1 [[SIGCMP]] > > // RTTI pointer check > - // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* > }>* [[PTR]], i32 0, i32 1 > - // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]] > + // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 > }>* [[PTR]], i32 0, i32 1 > + // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]] > + // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64 > + // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64 > + // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], > [[FuncAddrInt]] > + // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to > i8** > + // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8 > // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, > i8* }* @_ZTIFviE to i8*) > // CHECK-NEXT: br i1 [[RTTICMP]] > + > p(42); > } > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits