Static Value-Flow Analysis
Loading...
Searching...
No Matches
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 on: May 1, 2025
26// Author: Xiao Cheng, Jiawei Wang, Mingxiu Wang
27//
28#pragma once
29#include <SVFIR/SVFIR.h>
31#include "Util/SVFBugReport.h"
32
33namespace SVF
34{
40{
41public:
52
57
61 virtual ~AEDetector() = default;
62
68 static bool classof(const AEDetector* detector)
69 {
70 return detector->getKind() == AEDetector::UNKNOWN;
71 }
72
78 virtual void detect(AbstractState& as, const ICFGNode* node) = 0;
79
84 virtual void handleStubFunctions(const CallICFGNode* call) = 0;
85
89 virtual void reportBug() = 0;
90
96 {
97 return kind;
98 }
99
100protected:
102};
103
108class AEException : public std::exception
109{
110public:
115 AEException(const std::string& message)
116 : msg_(message) {}
117
122 virtual const char* what() const throw()
123 {
124 return msg_.c_str();
125 }
126
127private:
128 std::string msg_;
129};
130
136{
138public:
147
152
158 static bool classof(const AEDetector* detector)
159 {
160 return detector->getKind() == AEDetector::BUF_OVERFLOW;
161 }
162
174
180 void detect(AbstractState& as, const ICFGNode*);
181
182
188
198
205 {
206 return gepObjOffsetFromBase.find(obj) != gepObjOffsetFromBase.end();
207 }
208
215 {
217 return gepObjOffsetFromBase.at(obj);
218 else
219 {
220 assert(false && "GepObjVar not found in gepObjOffsetFromBase");
221 abort();
222 }
223 }
224
233
239 void addBugToReporter(const AEException& e, const ICFGNode* node)
240 {
241
244 eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
245
246 if (eventStack.empty())
247 {
248 return; // If the event stack is empty, return early
249 }
250
251 std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
252
253 // Check if the bug at this location has already been reported
254 if (bugLoc.find(loc) != bugLoc.end())
255 {
256 return; // If the bug location is already reported, return early
257 }
258 else
259 {
260 bugLoc.insert(loc); // Otherwise, mark this location as reported
261 }
262
263 // Add the bug to the recorder with details from the event stack
265 nodeToBugInfo[node] = e.what(); // Record the exception information for the node
266 }
267
272 {
273 if (!nodeToBugInfo.empty())
274 {
275 std::cerr << "######################Buffer Overflow (" + std::to_string(nodeToBugInfo.size())
276 + " found)######################\n";
277 std::cerr << "---------------------------------------------\n";
278 for (const auto& it : nodeToBugInfo)
279 {
280 std::cerr << it.second << "\n---------------------------------------------\n";
281 }
282 }
283 }
284
289
295 void detectExtAPI(AbstractState& as, const CallICFGNode *call);
296
304 bool canSafelyAccessMemory(AbstractState& as, const SVFVar *value, const IntervalValue &len);
305
306private:
313 bool detectStrcat(AbstractState& as, const CallICFGNode *call);
314
321 bool detectStrcpy(AbstractState& as, const CallICFGNode *call);
322
323private:
329};
331{
333public:
338
340
341 static bool classof(const AEDetector* detector)
342 {
343 return detector->getKind() == AEDetector::NULL_DEREF;
344 }
345
351 void detect(AbstractState& as, const ICFGNode* node);
352
357 void handleStubFunctions(const CallICFGNode* call);
358
365 {
366 // uninitialized value has neither interval value nor address value
367 bool is = v.getAddrs().isBottom() && v.getInterval().isBottom();
368 return is;
369 }
370
376 void addBugToReporter(const AEException& e, const ICFGNode* node)
377 {
380 eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
381
382 if (eventStack.empty())
383 {
384 return; // If the event stack is empty, return early
385 }
386 std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
387
388 // Check if the bug at this location has already been reported
389 if (bugLoc.find(loc) != bugLoc.end())
390 {
391 return; // If the bug location is already reported, return early
392 }
393 else
394 {
395 bugLoc.insert(loc); // Otherwise, mark this location as reported
396 }
398 nodeToBugInfo[node] = e.what(); // Record the exception information for the node
399 }
400
405 {
406 if (!nodeToBugInfo.empty())
407 {
408 std::cerr << "###################### Nullptr Dereference (" + std::to_string(nodeToBugInfo.size())
409 + " found)######################\n";
410 std::cerr << "---------------------------------------------\n";
411 for (const auto& it : nodeToBugInfo)
412 {
413 std::cerr << it.second << "\n---------------------------------------------\n";
414 }
415 }
416 }
417
423 void detectExtAPI(AbstractState& as, const CallICFGNode* call);
424
425
432 {
433 return !v.isAddr() && !v.isInterval();
434 }
435
437
438private:
442};
443}
buffer offset
Definition cJSON.cpp:1113
Base class for all detectors.
Definition AEDetector.h:40
static bool classof(const AEDetector *detector)
Check if the detector is of the UNKNOWN kind.
Definition AEDetector.h:68
DetectorKind
Enumerates the types of detectors available.
Definition AEDetector.h:47
@ NULL_DEREF
Detector for nullptr dereference issues.
Definition AEDetector.h:49
@ UNKNOWN
Default type if the kind is not specified.
Definition AEDetector.h:50
@ BUF_OVERFLOW
Detector for buffer overflow issues.
Definition AEDetector.h:48
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:101
virtual void reportBug()=0
Pure virtual function to report detected bugs.
AEDetector()
Constructor initializes the detector kind to UNKNOWN.
Definition AEDetector.h:56
virtual ~AEDetector()=default
Virtual destructor for safe polymorphic use.
DetectorKind getKind() const
Get the kind of the detector.
Definition AEDetector.h:95
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:109
virtual const char * what() const
Provides the error message.
Definition AEDetector.h:122
AEException(const std::string &message)
Constructor initializes the exception with a message.
Definition AEDetector.h:115
std::string msg_
The error message.
Definition AEDetector.h:128
AbstractInterpretation is same as Abstract Execution.
Detector for identifying buffer overflow issues.
Definition AEDetector.h:136
IntervalValue getAccessOffset(AbstractState &as, NodeID objId, const GepStmt *gep)
Retrieves the access offset for a given object and GEP statement.
void addToGepObjOffsetFromBase(const GepObjVar *obj, const IntervalValue &offset)
Adds an offset to a GEP object.
Definition AEDetector.h:194
~BufOverflowDetector()=default
Destructor.
Map< const GepObjVar *, IntervalValue > gepObjOffsetFromBase
Maps GEP objects to their offsets from the base.
Definition AEDetector.h:324
Map< std::string, std::vector< std::pair< u32_t, u32_t > > > extAPIBufOverflowCheckRules
Rules for checking buffer overflows in external APIs.
Definition AEDetector.h:325
void detect(AbstractState &as, const ICFGNode *)
Detect buffer overflow issues within a node.
bool detectStrcpy(AbstractState &as, const CallICFGNode *call)
Detects buffer overflow in 'strcpy' function calls.
SVFBugReport recoder
Recorder for abstract execution bugs.
Definition AEDetector.h:327
BufOverflowDetector()
Constructor initializes the detector kind to BUF_OVERFLOW and sets up external API buffer overflow ru...
Definition AEDetector.h:142
bool detectStrcat(AbstractState &as, const CallICFGNode *call)
Detects buffer overflow in 'strcat' function calls.
Set< std::string > bugLoc
Set of locations where bugs have been reported.
Definition AEDetector.h:326
IntervalValue getGepObjOffsetFromBase(const GepObjVar *obj) const
Retrieves the offset of a GEP object from its base.
Definition AEDetector.h:214
static bool classof(const AEDetector *detector)
Check if the detector is of the BUF_OVERFLOW kind.
Definition AEDetector.h:158
void reportBug()
Reports all detected buffer overflow bugs.
Definition AEDetector.h:271
Map< const ICFGNode *, std::string > nodeToBugInfo
Maps ICFG nodes to bug information.
Definition AEDetector.h:328
void handleStubFunctions(const CallICFGNode *)
Handles external API calls related to buffer overflow detection.
bool hasGepObjOffsetFromBase(const GepObjVar *obj) const
Checks if a GEP object has an associated offset.
Definition AEDetector.h:204
bool canSafelyAccessMemory(AbstractState &as, const SVFVar *value, const IntervalValue &len)
Checks if memory can be safely accessed.
void initExtAPIBufOverflowCheckRules()
Initializes external API buffer overflow check rules.
void detectExtAPI(AbstractState &as, const CallICFGNode *call)
Handles external API calls related to buffer overflow detection.
void updateGepObjOffsetFromBase(AbstractState &as, AddressValue gepAddrs, AddressValue objAddrs, IntervalValue offset)
Updates the offset of a GEP object from its base.
void addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
Definition AEDetector.h:239
std::vector< SVFBugEvent > EventStack
bool canSafelyDerefPtr(AbstractState &as, const SVFVar *ptr)
Set< std::string > bugLoc
Set of locations where bugs have been reported.
Definition AEDetector.h:439
bool isNull(AbstractValue v)
Check if an Abstract Value is NULL (or uninitialized).
Definition AEDetector.h:431
bool isUninit(AbstractValue v)
Checks if an Abstract Value is uninitialized.
Definition AEDetector.h:364
void detect(AbstractState &as, const ICFGNode *node)
Detects nullptr dereferences issues within a node.
void reportBug()
Reports all detected nullptr dereference bugs.
Definition AEDetector.h:404
static bool classof(const AEDetector *detector)
Definition AEDetector.h:341
void addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
Definition AEDetector.h:376
void handleStubFunctions(const CallICFGNode *call)
Handles external API calls related to nullptr dereferences.
SVFBugReport recoder
Recorder for abstract execution bugs.
Definition AEDetector.h:440
void detectExtAPI(AbstractState &as, const CallICFGNode *call)
Handle external API calls related to nullptr dereferences.
Map< const ICFGNode *, std::string > nodeToBugInfo
Maps ICFG nodes to bug information.
Definition AEDetector.h:441
void addAbsExecBug(GenericBug::BugType bugType, const GenericBug::EventStack &eventStack, s64_t allocLowerBound, s64_t allocUpperBound, s64_t accessLowerBound, s64_t accessUpperBound)
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74