Static Value-Flow Analysis
AEDetector.h
Go to the documentation of this file.
1 //===- AEDetector.h -- Vulnerability Detectors---------------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 
24 //
25 // Created by Jiawei Wang on 2024/8/20.
26 //
27 #pragma once
28 #include <SVFIR/SVFIR.h>
29 #include <AE/Core/AbstractState.h>
30 #include "Util/SVFBugReport.h"
31 
32 namespace SVF
33 {
39 {
40 public:
46  {
49  };
50 
55 
59  virtual ~AEDetector() = default;
60 
66  static bool classof(const AEDetector* detector)
67  {
68  return detector->getKind() == AEDetector::UNKNOWN;
69  }
70 
76  virtual void detect(AbstractState& as, const ICFGNode* node) = 0;
77 
82  virtual void handleStubFunctions(const CallICFGNode* call) = 0;
83 
87  virtual void reportBug() = 0;
88 
94  {
95  return kind;
96  }
97 
98 protected:
100 };
101 
106 class AEException : public std::exception
107 {
108 public:
113  AEException(const std::string& message)
114  : msg_(message) {}
115 
120  virtual const char* what() const throw()
121  {
122  return msg_.c_str();
123  }
124 
125 private:
127 };
128 
134 {
136 public:
141  {
142  kind = BUF_OVERFLOW;
144  }
145 
149  ~BufOverflowDetector() = default;
150 
156  static bool classof(const AEDetector* detector)
157  {
158  return detector->getKind() == AEDetector::BUF_OVERFLOW;
159  }
160 
168  AddressValue objAddrs,
170 
176  void detect(AbstractState& as, const ICFGNode*);
177 
178 
183  void handleStubFunctions(const CallICFGNode*);
184 
191  {
193  }
194 
200  bool hasGepObjOffsetFromBase(const GepObjVar* obj) const
201  {
202  return gepObjOffsetFromBase.find(obj) != gepObjOffsetFromBase.end();
203  }
204 
211  {
212  if (hasGepObjOffsetFromBase(obj))
213  return gepObjOffsetFromBase.at(obj);
214  else
215  assert(false && "GepObjVar not found in gepObjOffsetFromBase");
216  }
217 
225  IntervalValue getAccessOffset(AbstractState& as, NodeID objId, const GepStmt* gep);
226 
232  void addBugToReporter(const AEException& e, const ICFGNode* node)
233  {
234 
235  GenericBug::EventStack eventStack;
236  SVFBugEvent sourceInstEvent(SVFBugEvent::EventType::SourceInst, node);
237  eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
238 
239  if (eventStack.empty())
240  {
241  return; // If the event stack is empty, return early
242  }
243 
244  std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
245 
246  // Check if the bug at this location has already been reported
247  if (bugLoc.find(loc) != bugLoc.end())
248  {
249  return; // If the bug location is already reported, return early
250  }
251  else
252  {
253  bugLoc.insert(loc); // Otherwise, mark this location as reported
254  }
255 
256  // Add the bug to the recorder with details from the event stack
257  recoder.addAbsExecBug(GenericBug::FULLBUFOVERFLOW, eventStack, 0, 0, 0, 0);
258  nodeToBugInfo[node] = e.what(); // Record the exception information for the node
259  }
260 
264  void reportBug()
265  {
266  if (!nodeToBugInfo.empty())
267  {
268  std::cerr << "######################Buffer Overflow (" + std::to_string(nodeToBugInfo.size())
269  + " found)######################\n";
270  std::cerr << "---------------------------------------------\n";
271  for (const auto& it : nodeToBugInfo)
272  {
273  std::cerr << it.second << "\n---------------------------------------------\n";
274  }
275  }
276  }
277 
282 
288  void detectExtAPI(AbstractState& as, const CallICFGNode *call);
289 
297  bool canSafelyAccessMemory(AbstractState& as, const SVFVar *value, const IntervalValue &len);
298 
299 private:
306  bool detectStrcat(AbstractState& as, const CallICFGNode *call);
307 
314  bool detectStrcpy(AbstractState& as, const CallICFGNode *call);
315 
316 private:
322 };
323 }
buffer offset
Definition: cJSON.cpp:1113
const char *const string
Definition: cJSON.h:172
Base class for all detectors.
Definition: AEDetector.h:39
static bool classof(const AEDetector *detector)
Check if the detector is of the UNKNOWN kind.
Definition: AEDetector.h:66
DetectorKind
Enumerates the types of detectors available.
Definition: AEDetector.h:46
@ UNKNOWN
Default type if the kind is not specified.
Definition: AEDetector.h:48
@ BUF_OVERFLOW
Detector for buffer overflow issues.
Definition: AEDetector.h:47
virtual void handleStubFunctions(const CallICFGNode *call)=0
Pure virtual function for handling stub external API calls. (e.g. UNSAFE_BUFACCESS)
DetectorKind kind
The kind of the detector.
Definition: AEDetector.h:99
virtual void reportBug()=0
Pure virtual function to report detected bugs.
AEDetector()
Constructor initializes the detector kind to UNKNOWN.
Definition: AEDetector.h:54
virtual ~AEDetector()=default
Virtual destructor for safe polymorphic use.
DetectorKind getKind() const
Get the kind of the detector.
Definition: AEDetector.h:93
virtual void detect(AbstractState &as, const ICFGNode *node)=0
Pure virtual function for detecting issues within a node.
Exception class for handling errors in Abstract Execution.
Definition: AEDetector.h:107
AEException(const std::string &message)
Constructor initializes the exception with a message.
Definition: AEDetector.h:113
virtual const char * what() const
Provides the error message.
Definition: AEDetector.h:120
std::string msg_
The error message.
Definition: AEDetector.h:126
AbstractInterpretation is same as Abstract Execution.
Detector for identifying buffer overflow issues.
Definition: AEDetector.h:134
IntervalValue getAccessOffset(AbstractState &as, NodeID objId, const GepStmt *gep)
Retrieves the access offset for a given object and GEP statement.
Definition: AEDetector.cpp:314
void addToGepObjOffsetFromBase(const GepObjVar *obj, const IntervalValue &offset)
Adds an offset to a GEP object.
Definition: AEDetector.h:190
~BufOverflowDetector()=default
Destructor.
Map< const GepObjVar *, IntervalValue > gepObjOffsetFromBase
Maps GEP objects to their offsets from the base.
Definition: AEDetector.h:317
Map< std::string, std::vector< std::pair< u32_t, u32_t > > > extAPIBufOverflowCheckRules
Rules for checking buffer overflows in external APIs.
Definition: AEDetector.h:318
void detect(AbstractState &as, const ICFGNode *)
Detect buffer overflow issues within a node.
Definition: AEDetector.cpp:44
bool detectStrcpy(AbstractState &as, const CallICFGNode *call)
Detects buffer overflow in 'strcpy' function calls.
Definition: AEDetector.cpp:397
SVFBugReport recoder
Recorder for abstract execution bugs.
Definition: AEDetector.h:320
BufOverflowDetector()
Constructor initializes the detector kind to BUF_OVERFLOW and sets up external API buffer overflow ru...
Definition: AEDetector.h:140
bool detectStrcat(AbstractState &as, const CallICFGNode *call)
Detects buffer overflow in 'strcat' function calls.
Definition: AEDetector.cpp:415
Set< std::string > bugLoc
Set of locations where bugs have been reported.
Definition: AEDetector.h:319
IntervalValue getGepObjOffsetFromBase(const GepObjVar *obj) const
Retrieves the offset of a GEP object from its base.
Definition: AEDetector.h:210
static bool classof(const AEDetector *detector)
Check if the detector is of the BUF_OVERFLOW kind.
Definition: AEDetector.h:156
void reportBug()
Reports all detected buffer overflow bugs.
Definition: AEDetector.h:264
Map< const ICFGNode *, std::string > nodeToBugInfo
Maps ICFG nodes to bug information.
Definition: AEDetector.h:321
void handleStubFunctions(const CallICFGNode *)
Handles external API calls related to buffer overflow detection.
Definition: AEDetector.cpp:114
bool hasGepObjOffsetFromBase(const GepObjVar *obj) const
Checks if a GEP object has an associated offset.
Definition: AEDetector.h:200
void updateGepObjOffsetFromBase(AddressValue gepAddrs, AddressValue objAddrs, IntervalValue offset)
Updates the offset of a GEP object from its base.
Definition: AEDetector.cpp:346
bool canSafelyAccessMemory(AbstractState &as, const SVFVar *value, const IntervalValue &len)
Checks if memory can be safely accessed.
Definition: AEDetector.cpp:456
void initExtAPIBufOverflowCheckRules()
Initializes external API buffer overflow check rules.
Definition: AEDetector.cpp:186
void detectExtAPI(AbstractState &as, const CallICFGNode *call)
Handles external API calls related to buffer overflow detection.
Definition: AEDetector.cpp:220
void addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
Definition: AEDetector.h:232
std::vector< SVFBugEvent > EventStack
Definition: SVFBugReport.h:83
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack, s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound)
Definition: SVFBugReport.h:367
for isBitcode
Definition: BasicTypes.h:68
u32_t NodeID
Definition: GeneralType.h:55
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96