svf-tools 1.0.987 → 1.0.989

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -26,6 +26,7 @@
26
26
  //
27
27
 
28
28
  #include "AE/Svfexe/AbstractInterpretation.h"
29
+ #include "AE/Svfexe/AbsExtAPI.h"
29
30
  #include "SVFIR/SVFIR.h"
30
31
  #include "Util/Options.h"
31
32
  #include "Util/WorkList.h"
@@ -89,6 +90,7 @@ void AbstractInterpretation::runOnModule(ICFG *_icfg)
89
90
  stat->startClk();
90
91
  icfg = _icfg;
91
92
  svfir = PAG::getPAG();
93
+ utils = new AbsExtAPI(abstractTrace);
92
94
 
93
95
  /// collect checkpoint
94
96
  collectCheckPoint();
@@ -106,7 +108,6 @@ void AbstractInterpretation::runOnModule(ICFG *_icfg)
106
108
  AbstractInterpretation::AbstractInterpretation()
107
109
  {
108
110
  stat = new AEStat(this);
109
- initExtFunMap();
110
111
  }
111
112
  /// Destructor
112
113
  AbstractInterpretation::~AbstractInterpretation()
@@ -622,7 +623,11 @@ bool AbstractInterpretation::isExtCall(const SVF::CallICFGNode *callNode)
622
623
  void AbstractInterpretation::extCallPass(const SVF::CallICFGNode *callNode)
623
624
  {
624
625
  callSiteStack.push_back(callNode);
625
- handleExtAPI(callNode);
626
+ utils->handleExtAPI(callNode);
627
+ for (auto& detector : detectors)
628
+ {
629
+ detector->handleStubFunctions(callNode);
630
+ }
626
631
  callSiteStack.pop_back();
627
632
  }
628
633
 
@@ -955,490 +960,12 @@ void AEStat::performStat()
955
960
  SVFUtil::outs().flush();
956
961
  }
957
962
 
