1 //===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "../tools/llvm-cfi-verify/lib/FileAnalysis.h" 11 #include "../tools/llvm-cfi-verify/lib/GraphBuilder.h" 12 #include "gmock/gmock.h" 13 #include "gtest/gtest.h" 14 15 #include "llvm/BinaryFormat/ELF.h" 16 #include "llvm/MC/MCAsmInfo.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstPrinter.h" 21 #include "llvm/MC/MCInstrAnalysis.h" 22 #include "llvm/MC/MCInstrDesc.h" 23 #include "llvm/MC/MCInstrInfo.h" 24 #include "llvm/MC/MCObjectFileInfo.h" 25 #include "llvm/MC/MCRegisterInfo.h" 26 #include "llvm/MC/MCSubtargetInfo.h" 27 #include "llvm/Object/Binary.h" 28 #include "llvm/Object/COFF.h" 29 #include "llvm/Object/ELFObjectFile.h" 30 #include "llvm/Object/ObjectFile.h" 31 #include "llvm/Support/Casting.h" 32 #include "llvm/Support/CommandLine.h" 33 #include "llvm/Support/Error.h" 34 #include "llvm/Support/MemoryBuffer.h" 35 #include "llvm/Support/TargetRegistry.h" 36 #include "llvm/Support/TargetSelect.h" 37 #include "llvm/Support/raw_ostream.h" 38 39 #include <cstdlib> 40 41 using Instr = ::llvm::cfi_verify::FileAnalysis::Instr; 42 using ::testing::Eq; 43 using ::testing::Field; 44 45 namespace llvm { 46 namespace cfi_verify { 47 namespace { 48 class ELFx86TestFileAnalysis : public FileAnalysis { 49 public: 50 ELFx86TestFileAnalysis() 51 : FileAnalysis(Triple("x86_64--"), SubtargetFeatures()) {} 52 53 // Expose this method publicly for testing. 54 void parseSectionContents(ArrayRef<uint8_t> SectionBytes, 55 uint64_t SectionAddress) { 56 FileAnalysis::parseSectionContents(SectionBytes, SectionAddress); 57 } 58 59 Error initialiseDisassemblyMembers() { 60 return FileAnalysis::initialiseDisassemblyMembers(); 61 } 62 }; 63 64 class BasicFileAnalysisTest : public ::testing::Test { 65 protected: 66 virtual void SetUp() { 67 IgnoreDWARFFlag = true; 68 SuccessfullyInitialised = true; 69 if (auto Err = Analysis.initialiseDisassemblyMembers()) { 70 handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) { 71 SuccessfullyInitialised = false; 72 outs() 73 << "Note: CFIVerifyTests are disabled due to lack of x86 support " 74 "on this build.\n"; 75 }); 76 } 77 } 78 79 bool SuccessfullyInitialised; 80 ELFx86TestFileAnalysis Analysis; 81 }; 82 83 TEST_F(BasicFileAnalysisTest, BasicDisassemblyTraversalTest) { 84 if (!SuccessfullyInitialised) 85 return; 86 Analysis.parseSectionContents( 87 { 88 0x90, // 0: nop 89 0xb0, 0x00, // 1: mov $0x0, %al 90 0x48, 0x89, 0xe5, // 3: mov %rsp, %rbp 91 0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp 92 0x48, 0xbe, 0xc4, 0x07, 0x40, 93 0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi 94 0x2f, // 20: (bad) 95 0x41, 0x0e, // 21: rex.B (bad) 96 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1} 97 }, 98 0xDEADBEEF); 99 100 EXPECT_EQ(nullptr, Analysis.getInstruction(0x0)); 101 EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000)); 102 103 // 0xDEADBEEF: nop 104 const auto *InstrMeta = Analysis.getInstruction(0xDEADBEEF); 105 EXPECT_NE(nullptr, InstrMeta); 106 EXPECT_EQ(0xDEADBEEF, InstrMeta->VMAddress); 107 EXPECT_EQ(1u, InstrMeta->InstructionSize); 108 EXPECT_TRUE(InstrMeta->Valid); 109 110 const auto *NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta); 111 EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta)); 112 const auto *PrevInstrMeta = InstrMeta; 113 114 // 0xDEADBEEF + 1: mov $0x0, %al 115 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 1); 116 EXPECT_NE(nullptr, InstrMeta); 117 EXPECT_EQ(NextInstrMeta, InstrMeta); 118 EXPECT_EQ(0xDEADBEEF + 1, InstrMeta->VMAddress); 119 EXPECT_EQ(2u, InstrMeta->InstructionSize); 120 EXPECT_TRUE(InstrMeta->Valid); 121 122 NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta); 123 EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta)); 124 PrevInstrMeta = InstrMeta; 125 126 // 0xDEADBEEF + 3: mov %rsp, %rbp 127 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 3); 128 EXPECT_NE(nullptr, InstrMeta); 129 EXPECT_EQ(NextInstrMeta, InstrMeta); 130 EXPECT_EQ(0xDEADBEEF + 3, InstrMeta->VMAddress); 131 EXPECT_EQ(3u, InstrMeta->InstructionSize); 132 EXPECT_TRUE(InstrMeta->Valid); 133 134 NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta); 135 EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta)); 136 PrevInstrMeta = InstrMeta; 137 138 // 0xDEADBEEF + 6: sub $0x18, %rsp 139 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 6); 140 EXPECT_NE(nullptr, InstrMeta); 141 EXPECT_EQ(NextInstrMeta, InstrMeta); 142 EXPECT_EQ(0xDEADBEEF + 6, InstrMeta->VMAddress); 143 EXPECT_EQ(4u, InstrMeta->InstructionSize); 144 EXPECT_TRUE(InstrMeta->Valid); 145 146 NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta); 147 EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta)); 148 PrevInstrMeta = InstrMeta; 149 150 // 0xDEADBEEF + 10: movabs $0x4007c4, %rsi 151 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 10); 152 EXPECT_NE(nullptr, InstrMeta); 153 EXPECT_EQ(NextInstrMeta, InstrMeta); 154 EXPECT_EQ(0xDEADBEEF + 10, InstrMeta->VMAddress); 155 EXPECT_EQ(10u, InstrMeta->InstructionSize); 156 EXPECT_TRUE(InstrMeta->Valid); 157 158 EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta)); 159 EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta)); 160 PrevInstrMeta = InstrMeta; 161 162 // 0xDEADBEEF + 20: (bad) 163 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 20); 164 EXPECT_NE(nullptr, InstrMeta); 165 EXPECT_EQ(0xDEADBEEF + 20, InstrMeta->VMAddress); 166 EXPECT_EQ(1u, InstrMeta->InstructionSize); 167 EXPECT_FALSE(InstrMeta->Valid); 168 169 EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta)); 170 EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta)); 171 172 // 0xDEADBEEF + 21: rex.B (bad) 173 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 21); 174 EXPECT_NE(nullptr, InstrMeta); 175 EXPECT_EQ(0xDEADBEEF + 21, InstrMeta->VMAddress); 176 EXPECT_EQ(2u, InstrMeta->InstructionSize); 177 EXPECT_FALSE(InstrMeta->Valid); 178 179 EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta)); 180 EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta)); 181 182 // 0xDEADBEEF + 6: (bad) {%k1} 183 InstrMeta = Analysis.getInstruction(0xDEADBEEF + 23); 184 EXPECT_NE(nullptr, InstrMeta); 185 EXPECT_EQ(0xDEADBEEF + 23, InstrMeta->VMAddress); 186 EXPECT_EQ(5u, InstrMeta->InstructionSize); 187 EXPECT_FALSE(InstrMeta->Valid); 188 189 EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta)); 190 EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta)); 191 } 192 193 TEST_F(BasicFileAnalysisTest, PrevAndNextFromBadInst) { 194 if (!SuccessfullyInitialised) 195 return; 196 Analysis.parseSectionContents( 197 { 198 0x90, // 0: nop 199 0x2f, // 1: (bad) 200 0x90 // 2: nop 201 }, 202 0xDEADBEEF); 203 const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1); 204 const auto *GoodInstrMeta = 205 Analysis.getPrevInstructionSequential(BadInstrMeta); 206 EXPECT_NE(nullptr, GoodInstrMeta); 207 EXPECT_EQ(0xDEADBEEF, GoodInstrMeta->VMAddress); 208 EXPECT_EQ(1u, GoodInstrMeta->InstructionSize); 209 210 GoodInstrMeta = Analysis.getNextInstructionSequential(BadInstrMeta); 211 EXPECT_NE(nullptr, GoodInstrMeta); 212 EXPECT_EQ(0xDEADBEEF + 2, GoodInstrMeta->VMAddress); 213 EXPECT_EQ(1u, GoodInstrMeta->InstructionSize); 214 } 215 216 TEST_F(BasicFileAnalysisTest, CFITrapTest) { 217 if (!SuccessfullyInitialised) 218 return; 219 Analysis.parseSectionContents( 220 { 221 0x90, // 0: nop 222 0xb0, 0x00, // 1: mov $0x0, %al 223 0x48, 0x89, 0xe5, // 3: mov %rsp, %rbp 224 0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp 225 0x48, 0xbe, 0xc4, 0x07, 0x40, 226 0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi 227 0x2f, // 20: (bad) 228 0x41, 0x0e, // 21: rex.B (bad) 229 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1} 230 0x0f, 0x0b // 28: ud2 231 }, 232 0xDEADBEEF); 233 234 EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF))); 235 EXPECT_FALSE( 236 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 3))); 237 EXPECT_FALSE( 238 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 6))); 239 EXPECT_FALSE( 240 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 10))); 241 EXPECT_FALSE( 242 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 20))); 243 EXPECT_FALSE( 244 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 21))); 245 EXPECT_FALSE( 246 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 23))); 247 EXPECT_TRUE( 248 Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 28))); 249 } 250 251 TEST_F(BasicFileAnalysisTest, FallThroughTest) { 252 if (!SuccessfullyInitialised) 253 return; 254 Analysis.parseSectionContents( 255 { 256 0x90, // 0: nop 257 0xb0, 0x00, // 1: mov $0x0, %al 258 0x2f, // 3: (bad) 259 0x0f, 0x0b, // 4: ud2 260 0xff, 0x20, // 6: jmpq *(%rax) 261 0xeb, 0x00, // 8: jmp +0 262 0xe8, 0x45, 0xfe, 0xff, 0xff, // 10: callq [some loc] 263 0xff, 0x10, // 15: callq *(rax) 264 0x75, 0x00, // 17: jne +0 265 0xc3, // 19: retq 266 }, 267 0xDEADBEEF); 268 269 EXPECT_TRUE( 270 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF))); 271 EXPECT_TRUE( 272 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 1))); 273 EXPECT_FALSE( 274 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 3))); 275 EXPECT_FALSE( 276 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 4))); 277 EXPECT_FALSE( 278 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 6))); 279 EXPECT_FALSE( 280 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 8))); 281 EXPECT_FALSE( 282 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 10))); 283 EXPECT_FALSE( 284 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 15))); 285 EXPECT_TRUE( 286 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 17))); 287 EXPECT_FALSE( 288 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 19))); 289 } 290 291 TEST_F(BasicFileAnalysisTest, DefiniteNextInstructionTest) { 292 if (!SuccessfullyInitialised) 293 return; 294 Analysis.parseSectionContents( 295 { 296 0x90, // 0: nop 297 0xb0, 0x00, // 1: mov $0x0, %al 298 0x2f, // 3: (bad) 299 0x0f, 0x0b, // 4: ud2 300 0xff, 0x20, // 6: jmpq *(%rax) 301 0xeb, 0x00, // 8: jmp 10 [+0] 302 0xeb, 0x05, // 10: jmp 17 [+5] 303 0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0] 304 0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678] 305 0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4] 306 0xff, 0x10, // 27: callq *(rax) 307 0x75, 0x00, // 29: jne 31 [+0] 308 0x75, 0xe0, // 31: jne 1 [-32] 309 0xc3, // 33: retq 310 0xeb, 0xdd, // 34: jmp 1 [-35] 311 0xeb, 0xdd, // 36: jmp 3 [-35] 312 0xeb, 0xdc, // 38: jmp 4 [-36] 313 }, 314 0xDEADBEEF); 315 316 const auto *Current = Analysis.getInstruction(0xDEADBEEF); 317 const auto *Next = Analysis.getDefiniteNextInstruction(*Current); 318 EXPECT_NE(nullptr, Next); 319 EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress); 320 321 Current = Analysis.getInstruction(0xDEADBEEF + 1); 322 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 323 324 Current = Analysis.getInstruction(0xDEADBEEF + 3); 325 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 326 327 Current = Analysis.getInstruction(0xDEADBEEF + 4); 328 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 329 330 Current = Analysis.getInstruction(0xDEADBEEF + 6); 331 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 332 333 Current = Analysis.getInstruction(0xDEADBEEF + 8); 334 Next = Analysis.getDefiniteNextInstruction(*Current); 335 EXPECT_NE(nullptr, Next); 336 EXPECT_EQ(0xDEADBEEF + 10, Next->VMAddress); 337 338 Current = Analysis.getInstruction(0xDEADBEEF + 10); 339 Next = Analysis.getDefiniteNextInstruction(*Current); 340 EXPECT_NE(nullptr, Next); 341 EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress); 342 343 Current = Analysis.getInstruction(0xDEADBEEF + 12); 344 Next = Analysis.getDefiniteNextInstruction(*Current); 345 EXPECT_NE(nullptr, Next); 346 EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress); 347 348 Current = Analysis.getInstruction(0xDEADBEEF + 17); 349 // Note, definite next instruction address is out of range and should fail. 350 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 351 Next = Analysis.getDefiniteNextInstruction(*Current); 352 353 Current = Analysis.getInstruction(0xDEADBEEF + 22); 354 Next = Analysis.getDefiniteNextInstruction(*Current); 355 EXPECT_NE(nullptr, Next); 356 EXPECT_EQ(0xDEADBEEF + 31, Next->VMAddress); 357 358 Current = Analysis.getInstruction(0xDEADBEEF + 27); 359 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 360 Current = Analysis.getInstruction(0xDEADBEEF + 29); 361 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 362 Current = Analysis.getInstruction(0xDEADBEEF + 31); 363 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 364 Current = Analysis.getInstruction(0xDEADBEEF + 33); 365 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 366 367 Current = Analysis.getInstruction(0xDEADBEEF + 34); 368 Next = Analysis.getDefiniteNextInstruction(*Current); 369 EXPECT_NE(nullptr, Next); 370 EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress); 371 372 Current = Analysis.getInstruction(0xDEADBEEF + 36); 373 EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current)); 374 375 Current = Analysis.getInstruction(0xDEADBEEF + 38); 376 Next = Analysis.getDefiniteNextInstruction(*Current); 377 EXPECT_NE(nullptr, Next); 378 EXPECT_EQ(0xDEADBEEF + 4, Next->VMAddress); 379 } 380 381 TEST_F(BasicFileAnalysisTest, ControlFlowXRefsTest) { 382 if (!SuccessfullyInitialised) 383 return; 384 Analysis.parseSectionContents( 385 { 386 0x90, // 0: nop 387 0xb0, 0x00, // 1: mov $0x0, %al 388 0x2f, // 3: (bad) 389 0x0f, 0x0b, // 4: ud2 390 0xff, 0x20, // 6: jmpq *(%rax) 391 0xeb, 0x00, // 8: jmp 10 [+0] 392 0xeb, 0x05, // 10: jmp 17 [+5] 393 0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0] 394 0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678] 395 0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4] 396 0xff, 0x10, // 27: callq *(rax) 397 0x75, 0x00, // 29: jne 31 [+0] 398 0x75, 0xe0, // 31: jne 1 [-32] 399 0xc3, // 33: retq 400 0xeb, 0xdd, // 34: jmp 1 [-35] 401 0xeb, 0xdd, // 36: jmp 3 [-35] 402 0xeb, 0xdc, // 38: jmp 4 [-36] 403 }, 404 0xDEADBEEF); 405 const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF); 406 std::set<const Instr *> XRefs = 407 Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 408 EXPECT_TRUE(XRefs.empty()); 409 410 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 1); 411 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 412 EXPECT_THAT(XRefs, UnorderedElementsAre( 413 Field(&Instr::VMAddress, Eq(0xDEADBEEF)), 414 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31)), 415 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 34)))); 416 417 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 3); 418 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 419 EXPECT_THAT(XRefs, UnorderedElementsAre( 420 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 1)), 421 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 36)))); 422 423 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 4); 424 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 425 EXPECT_THAT(XRefs, UnorderedElementsAre( 426 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 38)))); 427 428 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 6); 429 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 430 431 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 8); 432 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 433 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 434 435 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 10); 436 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 437 EXPECT_THAT(XRefs, UnorderedElementsAre( 438 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 8)))); 439 440 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 12); 441 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 442 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 443 444 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 17); 445 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 446 EXPECT_THAT(XRefs, UnorderedElementsAre( 447 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 10)), 448 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 12)))); 449 450 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 22); 451 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 452 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 453 454 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 27); 455 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 456 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 457 458 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 29); 459 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 460 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 461 462 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 31); 463 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 464 EXPECT_THAT(XRefs, UnorderedElementsAre( 465 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 22)), 466 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 29)))); 467 468 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 33); 469 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 470 EXPECT_THAT(XRefs, UnorderedElementsAre( 471 Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31)))); 472 473 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 34); 474 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 475 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 476 477 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 36); 478 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 479 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 480 481 InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 38); 482 XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr); 483 EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty()); 484 } 485 486 TEST_F(BasicFileAnalysisTest, CFIProtectionInvalidTargets) { 487 if (!SuccessfullyInitialised) 488 return; 489 Analysis.parseSectionContents( 490 { 491 0x90, // 0: nop 492 0x0f, 0x0b, // 1: ud2 493 0x75, 0x00, // 3: jne 5 [+0] 494 }, 495 0xDEADBEEF); 496 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF); 497 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, 498 Analysis.validateCFIProtection(Result)); 499 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1); 500 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, 501 Analysis.validateCFIProtection(Result)); 502 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); 503 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF, 504 Analysis.validateCFIProtection(Result)); 505 Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678); 506 EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION, 507 Analysis.validateCFIProtection(Result)); 508 } 509 510 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicFallthroughToUd2) { 511 if (!SuccessfullyInitialised) 512 return; 513 Analysis.parseSectionContents( 514 { 515 0x75, 0x02, // 0: jne 4 [+2] 516 0x0f, 0x0b, // 2: ud2 517 0xff, 0x10, // 4: callq *(%rax) 518 }, 519 0xDEADBEEF); 520 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); 521 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 522 Analysis.validateCFIProtection(Result)); 523 } 524 525 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicJumpToUd2) { 526 if (!SuccessfullyInitialised) 527 return; 528 Analysis.parseSectionContents( 529 { 530 0x75, 0x02, // 0: jne 4 [+2] 531 0xff, 0x10, // 2: callq *(%rax) 532 0x0f, 0x0b, // 4: ud2 533 }, 534 0xDEADBEEF); 535 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); 536 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 537 Analysis.validateCFIProtection(Result)); 538 } 539 540 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathUd2) { 541 if (!SuccessfullyInitialised) 542 return; 543 Analysis.parseSectionContents( 544 { 545 0x75, 0x03, // 0: jne 5 [+3] 546 0x90, // 2: nop 547 0xff, 0x10, // 3: callq *(%rax) 548 0x0f, 0x0b, // 5: ud2 549 0x75, 0xf9, // 7: jne 2 [-7] 550 0x0f, 0x0b, // 9: ud2 551 }, 552 0xDEADBEEF); 553 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); 554 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 555 Analysis.validateCFIProtection(Result)); 556 } 557 558 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathSingleUd2) { 559 if (!SuccessfullyInitialised) 560 return; 561 Analysis.parseSectionContents( 562 { 563 0x75, 0x05, // 0: jne 7 [+5] 564 0x90, // 2: nop 565 0xff, 0x10, // 3: callq *(%rax) 566 0x75, 0xfb, // 5: jne 2 [-5] 567 0x0f, 0x0b, // 7: ud2 568 }, 569 0xDEADBEEF); 570 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3); 571 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 572 Analysis.validateCFIProtection(Result)); 573 } 574 575 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitUpwards) { 576 if (!SuccessfullyInitialised) 577 return; 578 Analysis.parseSectionContents( 579 { 580 0x75, 0x06, // 0: jne 8 [+6] 581 0x90, // 2: nop 582 0x90, // 3: nop 583 0x90, // 4: nop 584 0x90, // 5: nop 585 0xff, 0x10, // 6: callq *(%rax) 586 0x0f, 0x0b, // 8: ud2 587 }, 588 0xDEADBEEF); 589 uint64_t PrevSearchLengthForConditionalBranch = 590 SearchLengthForConditionalBranch; 591 SearchLengthForConditionalBranch = 2; 592 593 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6); 594 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, 595 Analysis.validateCFIProtection(Result)); 596 597 SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch; 598 } 599 600 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitDownwards) { 601 if (!SuccessfullyInitialised) 602 return; 603 Analysis.parseSectionContents( 604 { 605 0x75, 0x02, // 0: jne 4 [+2] 606 0xff, 0x10, // 2: callq *(%rax) 607 0x90, // 4: nop 608 0x90, // 5: nop 609 0x90, // 6: nop 610 0x90, // 7: nop 611 0x0f, 0x0b, // 8: ud2 612 }, 613 0xDEADBEEF); 614 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 615 SearchLengthForUndef = 2; 616 617 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2); 618 EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH, 619 Analysis.validateCFIProtection(Result)); 620 621 SearchLengthForUndef = PrevSearchLengthForUndef; 622 } 623 624 TEST_F(BasicFileAnalysisTest, CFIProtectionGoodAndBadPaths) { 625 if (!SuccessfullyInitialised) 626 return; 627 Analysis.parseSectionContents( 628 { 629 0xeb, 0x02, // 0: jmp 4 [+2] 630 0x75, 0x02, // 2: jne 6 [+2] 631 0xff, 0x10, // 4: callq *(%rax) 632 0x0f, 0x0b, // 6: ud2 633 }, 634 0xDEADBEEF); 635 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); 636 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, 637 Analysis.validateCFIProtection(Result)); 638 } 639 640 TEST_F(BasicFileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) { 641 if (!SuccessfullyInitialised) 642 return; 643 Analysis.parseSectionContents( 644 { 645 0x75, 0x04, // 0: jne 6 [+4] 646 0xeb, 0x00, // 2: jmp 4 [+0] 647 0xff, 0x10, // 4: callq *(%rax) 648 0x0f, 0x0b, // 6: ud2 649 }, 650 0xDEADBEEF); 651 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); 652 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 653 Analysis.validateCFIProtection(Result)); 654 } 655 656 TEST_F(BasicFileAnalysisTest, CFIProtectionComplexExample) { 657 if (!SuccessfullyInitialised) 658 return; 659 // See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this 660 // graph. 661 Analysis.parseSectionContents( 662 { 663 0x75, 0x12, // 0: jne 20 [+18] 664 0xeb, 0x03, // 2: jmp 7 [+3] 665 0x75, 0x10, // 4: jne 22 [+16] 666 0x90, // 6: nop 667 0x90, // 7: nop 668 0x90, // 8: nop 669 0xff, 0x10, // 9: callq *(%rax) 670 0xeb, 0xfc, // 11: jmp 9 [-4] 671 0x75, 0xfa, // 13: jne 9 [-6] 672 0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678] 673 0x90, // 20: nop 674 0x90, // 21: nop 675 0x0f, 0x0b, // 22: ud2 676 }, 677 0xDEADBEEF); 678 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 679 SearchLengthForUndef = 5; 680 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9); 681 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS, 682 Analysis.validateCFIProtection(Result)); 683 SearchLengthForUndef = PrevSearchLengthForUndef; 684 } 685 686 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTest) { 687 Analysis.parseSectionContents( 688 { 689 0x77, 0x0d, // 0x688118: ja 0x688127 [+12] 690 0x48, 0x89, 0xdf, // 0x68811a: mov %rbx, %rdi 691 0xff, 0xd0, // 0x68811d: callq *%rax 692 0x48, 0x89, 0xdf, // 0x68811f: mov %rbx, %rdi 693 0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130 694 0x0f, 0x0b, // 0x688127: ud2 695 }, 696 0x688118); 697 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 698 SearchLengthForUndef = 1; 699 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d); 700 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 701 Analysis.validateCFIProtection(Result)); 702 SearchLengthForUndef = PrevSearchLengthForUndef; 703 } 704 705 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTestFarAway) { 706 Analysis.parseSectionContents( 707 { 708 0x74, 0x73, // 0x7759eb: je 0x775a60 709 0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e 710 }, 711 0x7759eb); 712 713 Analysis.parseSectionContents( 714 { 715 0x0f, 0x85, 0xb2, 0x03, 0x00, 0x00, // 0x775a56: jne 0x775e0e 716 0x48, 0x83, 0xc3, 0xf4, // 0x775a5c: add $0xfffffffffffffff4,%rbx 717 0x48, 0x8b, 0x7c, 0x24, 0x10, // 0x775a60: mov 0x10(%rsp),%rdi 718 0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi 719 0xff, 0xd1, // 0x775a68: callq *%rcx 720 }, 721 0x775a56); 722 723 Analysis.parseSectionContents( 724 { 725 0x0f, 0x0b, // 0x775e0e: ud2 726 }, 727 0x775e0e); 728 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 729 SearchLengthForUndef = 1; 730 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); 731 EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH, 732 Analysis.validateCFIProtection(Result)); 733 SearchLengthForUndef = 2; 734 Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); 735 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 736 Analysis.validateCFIProtection(Result)); 737 SearchLengthForUndef = 3; 738 Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68); 739 EXPECT_EQ(CFIProtectionStatus::PROTECTED, 740 Analysis.validateCFIProtection(Result)); 741 SearchLengthForUndef = PrevSearchLengthForUndef; 742 } 743 744 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit) { 745 if (!SuccessfullyInitialised) 746 return; 747 Analysis.parseSectionContents( 748 { 749 0x75, 0x02, // 0: jne 4 [+2] 750 0x0f, 0x0b, // 2: ud2 751 0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax 752 0xff, 0x10, // 10: callq *(%rax) 753 }, 754 0xDEADBEEF); 755 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10); 756 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, 757 Analysis.validateCFIProtection(Result)); 758 } 759 760 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) { 761 if (!SuccessfullyInitialised) 762 return; 763 Analysis.parseSectionContents( 764 { 765 0x75, 0x02, // 0: jne 4 [+2] 766 0x0f, 0x0b, // 2: ud2 767 0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax 768 0xff, 0x10, // 8: callq *(%rax) 769 }, 770 0xDEADBEEF); 771 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8); 772 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, 773 Analysis.validateCFIProtection(Result)); 774 } 775 776 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathImplicit) { 777 if (!SuccessfullyInitialised) 778 return; 779 Analysis.parseSectionContents( 780 { 781 0x75, 0x02, // 0: jne 4 [+2] 782 0x0f, 0x0b, // 2: ud2 783 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax 784 0xff, 0x10, // 9: callq *(%rax) 785 }, 786 0xDEADBEEF); 787 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9); 788 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, 789 Analysis.validateCFIProtection(Result)); 790 } 791 792 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberDualPathImplicit) { 793 if (!SuccessfullyInitialised) 794 return; 795 Analysis.parseSectionContents( 796 { 797 0x75, 0x04, // 0: jne 6 [+4] 798 0x0f, 0x31, // 2: rdtsc (note: affects eax) 799 0xff, 0x10, // 4: callq *(%rax) 800 0x0f, 0x0b, // 6: ud2 801 0x75, 0xf9, // 8: jne 2 [-7] 802 0x0f, 0x0b, // 10: ud2 803 }, 804 0xDEADBEEF); 805 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4); 806 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED, 807 Analysis.validateCFIProtection(Result)); 808 } 809 810 } // anonymous namespace 811 } // end namespace cfi_verify 812 } // end namespace llvm 813 814 int main(int argc, char **argv) { 815 ::testing::InitGoogleTest(&argc, argv); 816 llvm::cl::ParseCommandLineOptions(argc, argv); 817 818 llvm::InitializeAllTargetInfos(); 819 llvm::InitializeAllTargetMCs(); 820 llvm::InitializeAllAsmParsers(); 821 llvm::InitializeAllDisassemblers(); 822 823 return RUN_ALL_TESTS(); 824 } 825