|
5 | 5 | // #include "polytracker/thread_pool.h" |
6 | 6 | #include "spdlog/cfg/env.h" |
7 | 7 | #include "spdlog/spdlog.h" |
| 8 | +#include "llvm/IR/Argument.h" |
8 | 9 | #include "llvm/IR/BasicBlock.h" |
9 | 10 | #include "llvm/IR/Dominators.h" |
10 | 11 | #include "llvm/IR/Function.h" |
@@ -289,12 +290,54 @@ bool PolytrackerPass::analyzeBlock(llvm::Function *func, |
289 | 290 | return true; |
290 | 291 | } |
291 | 292 |
|
| 293 | +// Inserts a function call to polytracker::taint_argv(argc, argv) |
| 294 | +// Assumes main is actually the main function of the program and |
| 295 | +// interprets first arg as argc and second as argv. |
| 296 | +static void emitTaintArgvCall(llvm::Function &main) { |
| 297 | + // Get the parameters of the main function, argc, argv |
| 298 | + auto argc = main.getArg(0); |
| 299 | + if (!argc) { |
| 300 | + spdlog::error("Failed to instrument argv. No argc available."); |
| 301 | + return; |
| 302 | + } |
| 303 | + auto argc_ty = argc->getType(); |
| 304 | + |
| 305 | + auto argv = main.getArg(1); |
| 306 | + if (!argv) { |
| 307 | + spdlog::error("Failed to instrument argv. No argv available."); |
| 308 | + return; |
| 309 | + } |
| 310 | + auto argv_ty = argv->getType(); |
| 311 | + |
| 312 | + // IRBuilder for emitting a call to __polytracker_taint_argv. Need to |
| 313 | + // specify insertion point first, to ensure that no instruction can |
| 314 | + // use argv before it is tainted. |
| 315 | + llvm::IRBuilder<> irb(&*(main.getEntryBlock().getFirstInsertionPt())); |
| 316 | + |
| 317 | + // Define the target function type and make it available in the module |
| 318 | + auto taint_argv_ty = |
| 319 | + llvm::FunctionType::get(irb.getVoidTy(), {argc_ty, argv_ty}, false); |
| 320 | + llvm::FunctionCallee taint_argv = main.getParent()->getOrInsertFunction( |
| 321 | + "__polytracker_taint_argv", taint_argv_ty); |
| 322 | + if (!taint_argv) { |
| 323 | + spdlog::error("Failed to declare __polytracker_taint_argv."); |
| 324 | + return; |
| 325 | + } |
| 326 | + |
| 327 | + // Emit the call using parameters from main. |
| 328 | + auto ci = irb.CreateCall(taint_argv, {argc, argv}); |
| 329 | + if (!ci) { |
| 330 | + spdlog::error("Failed to insert call to taint_argv."); |
| 331 | + } |
| 332 | +} |
| 333 | + |
292 | 334 | /* |
293 | 335 | We should instrument everything we have bitcode for, right? |
294 | 336 | If instructions have __polytracker, or they have __dfsan, ignore! |
295 | 337 | */ |
296 | 338 | bool PolytrackerPass::analyzeFunction(llvm::Function *f, |
297 | 339 | const func_index_t &func_index) { |
| 340 | + |
298 | 341 | // Add Function entry |
299 | 342 | polytracker::BBSplittingPass bbSplitter; |
300 | 343 | // llvm::removeUnreachableBlocks(*f); |
@@ -340,6 +383,11 @@ bool PolytrackerPass::analyzeFunction(llvm::Function *f, |
340 | 383 | visit(inst); |
341 | 384 | } |
342 | 385 |
|
| 386 | + // If this is the main function, insert a taint-argv call |
| 387 | + if (f && f->getName() == "main") { |
| 388 | + emitTaintArgvCall(*f); |
| 389 | + } |
| 390 | + |
343 | 391 | return true; |
344 | 392 | } |
345 | 393 |
|
|
0 commit comments