@@ -5497,6 +5497,100 @@ void Executor::executeFree(ExecutionState &state, ref<Expr> address,
5497
5497
}
5498
5498
}
5499
5499
5500
+ ExecutionState *Executor::handleNullPointerException (ExecutionState &state,
5501
+ ref<Expr> base) {
5502
+ StatePair branches =
5503
+ forkInternal (state, Expr::createIsZero (base), BranchType::MemOp);
5504
+ ExecutionState *bound = branches.first ;
5505
+ if (!bound) {
5506
+ return branches.second ;
5507
+ }
5508
+
5509
+ // If there are no markers on `malloc` returning nullptr,
5510
+ // then `confidence` depends on presence of `unbound` state.
5511
+ if (!bound->outOfMemoryMarkers .empty ()) {
5512
+ // bound constraints already contain `Expr::createIsZero()`
5513
+ std::vector<const Array *> markersArrays;
5514
+ markersArrays.reserve (bound->outOfMemoryMarkers .size ());
5515
+ findSymbolicObjects (bound->outOfMemoryMarkers .begin (),
5516
+ bound->outOfMemoryMarkers .end (), markersArrays);
5517
+
5518
+ // Do some iterations (2-3) to figure out if error is confident.
5519
+ ref<Expr> allExcludedVectorsOfMarkers = Expr::createTrue ();
5520
+
5521
+ bool convinced = false ;
5522
+ for (int tpCheckIteration = 0 ; tpCheckIteration < 2 ; ++tpCheckIteration) {
5523
+ ref<SolverResponse> isConfidentResponse;
5524
+ if (!solver->getResponse (bound->constraints .cs (),
5525
+ allExcludedVectorsOfMarkers, isConfidentResponse,
5526
+ bound->queryMetaData )) {
5527
+ terminateStateOnSolverError (*bound, " Query timeout" );
5528
+ }
5529
+
5530
+ if (isa<ValidResponse>(isConfidentResponse)) {
5531
+ reportStateOnTargetError (*bound,
5532
+ ReachWithError::MustBeNullPointerException);
5533
+
5534
+ terminateStateOnProgramError (
5535
+ *bound,
5536
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5537
+ " memory error: null pointer exception" ),
5538
+ StateTerminationConfidenceCategory::CONFIDENT);
5539
+ convinced = true ;
5540
+ break ;
5541
+ }
5542
+
5543
+ // Receive current values of markers
5544
+ std::vector<SparseStorage<unsigned char >> boundSetSolution;
5545
+ isConfidentResponse->tryGetInitialValuesFor (markersArrays,
5546
+ boundSetSolution);
5547
+ Assignment nonConfidentResponseAssignment (markersArrays,
5548
+ boundSetSolution);
5549
+
5550
+ // Exclude this combinations of markers
5551
+
5552
+ ref<Expr> conjExcludedVectorOfMarkers = Expr::createTrue ();
5553
+ for (ref<Expr> marker : bound->outOfMemoryMarkers ) {
5554
+ conjExcludedVectorOfMarkers = AndExpr::create (
5555
+ conjExcludedVectorOfMarkers,
5556
+ EqExpr::create (marker,
5557
+ nonConfidentResponseAssignment.evaluate (marker)));
5558
+ }
5559
+
5560
+ allExcludedVectorsOfMarkers =
5561
+ OrExpr::create (allExcludedVectorsOfMarkers,
5562
+ NotExpr::create (conjExcludedVectorOfMarkers));
5563
+ }
5564
+
5565
+ if (!convinced) {
5566
+ reportStateOnTargetError (*bound,
5567
+ ReachWithError::MayBeNullPointerException);
5568
+
5569
+ terminateStateOnProgramError (
5570
+ *bound,
5571
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5572
+ " memory error: null pointer exception" ),
5573
+ StateTerminationConfidenceCategory::PROBABLY);
5574
+ }
5575
+
5576
+ } else {
5577
+ auto error = branches.second != nullptr
5578
+ ? ReachWithError::MayBeNullPointerException
5579
+ : ReachWithError::MustBeNullPointerException;
5580
+ reportStateOnTargetError (*bound, error);
5581
+
5582
+ terminateStateOnProgramError (
5583
+ *bound,
5584
+ new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
5585
+ " memory error: null pointer exception" ),
5586
+ branches.second != nullptr
5587
+ ? StateTerminationConfidenceCategory::PROBABLY
5588
+ : StateTerminationConfidenceCategory::CONFIDENT);
5589
+ }
5590
+
5591
+ return branches.second ;
5592
+ }
5593
+
5500
5594
bool Executor::resolveExact (ExecutionState &estate, ref<Expr> address,
5501
5595
KType *type, ExactResolutionList &results,
5502
5596
const std::string &name) {
@@ -5522,20 +5616,12 @@ bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
5522
5616
Simplificator::simplifyExpr (estate.constraints .cs (), base).simplified ;
5523
5617
uniqueBase = toUnique (estate, uniqueBase);
5524
5618
5525
- StatePair branches =
5526
- forkInternal (estate, Expr::createIsZero (base), BranchType::MemOp);
5527
- ExecutionState *bound = branches.first ;
5528
- if (bound) {
5529
- auto error = isReadFromSymbolicArray (uniqueBase)
5530
- ? ReachWithError::MayBeNullPointerException
5531
- : ReachWithError::MustBeNullPointerException;
5532
- terminateStateOnTargetError (*bound, error);
5533
- }
5534
- if (!branches.second ) {
5535
- address = Expr::createPointer (0 );
5619
+ ExecutionState *handledNPEState = handleNullPointerException (estate, base);
5620
+ if (!handledNPEState) {
5621
+ return false ;
5536
5622
}
5537
5623
5538
- ExecutionState &state = *branches. second ;
5624
+ ExecutionState &state = *handledNPEState ;
5539
5625
5540
5626
ResolutionList rl;
5541
5627
bool mayBeOutOfBound = true ;
@@ -6316,97 +6402,9 @@ void Executor::executeMemoryOperation(
6316
6402
6317
6403
ref<Expr> uniqueBase = toUnique (estate, base);
6318
6404
6319
- StatePair branches =
6320
- forkInternal (estate, Expr::createIsZero (base), BranchType::MemOp);
6321
- ExecutionState *bound = branches.first ;
6322
-
6323
- if (bound) {
6324
- // If there are no markers on `malloc` returning nullptr,
6325
- // then `confidence` depends on presence of `unbound` state.
6326
- if (!bound->outOfMemoryMarkers .empty ()) {
6327
- // bound constraints already contain `Expr::createIsZero()`
6328
- std::vector<const Array *> markersArrays;
6329
- markersArrays.reserve (bound->outOfMemoryMarkers .size ());
6330
- findSymbolicObjects (bound->outOfMemoryMarkers .begin (),
6331
- bound->outOfMemoryMarkers .end (), markersArrays);
6332
-
6333
- // Do some iterations (2-3) to figure out if error is confident.
6334
- ref<Expr> allExcludedVectorsOfMarkers = Expr::createTrue ();
6335
-
6336
- bool convinced = false ;
6337
- for (int tpCheckIteration = 0 ; tpCheckIteration < 2 ; ++tpCheckIteration) {
6338
- ref<SolverResponse> isConfidentResponse;
6339
- if (!solver->getResponse (bound->constraints .cs (),
6340
- allExcludedVectorsOfMarkers,
6341
- isConfidentResponse, bound->queryMetaData )) {
6342
- terminateStateOnSolverError (*bound, " Query timeout" );
6343
- }
6344
-
6345
- if (isa<ValidResponse>(isConfidentResponse)) {
6346
- reportStateOnTargetError (*bound,
6347
- ReachWithError::MustBeNullPointerException);
6348
-
6349
- terminateStateOnProgramError (
6350
- *bound,
6351
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6352
- " memory error: null pointer exception" ),
6353
- StateTerminationConfidenceCategory::CONFIDENT);
6354
- convinced = true ;
6355
- break ;
6356
- }
6357
-
6358
- // Receive current values of markers
6359
- std::vector<SparseStorage<unsigned char >> boundSetSolution;
6360
- isConfidentResponse->tryGetInitialValuesFor (markersArrays,
6361
- boundSetSolution);
6362
- Assignment nonConfidentResponseAssignment (markersArrays,
6363
- boundSetSolution);
6364
-
6365
- // Exclude this combinations of markers
6366
-
6367
- ref<Expr> conjExcludedVectorOfMarkers = Expr::createTrue ();
6368
- for (ref<Expr> marker : bound->outOfMemoryMarkers ) {
6369
- conjExcludedVectorOfMarkers = AndExpr::create (
6370
- conjExcludedVectorOfMarkers,
6371
- EqExpr::create (marker,
6372
- nonConfidentResponseAssignment.evaluate (marker)));
6373
- }
6374
-
6375
- allExcludedVectorsOfMarkers =
6376
- OrExpr::create (allExcludedVectorsOfMarkers,
6377
- NotExpr::create (conjExcludedVectorOfMarkers));
6378
- }
6379
-
6380
- if (!convinced) {
6381
- reportStateOnTargetError (*bound,
6382
- ReachWithError::MayBeNullPointerException);
6383
-
6384
- terminateStateOnProgramError (
6385
- *bound,
6386
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6387
- " memory error: null pointer exception" ),
6388
- StateTerminationConfidenceCategory::PROBABLY);
6389
- }
6390
-
6391
- } else {
6392
- auto error = branches.second != nullptr
6393
- ? ReachWithError::MayBeNullPointerException
6394
- : ReachWithError::MustBeNullPointerException;
6395
- reportStateOnTargetError (*bound, error);
6396
-
6397
- terminateStateOnProgramError (
6398
- *bound,
6399
- new ErrorEvent (locationOf (*bound), StateTerminationType::Ptr ,
6400
- " memory error: null pointer exception" ),
6401
- branches.second != nullptr
6402
- ? StateTerminationConfidenceCategory::PROBABLY
6403
- : StateTerminationConfidenceCategory::CONFIDENT);
6404
- }
6405
- }
6406
-
6407
- if (!branches.second )
6405
+ ExecutionState *state = handleNullPointerException (estate, base);
6406
+ if (!state)
6408
6407
return ;
6409
- ExecutionState *state = branches.second ;
6410
6408
6411
6409
// fast path: single in-bounds resolution
6412
6410
IDType idFastResult;
@@ -6602,7 +6600,7 @@ void Executor::executeMemoryOperation(
6602
6600
maxNewWriteableOSSize =
6603
6601
std::max (maxNewWriteableOSSize, wos->getSparseStorageEntries ());
6604
6602
if (wos->readOnly ) {
6605
- branches =
6603
+ StatePair branches =
6606
6604
forkInternal (*state, Expr::createIsZero (unboundConditions[i]),
6607
6605
BranchType::MemOp);
6608
6606
assert (branches.first );
0 commit comments