Skip to content

Commit 665f227

Browse files
author
brianhuffman
authored
Merge pull request #826 from GaloisInc/methodspec
Fix soundness bug related to disjointness checking (#641)
2 parents 8914f33 + 3481ffd commit 665f227

File tree

17 files changed

+195
-53
lines changed

17 files changed

+195
-53
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
- mkdir -p s2n/test-deps/saw/bin
8686
- cp bin/saw s2n/test-deps/saw/bin
8787
- cd s2n
88-
- git checkout cd7282102bf5e65cc8b324c4127c7943c71c8513
88+
- git checkout 90b8913a01c6421444d19aaab798d413872cf6f0
8989
before_script:
9090
- export TESTS=sawHMAC
9191
script:

intTests/test_llvm_non_fresh/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test.bc : test.c
2+
clang -c -emit-llvm -g -o test.bc test.c

intTests/test_llvm_non_fresh/test.bc

2.72 KB
Binary file not shown.

intTests/test_llvm_non_fresh/test.c

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
uint64_t *foo (uint64_t *x) {
5+
return x;
6+
}
7+
8+
int bar (uint64_t *x) {
9+
return (foo(x) == x);
10+
}

intTests/test_llvm_non_fresh/test.saw

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// This test checks whether we can verify a spec that says a function
2+
// returns a fresh pointer, when in actuality the function returns
3+
// a pointer from the input. It is a regression test for saw-script
4+
// issue #641.
5+
// https://github.com/GaloisInc/saw-script/issues/641
6+
7+
bc <- llvm_load_module "test.bc";
8+
9+
let i64 = llvm_int 64;
10+
11+
foo_ov <-
12+
crucible_llvm_verify bc "foo" [] false
13+
do {
14+
x <- crucible_alloc i64;
15+
crucible_execute_func [x];
16+
crucible_return x;
17+
}
18+
z3;
19+
20+
fails (
21+
crucible_llvm_verify bc "foo" [] false
22+
do {
23+
x <- crucible_alloc i64;
24+
crucible_execute_func [x];
25+
y <- crucible_alloc i64;
26+
crucible_return y;
27+
}
28+
z3
29+
);
30+
31+
fails (
32+
crucible_llvm_verify bc "bar" [foo_ov] false
33+
do {
34+
x <- crucible_alloc i64;
35+
crucible_execute_func [x];
36+
crucible_return (crucible_term {{ 0 : [32] }});
37+
}
38+
z3
39+
);
40+
41+
bar_ov1 <-
42+
crucible_llvm_verify bc "bar" [] false
43+
do {
44+
x <- crucible_alloc i64;
45+
crucible_execute_func [x];
46+
crucible_return (crucible_term {{ 1 : [32] }});
47+
}
48+
z3;

intTests/test_llvm_non_fresh/test.sh

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$SAW test.saw
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test.bc : test.c
2+
clang -c -emit-llvm -g -o test.bc test.c
2.61 KB
Binary file not shown.
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
uint64_t glob;
5+
6+
uint64_t *foo () {
7+
return &glob;
8+
}
9+
10+
int bar () {
11+
return (foo() == &glob);
12+
}
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// This test checks whether we can verify a spec that says a function
2+
// returns a fresh pointer, when in actuality the function returns
3+
// a global. It is a regression test for saw-script issue #641.
4+
// https://github.com/GaloisInc/saw-script/issues/641
5+
6+
bc <- llvm_load_module "test.bc";
7+
8+
let i64 = llvm_int 64;
9+
10+
fails (
11+
crucible_llvm_verify bc "foo" [] false
12+
do {
13+
crucible_alloc_global "glob";
14+
crucible_execute_func [];
15+
x <- crucible_alloc i64;
16+
crucible_return x;
17+
}
18+
z3
19+
);
20+
21+
/*
22+
bar_ov0 <-
23+
crucible_llvm_verify bc "bar" [foo_ov] false
24+
do {
25+
crucible_execute_func [];
26+
crucible_return (crucible_term {{ 0 : [32] }});
27+
}
28+
z3;
29+
*/
30+
31+
bar_ov1 <-
32+
crucible_llvm_verify bc "bar" [] false
33+
do {
34+
crucible_alloc_global "glob";
35+
crucible_execute_func [];
36+
crucible_return (crucible_term {{ 1 : [32] }});
37+
}
38+
z3;
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
$SAW test.saw

s2nTests/docker/s2n.dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ RUN mkdir -p /saw-script && \
1919
git clone https://github.com/GaloisInc/s2n.git && \
2020
mkdir -p s2n/test-deps/saw/bin && \
2121
cd s2n && \
22-
git checkout cd7282102bf5e65cc8b324c4127c7943c71c8513
22+
git checkout 90b8913a01c6421444d19aaab798d413872cf6f0
2323

2424
COPY scripts/s2n-entrypoint.sh /entrypoint.sh
2525
ENTRYPOINT [ "/entrypoint.sh" ]

src/SAWScript/Crucible/Common/MethodSpec.hs

+2-5
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,7 @@ deriving instance ( SetupValueHas Show ext
325325
-- | Verification state (either pre- or post-) specification
326326
data StateSpec ext = StateSpec
327327
{ _csAllocs :: Map AllocIndex (AllocSpec ext)
328-
-- ^ allocated pointers
329-
, _csFreshPointers :: Map AllocIndex (AllocSpec ext)
330-
-- ^ symbolic pointers
328+
-- ^ allocated or declared pointers
331329
, _csPointsTos :: [PointsTo ext]
332330
-- ^ points-to statements
333331
, _csConditions :: [SetupCondition ext]
@@ -343,7 +341,6 @@ makeLenses ''StateSpec
343341
initialStateSpec :: StateSpec ext
344342
initialStateSpec = StateSpec
345343
{ _csAllocs = Map.empty
346-
, _csFreshPointers = Map.empty -- TODO: this is LLVM-specific
347344
, _csPointsTos = []
348345
, _csConditions = []
349346
, _csFreshVars = []
@@ -396,7 +393,7 @@ ppMethodSpec methodSpec =
396393
csAllocations :: CrucibleMethodSpecIR ext -> Map AllocIndex (AllocSpec ext)
397394
csAllocations
398395
= Map.unions
399-
. toListOf ((csPreState <> csPostState) . (csAllocs <> csFreshPointers))
396+
. toListOf ((csPreState <> csPostState) . csAllocs)
400397

401398
csTypeNames :: CrucibleMethodSpecIR ext -> Map AllocIndex (TypeName ext)
402399
csTypeNames

src/SAWScript/Crucible/LLVM/Builtins.hs

+15-11
Original file line numberDiff line numberDiff line change
@@ -693,16 +693,10 @@ verifyPrestate opts cc mspec globals =
693693
let Just mem = Crucible.lookupGlobal lvar globals
694694

695695
-- Allocate LLVM memory for each 'crucible_alloc'
696-
(env1, mem') <- runStateT
697-
(traverse (doAlloc cc) $ mspec ^. MS.csPreState . MS.csAllocs)
696+
(env, mem') <- runStateT
697+
(Map.traverseWithKey (doAlloc cc) (mspec ^. MS.csPreState . MS.csAllocs))
698698
mem
699699

700-
env2 <-
701-
Map.traverseWithKey
702-
(\k _ -> executeFreshPointer cc k)
703-
(mspec ^. MS.csPreState . MS.csFreshPointers)
704-
let env = Map.unions [env1, env2]
705-
706700
mem'' <- setupGlobalAllocs cc mspec mem'
707701

708702
mem''' <- setupPrePointsTos mspec opts cc env (mspec ^. MS.csPreState . MS.csPointsTos) mem''
@@ -875,9 +869,13 @@ assertEqualVals cc v1 v2 =
875869
doAlloc ::
876870
(Crucible.HasPtrWidth (Crucible.ArchWidth arch)) =>
877871
LLVMCrucibleContext arch ->
872+
AllocIndex ->
878873
LLVMAllocSpec ->
879874
StateT MemImpl IO (LLVMPtr (Crucible.ArchWidth arch))
880-
doAlloc cc (LLVMAllocSpec mut _memTy alignment sz loc) = StateT $ \mem ->
875+
doAlloc cc i (LLVMAllocSpec mut _memTy alignment sz loc fresh)
876+
| fresh = liftIO $ executeFreshPointer cc i
877+
| otherwise =
878+
StateT $ \mem ->
881879
do let sym = cc^.ccBackend
882880
sz' <- liftIO $ resolveSAWSymBV cc Crucible.PtrWidth sz
883881
let l = show (W4.plSourceLoc loc)
@@ -1157,7 +1155,10 @@ verifyPoststate opts sc cc mspec env0 globals ret =
11571155
io $
11581156
runOverrideMatcher sym globals env0 terms0 initialFree poststateLoc $
11591157
do matchResult
1160-
learnCond opts sc cc mspec PostState (mspec ^. MS.csGlobalAllocs) (mspec ^. MS.csPostState)
1158+
learnCond opts sc cc mspec PostState
1159+
(mspec ^. MS.csGlobalAllocs)
1160+
(mspec ^. MS.csPreState . MS.csAllocs)
1161+
(mspec ^. MS.csPostState)
11611162

11621163
st <-
11631164
case matchPost of
@@ -1756,6 +1757,7 @@ crucible_alloc_with_mutability_and_size mut sz alignment bic opts lty =
17561757
, _allocSpecAlign = alignment'
17571758
, _allocSpecBytes = sz''
17581759
, _allocSpecLoc = loc
1760+
, _allocSpecFresh = False
17591761
}
17601762

17611763
crucible_alloc ::
@@ -1861,6 +1863,7 @@ crucible_symbolic_alloc bic _opts ro align_bytes sz =
18611863
, _allocSpecAlign = alignment
18621864
, _allocSpecBytes = sz
18631865
, _allocSpecLoc = loc
1866+
, _allocSpecFresh = False
18641867
}
18651868
n <- Setup.csVarCounter <<%= nextAllocIndex
18661869
Setup.currentState . MS.csAllocs . at n ?= spec
@@ -1907,12 +1910,13 @@ constructFreshPointer mid loc memTy =
19071910
n <- Setup.csVarCounter <<%= nextAllocIndex
19081911
sz <- liftIO $ scPtrWidthBvNat cctx $ Crucible.memTypeSize ?dl memTy
19091912
let alignment = Crucible.memTypeAlign ?dl memTy
1910-
Setup.currentState . MS.csFreshPointers . at n ?=
1913+
Setup.currentState . MS.csAllocs . at n ?=
19111914
LLVMAllocSpec { _allocSpecMut = Crucible.Mutable
19121915
, _allocSpecType = memTy
19131916
, _allocSpecAlign = alignment
19141917
, _allocSpecBytes = sz
19151918
, _allocSpecLoc = loc
1919+
, _allocSpecFresh = True
19161920
}
19171921
-- TODO: refactor
19181922
case mid of

src/SAWScript/Crucible/LLVM/MethodSpecIR.hs

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ module SAWScript.Crucible.LLVM.MethodSpecIR
4343
, allocSpecMut
4444
, allocSpecLoc
4545
, allocSpecBytes
46+
, allocSpecFresh
4647
, mutIso
4748
, isMut
4849
-- * LLVMModule
@@ -187,6 +188,7 @@ data LLVMAllocSpec =
187188
, _allocSpecAlign :: CL.Alignment
188189
, _allocSpecBytes :: Term
189190
, _allocSpecLoc :: ProgramLoc
191+
, _allocSpecFresh :: Bool -- ^ Whether declared with @crucible_fresh_pointer@
190192
}
191193
deriving (Eq, Show)
192194

0 commit comments

Comments
 (0)