1515#include " phasar/PhasarLLVM/Utils/Annotation.h"
1616#include " phasar/PhasarLLVM/Utils/LLVMShorthands.h"
1717#include " phasar/Utils/Logger.h"
18- #include " phasar/Utils/NlohmannLogging.h"
1918
2019#include " llvm/IR/DebugInfo.h"
2120#include " llvm/IR/Function.h"
2221#include " llvm/IR/InstIterator.h"
2322#include " llvm/IR/IntrinsicInst.h"
2423
24+ #include < string>
25+
2526namespace psr {
2627
2728static llvm::SmallVector<const llvm::Function *>
@@ -59,9 +60,9 @@ findAllFunctionDefs(const LLVMProjectIRDB &IRDB, llvm::StringRef Name) {
5960}
6061
6162void LLVMTaintConfig::addAllFunctions (const LLVMProjectIRDB &IRDB,
62- const nlohmann::json &Config) {
63- for (const auto &FunDesc : Config[ " functions " ] ) {
64- auto Name = FunDesc[ " name " ]. get <std::string>() ;
63+ const TaintConfigData &Config) {
64+ for (const auto &FunDesc : Config. Functions ) {
65+ const auto & Name = FunDesc. Name ;
6566
6667 auto FnDefs = findAllFunctionDefs (IRDB, Name);
6768
@@ -72,127 +73,105 @@ void LLVMTaintConfig::addAllFunctions(const LLVMProjectIRDB &IRDB,
7273
7374 const auto *Fun = FnDefs[0 ];
7475
75- // handle a function's parameters
76- if (FunDesc.contains (" params" )) {
77- auto Params = FunDesc[" params" ];
78- if (Params.contains (" source" )) {
79- for (unsigned Idx : Params[" source" ]) {
80- if (Idx >= Fun->arg_size ()) {
81- llvm::errs ()
82- << " ERROR: The source-function parameter index is out of "
83- " bounds: "
84- << Idx << " \n " ;
85- // Use 'continue' instead of 'break' to get error messages for the
86- // remaining parameters as well
87- continue ;
88- }
89- addTaintCategory (Fun->getArg (Idx), TaintCategory::Source);
90- }
76+ // handle a function's source parameters
77+ for (const auto &Idx : FunDesc.SourceValues ) {
78+ if (Idx >= Fun->arg_size ()) {
79+ llvm::errs () << " ERROR: The source-function parameter index is out of "
80+ " bounds: "
81+ << Idx << " \n " ;
82+ // Use 'continue' instead of 'break' to get error messages for the
83+ // remaining parameters as well
84+ continue ;
9185 }
92- if (Params.contains (" sink" )) {
93- for (const auto &Idx : Params[" sink" ]) {
94- if (Idx.is_number ()) {
95- if (Idx >= Fun->arg_size ()) {
96- llvm::errs ()
97- << " ERROR: The source-function parameter index is out of "
98- " bounds: "
99- << Idx << " \n " ;
100- continue ;
101- }
102- addTaintCategory (Fun->getArg (Idx), TaintCategory::Sink);
103- } else if (Idx.is_string ()) {
104- const auto Sinks = Idx.get <std::string>();
105- if (Sinks == " all" ) {
106- for (const auto &Arg : Fun->args ()) {
107- addTaintCategory (&Arg, TaintCategory::Sink);
108- }
109- }
110- }
111- }
86+
87+ addTaintCategory (Fun->getArg (Idx), TaintCategory::Source);
88+ }
89+ for (const auto &Idx : FunDesc.SinkValues ) {
90+ if (Idx >= Fun->arg_size ()) {
91+ llvm::errs () << " ERROR: The sink-function parameter index is out of "
92+ " bounds: "
93+ << Idx << " \n " ;
94+ continue ;
11295 }
113- if (Params.contains (" sanitizer" )) {
114- for (unsigned Idx : Params[" sanitizer" ]) {
115- if (Idx >= Fun->arg_size ()) {
116- llvm::errs ()
117- << " ERROR: The source-function parameter index is out of "
118- " bounds: "
119- << Idx << " \n " ;
120- continue ;
121- }
122- addTaintCategory (Fun->getArg (Idx), TaintCategory::Sanitizer);
123- }
96+
97+ addTaintCategory (Fun->getArg (Idx), TaintCategory::Sink);
98+ }
99+
100+ if (FunDesc.HasAllSinkParam ) {
101+ for (const auto &Arg : Fun->args ()) {
102+ addTaintCategory (&Arg, TaintCategory::Sink);
124103 }
125104 }
126- // handle a function's return value
127- if (FunDesc.contains (" ret" )) {
128- for (const auto &User : Fun->users ()) {
129- addTaintCategory (User, FunDesc[" ret" ].get <std::string>());
105+
106+ for (const auto &Idx : FunDesc.SanitizerValues ) {
107+ if (Idx >= Fun->arg_size ()) {
108+ llvm::errs ()
109+ << " ERROR: The sanitizer-function parameter index is out of "
110+ " bounds: "
111+ << Idx << " \n " ;
112+ continue ;
130113 }
114+ addTaintCategory (Fun->getArg (Idx), TaintCategory::Sanitizer);
115+ }
116+ // handle a function's return value
117+ for (const auto &User : Fun->users ()) {
118+ addTaintCategory (User, FunDesc.ReturnCat );
131119 }
132120 }
133121}
134122
135123LLVMTaintConfig::LLVMTaintConfig (const psr::LLVMProjectIRDB &Code,
136- const nlohmann::json &Config) {
124+ const TaintConfigData &Config) {
137125 // handle functions
138- if (Config.contains (" functions" )) {
139- addAllFunctions (Code, Config);
140- }
126+ addAllFunctions (Code, Config);
141127
142128 // handle variables
143- if (Config.contains (" variables" )) {
144- // scope can be a function name or a struct.
145- std::unordered_map<const llvm::Type *, const nlohmann::json>
146- StructConfigMap;
147-
148- // read all struct types from config
149- for (const auto &VarDesc : Config[" variables" ]) {
150- llvm::DebugInfoFinder DIF;
151- const auto *M = Code.getModule ();
152-
153- DIF.processModule (*M);
154- for (const auto &Ty : DIF.types ()) {
155- if (Ty->getTag () == llvm::dwarf::DW_TAG_structure_type &&
156- Ty->getName ().equals (VarDesc[" scope" ].get <std::string>())) {
157- for (const auto &LlvmStructTy : M->getIdentifiedStructTypes ()) {
158- StructConfigMap.insert (
159- std::pair<const llvm::Type *, const nlohmann::json>(
160- LlvmStructTy, VarDesc));
161- }
129+ // scope can be a function name or a struct.
130+ std::unordered_map<const llvm::Type *, const std::string> StructConfigMap;
131+
132+ // read all struct types from config
133+ size_t Counter = 0 ;
134+ for (const auto &VarDesc : Config.Variables ) {
135+ llvm::DebugInfoFinder DIF;
136+ const auto *M = Code.getModule ();
137+
138+ DIF.processModule (*M);
139+ for (const auto &Ty : DIF.types ()) {
140+ if (Ty->getTag () == llvm::dwarf::DW_TAG_structure_type &&
141+ Ty->getName ().equals (VarDesc.Scope )) {
142+ for (const auto &LlvmStructTy : M->getIdentifiedStructTypes ()) {
143+ StructConfigMap.insert (
144+ std::pair<const llvm::Type *, const std::string>(LlvmStructTy,
145+ VarDesc.Name ));
162146 }
163147 }
164- DIF.reset ();
165148 }
166-
167- // add corresponding Allocas or getElementPtr instructions to the taint
168- // category
169- for (const auto &VarDesc : Config[" variables" ]) {
170- for (const auto &Fun : Code.getAllFunctions ()) {
171- for (const auto &I : llvm::instructions (Fun)) {
172- if (const auto *DbgDeclare =
173- llvm::dyn_cast<llvm::DbgDeclareInst>(&I)) {
174- const llvm::DILocalVariable *LocalVar = DbgDeclare->getVariable ();
175- // matching line number with for Allocas
176- if (LocalVar->getName ().equals (
177- VarDesc[" name" ].get <std::string>()) &&
178- LocalVar->getLine () == VarDesc[" line" ].get <unsigned int >()) {
179- addTaintCategory (DbgDeclare->getAddress (),
180- VarDesc[" cat" ].get <std::string>());
181- }
182- } else if (!StructConfigMap.empty ()) {
183- // Ignorning line numbers for getElementPtr instructions
184- if (const auto *Gep = llvm::dyn_cast<llvm::GetElementPtrInst>(&I)) {
185- const auto *StType = llvm::dyn_cast<llvm::StructType>(
186- Gep->getPointerOperandType ()->getPointerElementType ());
187- if (StType && StructConfigMap.count (StType)) {
188- const auto VarDesc = StructConfigMap.at (StType);
189- auto VarName = VarDesc[" name" ].get <std::string>();
190- // using substr to cover the edge case in which same variable
191- // name is present as a local variable and also as a struct
192- // member variable. (Ex. JsonConfig/fun_member_02.cpp)
193- if (Gep->getName ().substr (0 , VarName.size ()).equals (VarName)) {
194- addTaintCategory (Gep, VarDesc[" cat" ].get <std::string>());
195- }
149+ DIF.reset ();
150+ }
151+ // add corresponding Allocas or getElementPtr instructions to the taint
152+ // category
153+ for (const auto &VarDesc : Config.Variables ) {
154+ for (const auto &Fun : Code.getAllFunctions ()) {
155+ for (const auto &I : llvm::instructions (Fun)) {
156+ if (const auto *DbgDeclare = llvm::dyn_cast<llvm::DbgDeclareInst>(&I)) {
157+ const llvm::DILocalVariable *LocalVar = DbgDeclare->getVariable ();
158+ // matching line number with for Allocas
159+ if (LocalVar->getName ().equals (VarDesc.Name ) &&
160+ LocalVar->getLine () == VarDesc.Line ) {
161+ addTaintCategory (DbgDeclare->getAddress (), VarDesc.Cat );
162+ }
163+ } else if (!StructConfigMap.empty ()) {
164+ // Ignorning line numbers for getElementPtr instructions
165+ if (const auto *Gep = llvm::dyn_cast<llvm::GetElementPtrInst>(&I)) {
166+ const auto *StType = llvm::dyn_cast<llvm::StructType>(
167+ Gep->getPointerOperandType ()->getPointerElementType ());
168+ if (StType && StructConfigMap.count (StType)) {
169+ auto VarName = StructConfigMap.at (StType);
170+ // using substr to cover the edge case in which same variable
171+ // name is present as a local variable and also as a struct
172+ // member variable. (Ex. JsonConfig/fun_member_02.cpp)
173+ if (Gep->getName ().substr (0 , VarName.size ()).equals (VarName)) {
174+ addTaintCategory (Gep, VarDesc.Cat );
196175 }
197176 }
198177 }
0 commit comments