958
- void AbstractInterpretation::initExtFunMap()
959
- {
960
- #define SSE_FUNC_PROCESS(LLVM_NAME ,FUNC_NAME) \
961
- auto sse_##FUNC_NAME = [this](const CallICFGNode *callNode) { \
962
- /* run real ext function */ \
963
- AbstractState& as = getAbsStateFromTrace(callNode); \
964
- u32_t rhs_id = svfir->getValueNode(callNode->getArgument(0)); \
965
- if (!as.inVarToValTable(rhs_id)) return; \
966
- u32_t rhs = as[rhs_id].getInterval().lb().getIntNumeral(); \
967
- s32_t res = FUNC_NAME(rhs); \
968
- u32_t lhsId = svfir->getValueNode(callNode->getCallSite()); \
969
- as[lhsId] = IntervalValue(res); \
970
- return; \
971
- }; \
972
- func_map[#FUNC_NAME] = sse_##FUNC_NAME;
973
-
974
- SSE_FUNC_PROCESS(isalnum, isalnum);
975
- SSE_FUNC_PROCESS(isalpha, isalpha);
976
- SSE_FUNC_PROCESS(isblank, isblank);
977
- SSE_FUNC_PROCESS(iscntrl, iscntrl);
978
- SSE_FUNC_PROCESS(isdigit, isdigit);
979
- SSE_FUNC_PROCESS(isgraph, isgraph);
980
- SSE_FUNC_PROCESS(isprint, isprint);
981
- SSE_FUNC_PROCESS(ispunct, ispunct);
982
- SSE_FUNC_PROCESS(isspace, isspace);
983
- SSE_FUNC_PROCESS(isupper, isupper);
984
- SSE_FUNC_PROCESS(isxdigit, isxdigit);
985
- SSE_FUNC_PROCESS(llvm.sin.f64, sin);
986
- SSE_FUNC_PROCESS(llvm.cos.f64, cos);
987
- SSE_FUNC_PROCESS(llvm.tan.f64, tan);
988
- SSE_FUNC_PROCESS(llvm.log.f64, log);
989
- SSE_FUNC_PROCESS(sinh, sinh);
990
- SSE_FUNC_PROCESS(cosh, cosh);
991
- SSE_FUNC_PROCESS(tanh, tanh);
992
-
993
- auto sse_svf_assert = [this](const CallICFGNode* callNode)
994
- {
995
- checkpoints.erase(callNode);
996
- u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
997
- AbstractState&as = getAbsStateFromTrace(callNode);
998
- if (as[arg0].getInterval().equals(IntervalValue(1, 1)))
999
- {
1000
- SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
1001
- }
1002
- else
1003
- {
1004
- SVFUtil::errs() <<"svf_assert Fail. " << callNode->toString() << "\n";
1005
- assert(false);
1006
- }
1007
- return;
1008
- };
1009
- func_map["svf_assert"] = sse_svf_assert;
1010
-
1011
- auto svf_assert_eq = [this](const CallICFGNode* callNode)
1012
- {
1013
- checkpoints.erase(callNode);
1014
- u32_t arg0 = svfir->getValueNode(callNode->getArgument(0));
1015
- u32_t arg1 = svfir->getValueNode(callNode->getArgument(1));
1016
- AbstractState&as = getAbsStateFromTrace(callNode);
1017
- if (as[arg0].getInterval().equals(as[arg1].getInterval()))
1018
- {
1019
- SVFUtil::errs() << SVFUtil::sucMsg("The assertion is successfully verified!!\n");
1020
- }
1021
- else
1022
- {
1023
- SVFUtil::errs() <<"svf_assert_eq Fail. " << callNode->toString() << "\n";
1024
- assert(false);
1025
- }
1026
- return;
1027
- };
1028
- func_map["svf_assert_eq"] = svf_assert_eq;
1029
-
1030
- auto svf_print = [&](const CallICFGNode* callNode)
1031
- {
1032
- if (callNode->arg_size() < 2) return;
1033
- AbstractState&as = getAbsStateFromTrace(callNode);
1034
- u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
1035
- std::string text = strRead(as, callNode->getArgument(1));
1036
- assert(as.inVarToValTable(num_id) && "print() should pass integer");
1037
- IntervalValue itv = as[num_id].getInterval();
1038
- std::cout << "Text: " << text <<", Value: " << callNode->getArgument(0)->toString()
1039
- << ", PrintVal: " << itv.toString() << ", Loc:" << callNode->getSourceLoc() << std::endl;
1040
- return;
1041
- };
1042
- func_map["svf_print"] = svf_print;
1043
-
1044
- auto svf_set_value = [&](const CallICFGNode* callNode)
1045
- {
1046
- if (callNode->arg_size() < 2) return;
1047
- AbstractState&as = getAbsStateFromTrace(callNode);
1048
- AbstractValue& num = as[svfir->getValueNode(callNode->getArgument(0))];
1049
- AbstractValue& lb = as[svfir->getValueNode(callNode->getArgument(1))];
1050
- AbstractValue& ub = as[svfir->getValueNode(callNode->getArgument(2))];
1051
- assert(lb.getInterval().is_numeral() && ub.getInterval().is_numeral());
1052
- num.getInterval().set_to_top();
1053
- num.getInterval().meet_with(IntervalValue(lb.getInterval().lb(), ub.getInterval().ub()));
1054
- if (icfg->hasICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0))))
1055
- {
1056
- const ICFGNode* node = icfg->getICFGNode(SVFUtil::cast<SVFInstruction>(callNode->getArgument(0)));
1057
- for (const SVFStmt* stmt: node->getSVFStmts())
1058
- {
1059
- if (SVFUtil::isa<LoadStmt>(stmt))
1060
- {
1061
- const LoadStmt* load = SVFUtil::cast<LoadStmt>(stmt);
1062
- NodeID rhsId = load->getRHSVarID();
1063
- as.storeValue(rhsId, num);
1064
- }
1065
- }
1066
- }
1067
- return;
1068
- };
1069
- func_map["set_value"] = svf_set_value;
1070
-
1071
- auto sse_scanf = [&](const CallICFGNode* callNode)
1072
- {
1073
- AbstractState& as = getAbsStateFromTrace(callNode);
1074
- //scanf("%d", &data);
1075
- if (callNode->arg_size() < 2) return;
1076
-
1077
- u32_t dst_id = svfir->getValueNode(callNode->getArgument(1));
1078
- if (!as.inVarToAddrsTable(dst_id))
1079
- {
1080
- return;
1081
- }
1082
- else
1083
- {
1084
- AbstractValue Addrs = as[dst_id];
1085
- for (auto vaddr: Addrs.getAddrs())
1086
- {
1087
- u32_t objId = AbstractState::getInternalID(vaddr);
1088
- AbstractValue range = getRangeLimitFromType(svfir->getGNode(objId)->getType());
1089
- as.store(vaddr, range);
1090
- }
1091
- }
1092
- };
1093
- auto sse_fscanf = [&](const CallICFGNode* callNode)
1094
- {
1095
- //fscanf(stdin, "%d", &data);
1096
- if (callNode->arg_size() < 3) return;
1097
- AbstractState& as = getAbsStateFromTrace(callNode);
1098
- u32_t dst_id = svfir->getValueNode(callNode->getArgument(2));
1099
- if (!as.inVarToAddrsTable(dst_id))
1100
- {
1101
- }
1102
- else
1103
- {
1104
- AbstractValue Addrs = as[dst_id];
1105
- for (auto vaddr: Addrs.getAddrs())
1106
- {
1107
- u32_t objId = AbstractState::getInternalID(vaddr);
1108
- AbstractValue range = getRangeLimitFromType(svfir->getGNode(objId)->getType());
1109
- as.store(vaddr, range);
1110
- }
1111
- }
1112
- };
1113
-
1114
- func_map["__isoc99_fscanf"] = sse_fscanf;
1115
- func_map["__isoc99_scanf"] = sse_scanf;
1116
- func_map["__isoc99_vscanf"] = sse_scanf;
1117
- func_map["fscanf"] = sse_fscanf;
1118
- func_map["scanf"] = sse_scanf;
1119
- func_map["sscanf"] = sse_scanf;
1120
- func_map["__isoc99_sscanf"] = sse_scanf;
1121
- func_map["vscanf"] = sse_scanf;
1122
-
1123
- auto sse_fread = [&](const CallICFGNode *callNode)
1124
- {
1125
- if (callNode->arg_size() < 3) return;
1126
- AbstractState&as = getAbsStateFromTrace(callNode);
1127
- u32_t block_count_id = svfir->getValueNode(callNode->getArgument(2));
1128
- u32_t block_size_id = svfir->getValueNode(callNode->getArgument(1));
1129
- IntervalValue block_count = as[block_count_id].getInterval();
1130
- IntervalValue block_size = as[block_size_id].getInterval();
1131
- IntervalValue block_byte = block_count * block_size;
1132
- };
1133
- func_map["fread"] = sse_fread;
1134
-
1135
- auto sse_sprintf = [&](const CallICFGNode *callNode)
1136
- {
1137
- // printf is difficult to predict since it has no byte size arguments
1138
- };
1139
-
1140
- auto sse_snprintf = [&](const CallICFGNode *callNode)
1141
- {
1142
- if (callNode->arg_size() < 2) return;
1143
- AbstractState&as = getAbsStateFromTrace(callNode);
1144
- u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1145
- u32_t dst_id = svfir->getValueNode(callNode->getArgument(0));
1146
- // get elem size of arg2
1147
- u32_t elemSize = 1;
1148
- if (callNode->getArgument(2)->getType()->isArrayTy())
1149
- {
1150
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(callNode->getArgument(2)->getType())->getTypeOfElement()->getByteSize();
1151
- }
1152
- else if (callNode->getArgument(2)->getType()->isPointerTy())
1153
- {
1154
- elemSize = as.getPointeeElement(svfir->getValueNode(callNode->getArgument(2)))->getByteSize();
1155
- }
1156
- else
1157
- {
1158
- return;
1159
- // assert(false && "we cannot support this type");
1160
- }
1161
- IntervalValue size = as[size_id].getInterval() * IntervalValue(elemSize) - IntervalValue(1);
1162
- if (!as.inVarToAddrsTable(dst_id))
1163
- {
1164
- }
1165
- };
1166
- func_map["__snprintf_chk"] = sse_snprintf;
1167
- func_map["__vsprintf_chk"] = sse_sprintf;
1168
- func_map["__sprintf_chk"] = sse_sprintf;
1169
- func_map["snprintf"] = sse_snprintf;
1170
- func_map["sprintf"] = sse_sprintf;
1171
- func_map["vsprintf"] = sse_sprintf;
1172
- func_map["vsnprintf"] = sse_snprintf;
1173
- func_map["__vsnprintf_chk"] = sse_snprintf;
1174
- func_map["swprintf"] = sse_snprintf;
1175
- func_map["_snwprintf"] = sse_snprintf;
1176
-
1177
-
1178
- auto sse_itoa = [&](const CallICFGNode* callNode)
1179
- {
1180
- // itoa(num, ch, 10);
1181
- // num: int, ch: char*, 10 is decimal
1182
- if (callNode->arg_size() < 3) return;
1183
- AbstractState&as = getAbsStateFromTrace(callNode);
1184
- u32_t num_id = svfir->getValueNode(callNode->getArgument(0));
1185
-
1186
- u32_t num = (u32_t) as[num_id].getInterval().getNumeral();
1187
- std::string snum = std::to_string(num);
1188
- };
1189
- func_map["itoa"] = sse_itoa;
1190
-
1191
-
1192
- auto sse_strlen = [&](const CallICFGNode *callNode)
1193
- {
1194
- // check the arg size
1195
- if (callNode->arg_size() < 1) return;
1196
- const SVFValue* strValue = callNode->getArgument(0);
1197
- AbstractState& as = getAbsStateFromTrace(callNode);
1198
- NodeID value_id = svfir->getValueNode(strValue);
1199
- u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
1200
- u32_t dst_size = 0;
1201
- for (const auto& addr : as[value_id].getAddrs())
1202
- {
1203
- NodeID objId = AbstractState::getInternalID(addr);
1204
- if (svfir->getBaseObj(objId)->isConstantByteSize())
1205
- {
1206
- dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj();
1207
- }
1208
- else
1209
- {
1210
- const ICFGNode* addrNode = svfir->getICFG()->getICFGNode(SVFUtil::cast<SVFInstruction>(svfir->getBaseObj(objId)->getValue()));
1211
- for (const SVFStmt* stmt2: addrNode->getSVFStmts())
1212
- {
1213
- if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
1214
- {
1215
- dst_size = as.getAllocaInstByteSize(addrStmt);
1216
- }
1217
- }
1218
- }
1219
- }
1220
- u32_t len = 0;
1221
- NodeID dstid = svfir->getValueNode(strValue);
1222
- if (as.inVarToAddrsTable(dstid))
1223
- {
1224
- for (u32_t index = 0; index < dst_size; index++)
1225
- {
1226
- AbstractValue expr0 =
1227
- as.getGepObjAddrs(dstid, IntervalValue(index));
1228
- AbstractValue val;
1229
- for (const auto &addr: expr0.getAddrs())
1230
- {
1231
- val.join_with(as.load(addr));
1232
- }
1233
- if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
1234
- {
1235
- break;
1236
- }
1237
- ++len;
1238
- }
1239
- }
1240
- if (len == 0)
1241
- {
1242
- as[lhsId] = IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit());
1243
- }
1244
- else
1245
- {
1246
- as[lhsId] = IntervalValue(len);
1247
- }
1248
- };
1249
- func_map["strlen"] = sse_strlen;
1250
- func_map["wcslen"] = sse_strlen;
1251
-
1252
- auto sse_recv = [&](const CallICFGNode *callNode)
1253
- {
1254
- // recv(sockfd, buf, len, flags);
1255
- if (callNode->arg_size() < 4) return;
1256
- AbstractState&as = getAbsStateFromTrace(callNode);
1257
- u32_t len_id = svfir->getValueNode(callNode->getArgument(2));
1258
- IntervalValue len = as[len_id].getInterval() - IntervalValue(1);
1259
- u32_t lhsId = svfir->getValueNode(callNode->getCallSite());
1260
- as[lhsId] = len;
1261
- };
1262
- func_map["recv"] = sse_recv;
1263
- func_map["__recv"] = sse_recv;
1264
- auto safe_bufaccess = [&](const CallICFGNode *callNode)
1265
- {
1266
- checkpoints.erase(callNode);
1267
- //void SAFE_BUFACCESS(void* data, int size);
1268
- if (callNode->arg_size() < 2) return;
1269
- AbstractState&as = getAbsStateFromTrace(callNode);
1270
- u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1271
- IntervalValue val = as[size_id].getInterval();
1272
- if (val.isBottom())
1273
- {
1274
- val = IntervalValue(0);
1275
- assert(false && "SAFE_BUFACCESS size is bottom");
1276
- }
1277
- for (auto& detector: detectors)
1278
- {
1279
- // if detector is a buffer overflow detector, call it
1280
- if (SVFUtil::isa<BufOverflowDetector>(detector))
1281
- {
1282
- BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
1283
- bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
1284
- if (isSafe)
1285
- {
1286
- std::cout << "safe buffer access success: " << callNode->toString() << std::endl;
1287
- return;
1288
- }
1289
- else
1290
- {
1291
- std::string err_msg = "this SAFE_BUFACCESS should be a safe access but detected buffer overflow. Pos: ";
1292
- err_msg += callNode->getSourceLoc();
1293
- std::cerr << err_msg << std::endl;
1294
- assert(false);
1295
- }
1296
- }
1297
- }
1298
- };
1299
- func_map["SAFE_BUFACCESS"] = safe_bufaccess;
1300
-
1301
- auto unsafe_bufaccess = [&](const CallICFGNode *callNode)
1302
- {
1303
- checkpoints.erase(callNode);
1304
- //void UNSAFE_BUFACCESS(void* data, int size);
1305
- if (callNode->arg_size() < 2) return;
1306
- AbstractState&as = getAbsStateFromTrace(callNode);
1307
- u32_t size_id = svfir->getValueNode(callNode->getArgument(1));
1308
- IntervalValue val = as[size_id].getInterval();
1309
- if (val.isBottom())
1310
- {
1311
- assert(false && "UNSAFE_BUFACCESS size is bottom");
1312
- }
1313
- for (auto& detector: detectors)
1314
- {
1315
- // if detector is a buffer overflow detector, call it
1316
- if (SVFUtil::isa<BufOverflowDetector>(detector))
1317
- {
1318
- BufOverflowDetector* bufDetector = SVFUtil::cast<BufOverflowDetector>(detector.get());
1319
- bool isSafe = bufDetector->canSafelyAccessMemory(as, callNode->getArgument(0), val);
1320
- if (!isSafe)
1321
- {
1322
- std::cout << "detect buffer overflow success: " << callNode->toString() << std::endl;
1323
- return;
1324
- }
1325
- else
1326
- {
1327
- std::string err_msg = "this UNSAFE_BUFACCESS should be a buffer overflow but not detected. Pos: ";
1328
- err_msg += callNode->getSourceLoc();
1329
- std::cerr << err_msg << std::endl;
1330
- assert(false);
1331
- }
1332
- }
1333
- }
1334
- };
1335
- func_map["UNSAFE_BUFACCESS"] = unsafe_bufaccess;
1336
-
1337
- // init checkpoint_names
1338
- checkpoint_names.insert("svf_assert");
1339
- checkpoint_names.insert("UNSAFE_ACCESS");
1340
- checkpoint_names.insert("SAFE_ACCESS");
1341
- };
1342
-
1343
- std::string AbstractInterpretation::strRead(AbstractState& as, const SVFValue* rhs)
1344
- {
1345
- // sse read string nodeID->string
1346
- std::string str0;
1347
-
1348
- for (u32_t index = 0; index < Options::MaxFieldLimit(); index++)
1349
- {
1350
- // dead loop for string and break if there's a \0. If no \0, it will throw err.
1351
- if (!as.inVarToAddrsTable(svfir->getValueNode(rhs))) continue;
1352
- AbstractValue expr0 =
1353
- as.getGepObjAddrs(svfir->getValueNode(rhs), IntervalValue(index));
1354
-
1355
- AbstractValue val;
1356
- for (const auto &addr: expr0.getAddrs())
1357
- {
1358
- val.join_with(as.load(addr));
1359
- }
1360
- if (!val.getInterval().is_numeral())
1361
- {
1362
- break;
1363
- }
1364
- if ((char) val.getInterval().getIntNumeral() == '\0')
1365
- {
1366
- break;
1367
- }
1368
- str0.push_back((char) val.getInterval().getIntNumeral());
1369
- }
1370
- return str0;
1371
- }
1372
-
1373
- void AbstractInterpretation::handleExtAPI(const CallICFGNode *call)
1374
- {
1375
- AbstractState& as = getAbsStateFromTrace(call);
1376
- const SVFFunction *fun = call->getCalledFunction();
1377
- assert(fun && "SVFFunction* is nullptr");
1378
- ExtAPIType extType = UNCLASSIFIED;
1379
- // get type of mem api
1380
- for (const std::string &annotation: fun->getAnnotations())
1381
- {
1382
- if (annotation.find("MEMCPY") != std::string::npos)
1383
- extType = MEMCPY;
1384
- if (annotation.find("MEMSET") != std::string::npos)
1385
- extType = MEMSET;
1386
- if (annotation.find("STRCPY") != std::string::npos)
1387
- extType = STRCPY;
1388
- if (annotation.find("STRCAT") != std::string::npos)
1389
- extType = STRCAT;
1390
- }
1391
- if (extType == UNCLASSIFIED)
1392
- {
1393
- if (func_map.find(fun->getName()) != func_map.end())
1394
- {
1395
- func_map[fun->getName()](call);
1396
- }
1397
- else
1398
- {
1399
- u32_t lhsId = svfir->getValueNode(call->getCallSite());
1400
- if (as.inVarToAddrsTable(lhsId))
1401
- {
1402
-
1403
- }
1404
- else
1405
- {
1406
- as[lhsId] = IntervalValue();
1407
- }
1408
- return;
1409
- }
1410
- }
1411
- // 1. memcpy functions like memcpy_chk, strncpy, annotate("MEMCPY"), annotate("BUF_CHECK:Arg0, Arg2"), annotate("BUF_CHECK:Arg1, Arg2")
1412
- else if (extType == MEMCPY)
1413
- {
1414
- IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
1415
- handleMemcpy(as, call->getArgument(0), call->getArgument(1), len, 0);
1416
- }
1417
- else if (extType == MEMSET)
1418
- {
1419
- // memset dst is arg0, elem is arg1, size is arg2
1420
- IntervalValue len = as[svfir->getValueNode(call->getArgument(2))].getInterval();
1421
- IntervalValue elem = as[svfir->getValueNode(call->getArgument(1))].getInterval();
1422
- handleMemset(as,call->getArgument(0), elem, len);
1423
- }
1424
- else if (extType == STRCPY)
1425
- {
1426
- handleStrcpy(call);
1427
- }
1428
- else if (extType == STRCAT)
1429
- {
1430
- handleStrcat(call);
1431
- }
1432
- else
1433
- {
1434
-
1435
- }
1436
- return;
1437
- }
1438
-
1439
963
  void AbstractInterpretation::collectCheckPoint()
