46 if (!SVFUtil::isa<CallICFGNode>(node))
117 std::string funcName =
callNode->getCalledFunction()->getName();
118 if (funcName ==
"SAFE_BUFACCESS")
132 assert(
false &&
"SAFE_BUFACCESS size is bottom");
138 std::cout <<
"safe buffer access success: " <<
callNode->toString()
144 std::string
err_msg =
"this SAFE_BUFACCESS should be a safe access but detected buffer overflow. Pos: ";
146 std::cerr <<
err_msg << std::endl;
150 else if (funcName ==
"UNSAFE_BUFACCESS")
155 if (
callNode->arg_size() < 2)
return;
161 assert(
false &&
"UNSAFE_BUFACCESS size is bottom");
167 std::cout <<
"detect buffer overflow success: " <<
callNode->toString() << std::endl;
172 std::string
err_msg =
"this UNSAFE_BUFACCESS should be a buffer overflow but not detected. Pos: ";
174 std::cerr <<
err_msg << std::endl;
230 if (
annotation.find(
"MEMCPY") != std::string::npos)
232 if (
annotation.find(
"MEMSET") != std::string::npos)
234 if (
annotation.find(
"STRCPY") != std::string::npos)
236 if (
annotation.find(
"STRCAT") != std::string::npos)
248 std::vector<std::pair<u32_t, u32_t>> args =
250 for (
auto arg : args)
268 std::vector<std::pair<u32_t, u32_t>> args =
270 for (
auto arg : args)
320 if (SVFUtil::isa<BaseObjVar>(
obj))
322 return as.getByteOffset(
gep);
324 else if (SVFUtil::isa<GepObjVar>(
obj))
331 assert(SVFUtil::isa<DummyObjVar>(
obj) &&
"Unknown object type");
355 if (SVFUtil::isa<BaseObjVar>(
obj))
364 else if (SVFUtil::isa<GepObjVar>(
obj))
380 assert(
false &&
"GEP RHS object has no offset from base");
417 const std::vector<std::string>
strcatGroup = {
"__strcat_chk",
"strcat",
"__wcscat_chk",
"wcscat"};
418 const std::vector<std::string>
strncatGroup = {
"__strncat_chk",
"strncat",
"__wcsncat_chk",
"wcsncat"};
440 assert(
false &&
"Unknown strcat function, please add it to strcatGroup or strncatGroup");
498 if (
offset.ub().getIntNumeral() >= size)
Exception class for handling errors in Abstract Execution.
IntervalValue getStrlen(AbstractState &as, const SVF::SVFVar *strValue)
Calculates the length of a string.
ExtAPIType
Enumeration of external API types.
static AbstractInterpretation & getAEInstance()
AbstractState & getAbsStateFromTrace(const ICFGNode *node)
Set< const CallICFGNode * > checkpoints
static u32_t getInternalID(u32_t idx)
Return the internal index if idx is an address otherwise return the value of idx.
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.
Map< std::string, std::vector< std::pair< u32_t, u32_t > > > extAPIBufOverflowCheckRules
Rules for checking buffer overflows in external APIs.
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.
bool detectStrcat(AbstractState &as, const CallICFGNode *call)
Detects buffer overflow in 'strcat' function calls.
IntervalValue getGepObjOffsetFromBase(const GepObjVar *obj) const
Retrieves the offset of a GEP object from its base.
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.
void updateGepObjOffsetFromBase(AddressValue gepAddrs, AddressValue objAddrs, IntervalValue offset)
Updates the offset of a GEP object from its base.
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 addBugToReporter(const AEException &e, const ICFGNode *node)
Adds a bug to the reporter based on an exception.
const std::string toString() const override
const ValVar * getArgument(u32_t ArgNo) const
Parameter operations.
const SVFFunction * getCalledFunction() const
const std::vector< std::string > & getExtFuncAnnotations(const SVFFunction *fun)
static ExtAPI * getExtAPI()
NodeType * getGNode(NodeID id) const
Get a node.
const SVFStmtList & getSVFStmts() const
static IntervalValue bottom()
Create the bottom IntervalValue [+inf, -inf].
static IntervalValue top()
Create the IntervalValue [-inf, +inf].
const SVFBaseNode * getGNode() const
Get the reference value to this object.
u32_t getByteSizeOfObj() const
Get the byte size of this object.
bool isConstantByteSize() const
Check if byte size is a const value.
NodeID getId() const
Get ID.
const MemObj * getBaseObj(NodeID id) const
static SVFIR * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis.
const std::string & getName() const
bool isExtCall(const SVFFunction *fun)
std::ostream & errs()
Overwrite llvm::errs()
llvm::IRBuilder IRBuilder