@@ -5471,6 +5471,100 @@ void Executor::executeFree(ExecutionState &state, ref<Expr> address,
5471
5471
}
5472
5472
}
5473
5473
5474
+ ExecutionState *Executor::handleNullPointerException (ExecutionState &state,
5475
+ ref<Expr> base) {
5476
+ StatePair branches =
5477
+ forkInternal (state, Expr::createIsZero (base), BranchType::MemOp);
5478
+ ExecutionState *bound = branches.first ;
5479
+ if (!bound) {
5480
+ return branches.second ;
5481
+ }
5482
+
5483
+ // If there are no markers on `malloc` returning nullptr,
5484
+ // then `confidence` depends on presence of `unbound` state.
5485
+ if (!bound->outOfMemoryMarkers .empty ()) {
5486
+ // bound constraints already contain `Expr::createIsZero()`
5487
+ std::vector<const Array *> markersArrays;
5488
+ markersArrays.reserve (bound->outOfMemoryMarkers .size ());
5489
+ findSymbolicObjects (bound->outOfMemoryMarkers .begin (),
5490
+ bound->outOfMemoryMarkers .end (), markersArrays);
5491
+
5492
+ // Do some iterations (2-3) to figure out if error is confident.
5493
+ ref<Expr> allExcludedVectorsOfMarkers = Expr::createTrue ();
5494
+
5495
+ bool convinced = false ;
5496
+ for (int tpCheckIteration = 0 ; tpCheckIteration < 2 ; ++tpCheckIteration) {
5497
+ ref<SolverResponse> isConfidentResponse;
5498
+ if (!solver->getResponse (bound->constraints .cs (),
5499
+ allExcludedVectorsOfMarkers, isConfidentResponse,
5500
+ bound->queryMetaData )) {
5501
+ terminateStateOnSolverError (*bound, " Query timeout" );
5502
+ }
5503
+
5504
+ if (isa<ValidResponse>(isConfidentResponse)) {
5505
+ reportStateOnTargetError (*bound,
5506
+ ReachWithError::MustBeNullPointerException);
5507
+
5508
+ terminateStateOnProgramError (
5509
+ *bound,
5510
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5511
+ " memory error: null pointer exception" ),
5512
+ StateTerminationConfidenceCategory::CONFIDENT);
5513
+ convinced = true ;
5514
+ break ;
5515
+ }
5516
+
5517
+ // Receive current values of markers
5518
+ std::vector<SparseStorage<unsigned char >> boundSetSolution;
5519
+ isConfidentResponse->tryGetInitialValuesFor (markersArrays,
5520
+ boundSetSolution);
5521
+ Assignment nonConfidentResponseAssignment (markersArrays,
5522
+ boundSetSolution);
5523
+
5524
+ // Exclude this combinations of markers
5525
+
5526
+ ref<Expr> conjExcludedVectorOfMarkers = Expr::createTrue ();
5527
+ for (ref<Expr> marker : bound->outOfMemoryMarkers ) {
5528
+ conjExcludedVectorOfMarkers = AndExpr::create (
5529
+ conjExcludedVectorOfMarkers,
5530
+ EqExpr::create (marker,
5531
+ nonConfidentResponseAssignment.evaluate (marker)));
5532
+ }
5533
+
5534
+ allExcludedVectorsOfMarkers =
5535
+ OrExpr::create (allExcludedVectorsOfMarkers,
5536
+ NotExpr::create (conjExcludedVectorOfMarkers));
5537
+ }
5538
+
5539
+ if (!convinced) {
5540
+ reportStateOnTargetError (*bound,
5541
+ ReachWithError::MayBeNullPointerException);
5542
+
5543
+ terminateStateOnProgramError (
5544
+ *bound,
5545
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5546
+ " memory error: null pointer exception" ),
5547
+ StateTerminationConfidenceCategory::PROBABLY);
5548
+ }
5549
+
5550
+ } else {
5551
+ auto error = branches.second != nullptr
5552
+ ? ReachWithError::MayBeNullPointerException
5553
+ : ReachWithError::MustBeNullPointerException;
5554
+ reportStateOnTargetError (*bound, error);
5555
+
5556
+ terminateStateOnProgramError (
5557
+ *bound,
5558
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5559
+ " memory error: null pointer exception" ),
5560
+ branches.second != nullptr
5561
+ ? StateTerminationConfidenceCategory::PROBABLY
5562
+ : StateTerminationConfidenceCategory::CONFIDENT);
5563
+ }
5564
+
5565
+ return branches.second ;
5566
+ }
5567
+
5474
5568
bool Executor::resolveExact (ExecutionState &estate, ref<Expr> address,
5475
5569
KType *type, ExactResolutionList &results,
5476
5570
const std::string &name) {
@@ -5496,20 +5590,12 @@ bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
5496
5590
Simplificator::simplifyExpr (estate.constraints .cs (), base).simplified ;
5497
5591
uniqueBase = toUnique (estate, uniqueBase);
5498
5592
5499
- StatePair branches =
5500
- forkInternal (estate, Expr::createIsZero (base), BranchType::MemOp);
5501
- ExecutionState *bound = branches.first ;
5502
- if (bound) {
5503
- auto error = isReadFromSymbolicArray (uniqueBase)
5504
- ? ReachWithError::MayBeNullPointerException
5505
- : ReachWithError::MustBeNullPointerException;
5506
- terminateStateOnTargetError (*bound, error);
5507
- }
5508
- if (!branches.second ) {
5509
- address = Expr::createPointer (0 );
5593
+ ExecutionState *handledNPEState = handleNullPointerException (estate, base);
5594
+ if (!handledNPEState) {
5595
+ return false ;
5510
5596
}
5511
5597
5512
- ExecutionState &state = *branches. second ;
5598
+ ExecutionState &state = *handledNPEState ;
5513
5599
5514
5600
ResolutionList rl;
5515
5601
bool mayBeOutOfBound = true ;
@@ -6266,97 +6352,9 @@ void Executor::executeMemoryOperation(
6266
6352
6267
6353
ref<Expr> uniqueBase = toUnique (estate, base);
6268
6354
6269
- StatePair branches =
6270
- forkInternal (estate, Expr::createIsZero (base), BranchType::MemOp);
6271
- ExecutionState *bound = branches.first ;
6272
-
6273
- if (bound) {
6274
- // If there are no markers on `malloc` returning nullptr,
6275
- // then `confidence` depends on presence of `unbound` state.
6276
- if (!bound->outOfMemoryMarkers .empty ()) {
6277
- // bound constraints already contain `Expr::createIsZero()`
6278
- std::vector<const Array *> markersArrays;
6279
- markersArrays.reserve (bound->outOfMemoryMarkers .size ());
6280
- findSymbolicObjects (bound->outOfMemoryMarkers .begin (),
6281
- bound->outOfMemoryMarkers .end (), markersArrays);
6282
-
6283
- // Do some iterations (2-3) to figure out if error is confident.
6284
- ref<Expr> allExcludedVectorsOfMarkers = Expr::createTrue ();
6285
-
6286
- bool convinced = false ;
6287
- for (int tpCheckIteration = 0 ; tpCheckIteration < 2 ; ++tpCheckIteration) {
6288
- ref<SolverResponse> isConfidentResponse;
6289
- if (!solver->getResponse (bound->constraints .cs (),
6290
- allExcludedVectorsOfMarkers,
6291
- isConfidentResponse, bound->queryMetaData )) {
6292
- terminateStateOnSolverError (*bound, " Query timeout" );
6293
- }
6294
-
6295
- if (isa<ValidResponse>(isConfidentResponse)) {
6296
- reportStateOnTargetError (*bound,
6297
- ReachWithError::MustBeNullPointerException);
6298
-
6299
- terminateStateOnProgramError (
6300
- *bound,
6301
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6302
- " memory error: null pointer exception" ),
6303
- StateTerminationConfidenceCategory::CONFIDENT);
6304
- convinced = true ;
6305
- break ;
6306
- }
6307
-
6308
- // Receive current values of markers
6309
- std::vector<SparseStorage<unsigned char >> boundSetSolution;
6310
- isConfidentResponse->tryGetInitialValuesFor (markersArrays,
6311
- boundSetSolution);
6312
- Assignment nonConfidentResponseAssignment (markersArrays,
6313
- boundSetSolution);
6314
-
6315
- // Exclude this combinations of markers
6316
-
6317
- ref<Expr> conjExcludedVectorOfMarkers = Expr::createTrue ();
6318
- for (ref<Expr> marker : bound->outOfMemoryMarkers ) {
6319
- conjExcludedVectorOfMarkers = AndExpr::create (
6320
- conjExcludedVectorOfMarkers,
6321
- EqExpr::create (marker,
6322
- nonConfidentResponseAssignment.evaluate (marker)));
6323
- }
6324
-
6325
- allExcludedVectorsOfMarkers =
6326
- OrExpr::create (allExcludedVectorsOfMarkers,
6327
- NotExpr::create (conjExcludedVectorOfMarkers));
6328
- }
6329
-
6330
- if (!convinced) {
6331
- reportStateOnTargetError (*bound,
6332
- ReachWithError::MayBeNullPointerException);
6333
-
6334
- terminateStateOnProgramError (
6335
- *bound,
6336
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6337
- " memory error: null pointer exception" ),
6338
- StateTerminationConfidenceCategory::PROBABLY);
6339
- }
6340
-
6341
- } else {
6342
- auto error = branches.second != nullptr
6343
- ? ReachWithError::MayBeNullPointerException
6344
- : ReachWithError::MustBeNullPointerException;
6345
- reportStateOnTargetError (*bound, error);
6346
-
6347
- terminateStateOnProgramError (
6348
- *bound,
6349
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6350
- " memory error: null pointer exception" ),
6351
- branches.second != nullptr
6352
- ? StateTerminationConfidenceCategory::PROBABLY
6353
- : StateTerminationConfidenceCategory::CONFIDENT);
6354
- }
6355
- }
6356
-
6357
- if (!branches.second )
6355
+ ExecutionState *state = handleNullPointerException (estate, base);
6356
+ if (!state)
6358
6357
return ;
6359
- ExecutionState *state = branches.second ;
6360
6358
6361
6359
// fast path: single in-bounds resolution
6362
6360
IDType idFastResult;
@@ -6542,7 +6540,7 @@ void Executor::executeMemoryOperation(
6542
6540
maxNewWriteableOSSize =
6543
6541
std::max (maxNewWriteableOSSize, wos->getSparseStorageEntries ());
6544
6542
if (wos->readOnly ) {
6545
- branches =
6543
+ StatePair branches =
6546
6544
forkInternal (*state, Expr::createIsZero (unboundConditions[i]),
6547
6545
BranchType::MemOp);
6548
6546
assert (branches.first );
0 commit comments