1440
964
  {
1441
965
  // traverse every ICFGNode
966
+ Set<std::string> ae_checkpoint_names = {"svf_assert"};
967
+ Set<std::string> buf_checkpoint_names = {"UNSAFE_BUFACCESS", "SAFE_BUFACCESS"};
968
+
1442
969
  for (auto it = svfir->getICFG()->begin(); it != svfir->getICFG()->end(); ++it)
1443
970
  {
1444
971
  const ICFGNode* node = it->second;
@@ -1446,11 +973,19 @@ void AbstractInterpretation::collectCheckPoint()
1446
973
  {
1447
974
  if (const SVFFunction *fun = call->getCalledFunction())
1448
975
  {
1449
- if (checkpoint_names.find(fun->getName()) !=
1450
- checkpoint_names.end())
976
+ if (ae_checkpoint_names.find(fun->getName()) !=
977
+ ae_checkpoint_names.end())
1451
978
  {
1452
979
  checkpoints.insert(call);
1453
980
  }
981
+ if (Options::BufferOverflowCheck())
982
+ {
983
+ if (buf_checkpoint_names.find(fun->getName()) !=
984
+ buf_checkpoint_names.end())
985
+ {
986
+ checkpoints.insert(call);
987
+ }
988
+ }
1454
989
  }
1455
990
  }
1456
991
  }
@@ -1472,241 +1007,6 @@ void AbstractInterpretation::checkPointAllSet()
1472
1007
 
1473
1008
  }
