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{
35
36class AbstractInterpretation;
37
43{
44public:
55
60
64 virtual ~AEDetector() = default;
65
71 static bool classof(const AEDetector* detector)
72 {
73 return detector->getKind() == AEDetector::UNKNOWN;
74 }
75
81 virtual void detect(const ICFGNode* node) = 0;
82
87 virtual void handleStubFunctions(const CallICFGNode* call) = 0;
88
92 virtual void reportBug() = 0;
93
99 {
100 return kind;
101 }
102
103protected:
105};
106
111class AEException : public std::exception
112{
113public:
118 AEException(const std::string& message)
119 : msg_(message) {}
120
125 virtual const char* what() const throw()
126 {
127 return msg_.c_str();
128 }
129
130private:
131 std::string msg_;
132};
133
139{
141public:
148
157
162
168 static bool classof(const AEDetector* detector)
169 {
170 return detector->getKind() == AEDetector::BUF_OVERFLOW;
171 }
172
180 void updateGepObjOffsetFromBase(const ICFGNode* node,
184
190 void detect(const ICFGNode*) override;
191
192
197 void handleStubFunctions(const CallICFGNode*) override;
198
208
215 {
216 return gepObjOffsetFromBase.find(obj) != gepObjOffsetFromBase.end();
217 }
218
225 {
227 return gepObjOffsetFromBase.at(obj);
228 else
229 {
230 assert(false && "GepObjVar not found in gepObjOffsetFromBase");
231 abort();
232 }
233 }
234
243
249 void addBugToReporter(const AEException& e, const ICFGNode* node)
250 {
252 }
253
255 void addBugToReporter(const AEException& e, const ICFGNode* node,
257 {
258
261 eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
262
263 if (eventStack.empty())
264 {
265 return; // If the event stack is empty, return early
266 }
267
268 std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
269
270 // Check if the bug at this location has already been reported
271 if (bugLoc.find(loc) != bugLoc.end())
272 {
273 return; // If the bug location is already reported, return early
274 }
275 else
276 {
277 bugLoc.insert(loc); // Otherwise, mark this location as reported
278 }
279
280 // Add the bug to the recorder with details from the event stack
282 info.bufferLowerBound, info.bufferSize,
283 info.accessOffset.lb().getNumeral(), info.accessOffset.ub().getNumeral());
284 nodeToBugInfo[node] = e.what(); // Record the exception information for the node
285 }
286
290 void reportBug() override
291 {
292 if (!nodeToBugInfo.empty())
293 {
294 std::cerr << "######################Buffer Overflow (" + std::to_string(nodeToBugInfo.size())
295 + " found)######################\n";
296 std::cerr << "---------------------------------------------\n";
297 for (const auto& it : nodeToBugInfo)
298 {
299 std::cerr << it.second << "\n---------------------------------------------\n";
300 }
301 }
302 }
303
308
314 void detectExtAPI(const CallICFGNode *call);
315
323 bool canSafelyAccessMemory(const ValVar *value, const IntervalValue &len,
324 const ICFGNode* node, BufferOverflowInfo* info = nullptr);
325
326private:
332 bool detectStrcat(const CallICFGNode *call, BufferOverflowInfo& info);
333
339 bool detectStrcpy(const CallICFGNode *call, BufferOverflowInfo& info);
340
341private:
347};
349{
351public:
356
358
359 static bool classof(const AEDetector* detector)
360 {
361 return detector->getKind() == AEDetector::NULL_DEREF;
362 }
363
369 void detect(const ICFGNode* node) override;
370
375 void handleStubFunctions(const CallICFGNode* call) override;
376
383 {
384 // uninitialized value has neither interval value nor address value
385 bool is = v.getAddrs().isBottom() && v.getInterval().isBottom();
386 return is;
387 }
388
394 void addBugToReporter(const AEException& e, const ICFGNode* node)
395 {
398 eventStack.push_back(sourceInstEvent); // Add the source instruction event to the event stack
399
400 if (eventStack.empty())
401 {
402 return; // If the event stack is empty, return early
403 }
404 std::string loc = eventStack.back().getEventLoc(); // Get the location of the last event in the stack
405
406 // Check if the bug at this location has already been reported
407 if (bugLoc.find(loc) != bugLoc.end())
408 {
409 return; // If the bug location is already reported, return early
410 }
411 else
412 {
413 bugLoc.insert(loc); // Otherwise, mark this location as reported
414 }
416 nodeToBugInfo[node] = e.what(); // Record the exception information for the node
417 }
418
422 void reportBug() override
423 {
424 if (!nodeToBugInfo.empty())
425 {
426 std::cerr << "###################### Nullptr Dereference (" + std::to_string(nodeToBugInfo.size())
427 + " found)######################\n";
428 std::cerr << "---------------------------------------------\n";
429 for (const auto& it : nodeToBugInfo)
430 {
431 std::cerr << it.second << "\n---------------------------------------------\n";
432 }
433 }
434 }
435
441 void detectExtAPI(const CallICFGNode* call);
442
443
450 {
451 return !v.isAddr() && !v.isInterval();
452 }
453
454 bool canSafelyDerefPtr(const ValVar* ptr, const ICFGNode* node);
455
456private:
460};
461}
buffer offset
Definition cJSON.cpp:1113
Base class for all detectors.
Definition AEDetector.h:43
static bool classof(const AEDetector *detector)
Check if the detector is of the UNKNOWN kind.
Definition AEDetector.h:71
DetectorKind
Enumerates the types of detectors available.
Definition AEDetector.h:50
@ NULL_DEREF
Detector for nullptr dereference issues.
Definition AEDetector.h:52
@ UNKNOWN
Default type if the kind is not specified.
Definition AEDetector.h:53
@ BUF_OVERFLOW
Detector for buffer overflow issues.
Definition AEDetector.h:51
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:104
virtual void reportBug()=0
Pure virtual function to report detected bugs.
AEDetector()
Constructor initializes the detector kind to UNKNOWN.
Definition AEDetector.h:59
virtual ~AEDetector()=default
Virtual destructor for safe polymorphic use.
virtual void detect(const ICFGNode *node)=0
Pure virtual function for detecting issues within a node.
DetectorKind getKind() const
Get the kind of the detector.
Definition AEDetector.h:98
Exception class for handling errors in Abstract Execution.
Definition AEDetector.h:112
virtual const char * what() const
Provides the error message.
Definition AEDetector.h:125
AEException(const std::string &message)
Constructor initializes the exception with a message.
Definition AEDetector.h:118
std::string msg_
The error message.
Definition AEDetector.h:131
Detector for identifying buffer overflow issues.
Definition AEDetector.h:139
bool detectStrcat(const CallICFGNode *call, BufferOverflowInfo &info)
Detects buffer overflow in 'strcat' function calls.
void addToGepObjOffsetFromBase(const GepObjVar *obj, const IntervalValue &offset)
Adds an offset to a GEP object.
Definition AEDetector.h:204
void detect(const ICFGNode *) override
Detect buffer overflow issues within a node.
void reportBug() override
Reports all detected buffer overflow bugs.
Definition AEDetector.h:290
~BufOverflowDetector()=default
Destructor.
Map< const GepObjVar *, IntervalValue > gepObjOffsetFromBase
Maps GEP objects to their offsets from the base.
Definition AEDetector.h:342
Map< std::string, std::vector< std::pair< u32_t, u32_t > > > extAPIBufOverflowCheckRules
Rules for checking buffer overflows in external APIs.
Definition AEDetector.h:343
SVFBugReport recoder
Recorder for abstract execution bugs.
Definition AEDetector.h:345
IntervalValue getAccessOffset(NodeID objId, const GepStmt *gep)
Retrieves the access offset for a given object and GEP statement.
void updateGepObjOffsetFromBase(const ICFGNode *node, AddressValue gepAddrs, AddressValue objAddrs, IntervalValue offset)
Updates the offset of a GEP object from its base.
void detectExtAPI(const CallICFGNode *call)
Handles external API calls related to buffer overflow detection.
void addBugToReporter(const AEException &e, const ICFGNode *node, const BufferOverflowInfo &info)
Report an OOB alarm with the buffer size and offset from its check.
Definition AEDetector.h:255
BufOverflowDetector()
Constructor initializes the detector kind to BUF_OVERFLOW and sets up external API buffer overflow ru...
Definition AEDetector.h:152
Set< std::string > bugLoc
Set of locations where bugs have been reported.
Definition AEDetector.h:344
IntervalValue getGepObjOffsetFromBase(const GepObjVar *obj) const
Retrieves the offset of a GEP object from its base.
Definition AEDetector.h:224
static bool classof(const AEDetector *detector)
Check if the detector is of the BUF_OVERFLOW kind.
Definition AEDetector.h:168
bool canSafelyAccessMemory(const ValVar *value, const IntervalValue &len, const ICFGNode *node, BufferOverflowInfo *info=nullptr)
Checks if memory can be safely accessed.
void handleStubFunctions(const CallICFGNode *) override
Handles external API calls related to buffer overflow detection.
Map< const ICFGNode *, std::string > nodeToBugInfo
Maps ICFG nodes to bug information.
Definition AEDetector.h:346
bool hasGepObjOffsetFromBase(const GepObjVar *obj) const
Checks if a GEP object has an associated offset.
Definition AEDetector.h:214
void initExtAPIBufOverflowCheckRules()
Initializes external API buffer overflow check rules.
void addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
Definition AEDetector.h:249
bool detectStrcpy(const CallICFGNode *call, BufferOverflowInfo &info)
Detects buffer overflow in 'strcpy' function calls.
std::vector< SVFBugEvent > EventStack
bool canSafelyDerefPtr(const ValVar *ptr, const ICFGNode *node)
Set< std::string > bugLoc
Set of locations where bugs have been reported.
Definition AEDetector.h:457
bool isNull(AbstractValue v)
Check if an Abstract Value is NULL (or uninitialized).
Definition AEDetector.h:449
bool isUninit(AbstractValue v)
Checks if an Abstract Value is uninitialized.
Definition AEDetector.h:382
void handleStubFunctions(const CallICFGNode *call) override
Handles external API calls related to nullptr dereferences.
void detect(const ICFGNode *node) override
Detects nullptr dereferences issues within a node.
static bool classof(const AEDetector *detector)
Definition AEDetector.h:359
void addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
Definition AEDetector.h:394
void reportBug() override
Reports all detected nullptr dereference bugs.
Definition AEDetector.h:422
void detectExtAPI(const CallICFGNode *call)
Handle external API calls related to nullptr dereferences.
SVFBugReport recoder
Recorder for abstract execution bugs.
Definition AEDetector.h:458
Map< const ICFGNode *, std::string > nodeToBugInfo
Maps ICFG nodes to bug information.
Definition AEDetector.h:459
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:70
u32_t NodeID
Definition GeneralType.h:76
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
unsigned u32_t
Definition GeneralType.h:67