1474
1009
 
1475
-
1476
- void AbstractInterpretation::handleStrcpy(const CallICFGNode *call)
1477
- {
1478
- // strcpy, __strcpy_chk, stpcpy , wcscpy, __wcscpy_chk
1479
- // get the dst and src
1480
- AbstractState& as = getAbsStateFromTrace(call);
1481
- const SVFValue* arg0Val = call->getArgument(0);
1482
- const SVFValue* arg1Val = call->getArgument(1);
1483
- IntervalValue strLen = getStrlen(as, arg1Val);
1484
- // no need to -1, since it has \0 as the last byte
1485
- handleMemcpy(as, arg0Val, arg1Val, strLen, strLen.lb().getIntNumeral());
1486
- }
1487
-
1488
- IntervalValue AbstractInterpretation::getStrlen(AbstractState& as, const SVF::SVFValue *strValue)
1489
- {
1490
- NodeID value_id = svfir->getValueNode(strValue);
1491
- u32_t dst_size = 0;
1492
- for (const auto& addr : as[value_id].getAddrs())
1493
- {
1494
- NodeID objId = AbstractState::getInternalID(addr);
1495
- if (svfir->getBaseObj(objId)->isConstantByteSize())
1496
- {
1497
- dst_size = svfir->getBaseObj(objId)->getByteSizeOfObj();
1498
- }
1499
- else
1500
- {
1501
- const ICFGNode* addrNode = svfir->getICFG()->getICFGNode(SVFUtil::cast<SVFInstruction>(svfir->getBaseObj(objId)->getValue()));
1502
- for (const SVFStmt* stmt2: addrNode->getSVFStmts())
1503
- {
1504
- if (const AddrStmt* addrStmt = SVFUtil::dyn_cast<AddrStmt>(stmt2))
1505
- {
1506
- dst_size = as.getAllocaInstByteSize(addrStmt);
1507
- }
1508
- }
1509
- }
1510
- }
1511
- u32_t len = 0;
1512
- NodeID dstid = svfir->getValueNode(strValue);
1513
- u32_t elemSize = 1;
1514
- if (as.inVarToAddrsTable(dstid))
1515
- {
1516
- for (u32_t index = 0; index < dst_size; index++)
1517
- {
1518
- AbstractValue expr0 =
1519
- as.getGepObjAddrs(dstid, IntervalValue(index));
1520
- AbstractValue val;
1521
- for (const auto &addr: expr0.getAddrs())
1522
- {
1523
- val.join_with(as.load(addr));
1524
- }
1525
- if (val.getInterval().is_numeral() && (char) val.getInterval().getIntNumeral() == '\0')
1526
- {
1527
- break;
1528
- }
1529
- ++len;
1530
- }
1531
- if (strValue->getType()->isArrayTy())
1532
- {
1533
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(strValue->getType())->getTypeOfElement()->getByteSize();
1534
- }
1535
- else if (strValue->getType()->isPointerTy())
1536
- {
1537
- if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(strValue)))
1538
- {
1539
- if (elemType->isArrayTy())
1540
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
1541
- else
1542
- elemSize = elemType->getByteSize();
1543
- }
1544
- else
1545
- {
1546
- elemSize = 1;
1547
- }
1548
- }
1549
- else
1550
- {
1551
- assert(false && "we cannot support this type");
1552
- }
1553
- }
1554
- if (len == 0)
1555
- {
1556
- return IntervalValue((s64_t)0, (s64_t)Options::MaxFieldLimit());
1557
- }
1558
- else
1559
- {
1560
- return IntervalValue(len * elemSize);
1561
- }
1562
- }
1563
-
1564
-
1565
- void AbstractInterpretation::handleStrcat(const SVF::CallICFGNode *call)
1566
- {
1567
- // __strcat_chk, strcat, __wcscat_chk, wcscat, __strncat_chk, strncat, __wcsncat_chk, wcsncat
1568
- // to check it is strcat group or strncat group
1569
- AbstractState& as = getAbsStateFromTrace(call);
1570
- const SVFFunction *fun = call->getCalledFunction();
1571
- const std::vector<std::string> strcatGroup = {"__strcat_chk", "strcat", "__wcscat_chk", "wcscat"};
1572
- const std::vector<std::string> strncatGroup = {"__strncat_chk", "strncat", "__wcsncat_chk", "wcsncat"};
1573
- if (std::find(strcatGroup.begin(), strcatGroup.end(), fun->getName()) != strcatGroup.end())
1574
- {
1575
- const SVFValue* arg0Val = call->getArgument(0);
1576
- const SVFValue* arg1Val = call->getArgument(1);
1577
- IntervalValue strLen0 = getStrlen(as, arg0Val);
1578
- IntervalValue strLen1 = getStrlen(as, arg1Val);
1579
- IntervalValue totalLen = strLen0 + strLen1;
1580
- handleMemcpy(as, arg0Val, arg1Val, strLen1, strLen0.lb().getIntNumeral());
1581
- // do memcpy
1582
- }
1583
- else if (std::find(strncatGroup.begin(), strncatGroup.end(), fun->getName()) != strncatGroup.end())
1584
- {
1585
- const SVFValue* arg0Val = call->getArgument(0);
1586
- const SVFValue* arg1Val = call->getArgument(1);
1587
- const SVFValue* arg2Val = call->getArgument(2);
1588
- IntervalValue arg2Num = as[svfir->getValueNode(arg2Val)].getInterval();
1589
- IntervalValue strLen0 = getStrlen(as, arg0Val);
1590
- IntervalValue totalLen = strLen0 + arg2Num;
1591
- handleMemcpy(as, arg0Val, arg1Val, arg2Num, strLen0.lb().getIntNumeral());
1592
- // do memcpy
1593
- }
1594
- else
1595
- {
1596
- assert(false && "unknown strcat function, please add it to strcatGroup or strncatGroup");
1597
- }
1598
- }
1599
-
1600
- void AbstractInterpretation::handleMemcpy(AbstractState& as, const SVF::SVFValue *dst, const SVF::SVFValue *src, IntervalValue len, u32_t start_idx)
1601
- {
1602
- u32_t dstId = svfir->getValueNode(dst); // pts(dstId) = {objid} objbar objtypeinfo->getType().
1603
- u32_t srcId = svfir->getValueNode(src);
1604
- u32_t elemSize = 1;
1605
- if (dst->getType()->isArrayTy())
1606
- {
1607
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
1608
- }
1609
- // memcpy(i32*, i32*, 40)
1610
- else if (dst->getType()->isPointerTy())
1611
- {
1612
- if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(dst)))
1613
- {
1614
- if (elemType->isArrayTy())
1615
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(elemType)->getTypeOfElement()->getByteSize();
1616
- else
1617
- elemSize = elemType->getByteSize();
1618
- }
1619
- else
1620
- {
1621
- elemSize = 1;
1622
- }
1623
- }
1624
- else
1625
- {
1626
- assert(false && "we cannot support this type");
1627
- }
1628
- u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
1629
- u32_t range_val = size / elemSize;
1630
- if (as.inVarToAddrsTable(srcId) && as.inVarToAddrsTable(dstId))
1631
- {
1632
- for (u32_t index = 0; index < range_val; index++)
1633
- {
1634
- // dead loop for string and break if there's a \0. If no \0, it will throw err.
1635
- AbstractValue expr_src =
1636
- as.getGepObjAddrs(srcId, IntervalValue(index));
1637
- AbstractValue expr_dst =
1638
- as.getGepObjAddrs(dstId, IntervalValue(index + start_idx));
1639
- for (const auto &dst: expr_dst.getAddrs())
1640
- {
1641
- for (const auto &src: expr_src.getAddrs())
1642
- {
1643
- u32_t objId = AbstractState::getInternalID(src);
1644
- if (as.inAddrToValTable(objId))
1645
- {
1646
- as.store(dst, as.load(src));
1647
- }
1648
- else if (as.inAddrToAddrsTable(objId))
1649
- {
1650
- as.store(dst, as.load(src));
1651
- }
1652
- }
1653
- }
1654
- }
1655
- }
1656
- }
1657
-
1658
- void AbstractInterpretation::handleMemset(AbstractState& as, const SVF::SVFValue *dst, IntervalValue elem, IntervalValue len)
1659
- {
1660
- u32_t dstId = svfir->getValueNode(dst);
1661
- u32_t size = std::min((u32_t)Options::MaxFieldLimit(), (u32_t) len.lb().getIntNumeral());
1662
- u32_t elemSize = 1;
1663
- if (dst->getType()->isArrayTy())
1664
- {
1665
- elemSize = SVFUtil::dyn_cast<SVFArrayType>(dst->getType())->getTypeOfElement()->getByteSize();
1666
- }
1667
- else if (dst->getType()->isPointerTy())
1668
- {
1669
- if (const SVFType* elemType = as.getPointeeElement(svfir->getValueNode(dst)))
1670
- {
1671
- elemSize = elemType->getByteSize();
1672
- }
1673
- else
1674
- {
1675
- elemSize = 1;
1676
- }
1677
- }
1678
- else
1679
- {
1680
- assert(false && "we cannot support this type");
1681
- }
1682
-
1683
- u32_t range_val = size / elemSize;
1684
- for (u32_t index = 0; index < range_val; index++)
1685
- {
1686
- // dead loop for string and break if there's a \0. If no \0, it will throw err.
1687
- if (as.inVarToAddrsTable(dstId))
1688
- {
1689
- AbstractValue lhs_gep = as.getGepObjAddrs(dstId, IntervalValue(index));
1690
- for (const auto &addr: lhs_gep.getAddrs())
1691
- {
1692
- u32_t objId = AbstractState::getInternalID(addr);
1693
- if (as.inAddrToValTable(objId))
1694
- {
1695
- AbstractValue tmp = as.load(addr);
1696
- tmp.join_with(elem);
1697
- as.store(addr, tmp);
1698
- }
1699
- else
1700
- {
1701
- as.store(addr, elem);
1702
- }
1703
- }
1704
- }
1705
- else
1706
- break;
1707
- }
1708
- }
1709
-
1710
1010
  void AbstractInterpretation::updateStateOnGep(const GepStmt *gep)
1711
1011
  {
1712
1012
  AbstractState& as = getAbsStateFromTrace(gep->getICFGNode());
@@ -1802,7 +1102,7 @@ void AbstractInterpretation::updateStateOnAddr(const AddrStmt *addr)
1802
1102
  AbstractState& as = getAbsStateFromTrace(addr->getICFGNode());
1803
1103
  as.initObjVar(SVFUtil::cast<ObjVar>(addr->getRHSVar()));
1804
1104
  if (addr->getRHSVar()->getType()->getKind() == SVFType::SVFIntegerTy)
1805
- as[addr->getRHSVarID()].getInterval().meet_with(getRangeLimitFromType(addr->getRHSVar()->getType()));
1105
+ as[addr->getRHSVarID()].getInterval().meet_with(utils->getRangeLimitFromType(addr->getRHSVar()->getType()));
1806
1106
  as[addr->getLHSVarID()] = as[addr->getRHSVarID()];
1807
1107
  }
1808
1108
 
@@ -2162,7 +1462,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2162
1462
  if (s8_lb > s8_ub)
2163
1463
  {
2164
1464
  // return range of s8
2165
- return this->getRangeLimitFromType(dstType);
1465
+ return utils->getRangeLimitFromType(dstType);
2166
1466
  }
2167
1467
  return IntervalValue(s8_lb, s8_ub);
2168
1468
  }
@@ -2174,7 +1474,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2174
1474
  if (s16_lb > s16_ub)
2175
1475
  {
2176
1476
  // return range of s16
2177
- return this->getRangeLimitFromType(dstType);
1477
+ return utils->getRangeLimitFromType(dstType);
2178
1478
  }
2179
1479
  return IntervalValue(s16_lb, s16_ub);
2180
1480
  }
@@ -2186,7 +1486,7 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2186
1486
  if (s32_lb > s32_ub)
2187
1487
  {
2188
1488
  // return range of s32
2189
- return this->getRangeLimitFromType(dstType);
1489
+ return utils->getRangeLimitFromType(dstType);
2190
1490
  }
2191
1491
  return IntervalValue(s32_lb, s32_ub);
2192
1492
  }
@@ -2262,78 +1562,5 @@ void AbstractInterpretation::updateStateOnCopy(const CopyStmt *copy)
2262
1562
  }
2263
1563
  }
2264
1564
 
2265
- /**
2266
- * This function, getRangeLimitFromType, calculates the lower and upper bounds of
2267
- * a numeric range for a given SVFType. It is used to determine the possible value
2268
- * range of integer types. If the type is an SVFIntegerType, it calculates the bounds
2269
- * based on the size and signedness of the type. The calculated bounds are returned
2270
- * as an IntervalValue representing the lower (lb) and upper (ub) limits of the range.
2271
- *
2272
- * @param type The SVFType for which to calculate the value range.
2273
- *
2274
- * @return An IntervalValue representing the lower and upper bounds of the range.
2275
- */
2276
- IntervalValue AbstractInterpretation::getRangeLimitFromType(const SVFType* type)
2277
- {
2278
- if (const SVFIntegerType* intType = SVFUtil::dyn_cast<SVFIntegerType>(type))
2279
- {
2280
- u32_t bits = type->getByteSize() * 8;
2281
- s64_t ub = 0;
2282
- s64_t lb = 0;
2283
- if (bits >= 32)
2284
- {
2285
- if (intType->isSigned())
2286
- {
2287
- ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
2288
- lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
2289
- }
2290
- else
2291
- {
2292
- ub = static_cast<s64_t>(std::numeric_limits<u32_t>::max());
2293
- lb = static_cast<s64_t>(std::numeric_limits<u32_t>::min());
2294
- }
2295
- }
2296
- else if (bits == 16)
2297
- {
2298
- if (intType->isSigned())
2299
- {
2300
- ub = static_cast<s64_t>(std::numeric_limits<s16_t>::max());
2301
- lb = static_cast<s64_t>(std::numeric_limits<s16_t>::min());
2302
- }
2303
- else
2304
- {
2305
- ub = static_cast<s64_t>(std::numeric_limits<u16_t>::max());
2306
- lb = static_cast<s64_t>(std::numeric_limits<u16_t>::min());
2307
- }
2308
- }
2309
- else if (bits == 8)
2310
- {
2311
- if (intType->isSigned())
2312
- {
2313
- ub = static_cast<s64_t>(std::numeric_limits<int8_t>::max());
2314
- lb = static_cast<s64_t>(std::numeric_limits<int8_t>::min());
2315
- }
2316
- else
2317
- {
2318
- ub = static_cast<s64_t>(std::numeric_limits<u_int8_t>::max());
2319
- lb = static_cast<s64_t>(std::numeric_limits<u_int8_t>::min());
2320
- }
2321
- }
2322
- return IntervalValue(lb, ub);
2323
- }
2324
- else if (SVFUtil::isa<SVFOtherType>(type))
2325
- {
2326
- // handle other type like float double, set s32_t as the range
2327
- s64_t ub = static_cast<s64_t>(std::numeric_limits<s32_t>::max());
2328
- s64_t lb = static_cast<s64_t>(std::numeric_limits<s32_t>::min());
2329
- return IntervalValue(lb, ub);
2330
- }
2331
- else
2332
- {
2333
- return IntervalValue::top();
2334
- // other types, return top interval
2335
- }
2336
- }
2337
-
2338
1565
 
2339
1566