Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
cwe_checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
cwe_checker
Commits
76936d8c
Commit
76936d8c
authored
Aug 10, 2021
by
Enkelmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor MemRegion for usage with new DataDomain (#211)
parent
a20a5379
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
239 additions
and
12 deletions
+239
-12
mem_region.rs
src/cwe_checker_lib/src/abstract_domain/mem_region.rs
+0
-0
tests.rs
src/cwe_checker_lib/src/abstract_domain/mem_region/tests.rs
+224
-0
object.rs
src/cwe_checker_lib/src/analysis/pointer_inference/object.rs
+7
-2
object_list.rs
...checker_lib/src/analysis/pointer_inference/object_list.rs
+4
-4
tests.rs
...checker_lib/src/analysis/pointer_inference/state/tests.rs
+4
-6
No files found.
src/cwe_checker_lib/src/abstract_domain/mem_region.rs
View file @
76936d8c
This diff is collapsed.
Click to expand it.
src/cwe_checker_lib/src/abstract_domain/mem_region/tests.rs
0 → 100644
View file @
76936d8c
use
super
::
*
;
use
crate
::
abstract_domain
::
DataDomain
;
use
crate
::
abstract_domain
::
IntervalDomain
;
use
crate
::
abstract_domain
::
RegisterDomain
;
use
crate
::
intermediate_representation
::
*
;
#[derive(PartialEq,
Eq,
Clone,
Copy,
Debug,
Hash,
PartialOrd,
Ord)]
struct
MockDomain
(
i64
,
ByteSize
);
impl
AbstractDomain
for
MockDomain
{
fn
merge
(
&
self
,
other
:
&
Self
)
->
Self
{
assert_eq!
(
self
.
1
,
other
.
1
);
if
self
==
other
{
self
.clone
()
}
else
{
self
.top
()
}
}
fn
is_top
(
&
self
)
->
bool
{
self
==
&
self
.top
()
}
}
impl
SizedDomain
for
MockDomain
{
fn
bytesize
(
&
self
)
->
ByteSize
{
self
.
1
}
fn
new_top
(
bytesize
:
ByteSize
)
->
MockDomain
{
MockDomain
(
0
,
bytesize
)
}
}
impl
HasTop
for
MockDomain
{
fn
top
(
&
self
)
->
Self
{
Self
::
new_top
(
self
.
1
)
}
}
impl
RegisterDomain
for
MockDomain
{
fn
bin_op
(
&
self
,
_op
:
BinOpType
,
_rhs
:
&
Self
)
->
Self
{
Self
::
new_top
(
self
.
1
)
}
fn
un_op
(
&
self
,
_op
:
UnOpType
)
->
Self
{
Self
::
new_top
(
self
.
1
)
}
fn
cast
(
&
self
,
_kind
:
CastOpType
,
width
:
ByteSize
)
->
Self
{
Self
::
new_top
(
width
)
}
fn
subpiece
(
&
self
,
_low_byte
:
ByteSize
,
size
:
ByteSize
)
->
Self
{
Self
::
new_top
(
size
)
}
}
fn
mock
(
val
:
i64
,
bytesize
:
impl
Into
<
ByteSize
>
)
->
MockDomain
{
MockDomain
(
val
,
bytesize
.into
())
}
fn
bv
(
val
:
i64
)
->
Bitvector
{
Bitvector
::
from_i64
(
val
)
}
#[test]
fn
mem_region
()
{
let
mut
region
:
MemRegion
<
MockDomain
>
=
MemRegion
::
new
(
ByteSize
::
from
(
8u64
));
region
.add
(
mock
(
5
,
3u64
),
bv
(
5
));
assert_eq!
(
region
.get
(
bv
(
5
),
ByteSize
::
from
(
3u64
)),
mock
(
5
,
3u64
));
region
.add
(
mock
(
7
,
2u64
),
bv
(
8
));
assert_eq!
(
region
.get
(
bv
(
8
),
ByteSize
::
from
(
2u64
)),
mock
(
7
,
2u64
));
assert_eq!
(
region
.get
(
bv
(
5
),
ByteSize
::
from
(
3u64
)),
mock
(
5
,
3u64
));
assert_eq!
(
region
.get
(
bv
(
5
),
ByteSize
::
from
(
2u64
)),
MockDomain
::
new_top
(
ByteSize
::
new
(
2
))
);
region
.add
(
mock
(
9
,
2u64
),
bv
(
6
));
assert_eq!
(
region
.get
(
bv
(
6
),
ByteSize
::
from
(
2u64
)),
mock
(
9
,
2u64
));
assert_eq!
(
region
.get
(
bv
(
5
),
ByteSize
::
from
(
3u64
)),
MockDomain
::
new_top
(
ByteSize
::
new
(
3
))
);
assert_eq!
(
region
.get
(
bv
(
8
),
ByteSize
::
from
(
2u64
)),
mock
(
7
,
2u64
));
region
.add
(
mock
(
9
,
11u64
),
bv
(
-
3
));
assert_eq!
(
region
.get
(
bv
(
-
3
),
ByteSize
::
from
(
11u64
)),
mock
(
9
,
11u64
));
assert_eq!
(
region
.get
(
bv
(
6
),
ByteSize
::
from
(
2u64
)),
MockDomain
::
new_top
(
ByteSize
::
new
(
2
))
);
assert_eq!
(
region
.get
(
bv
(
8
),
ByteSize
::
from
(
2u64
)),
mock
(
7
,
2u64
));
let
mut
other_region
=
MemRegion
::
new
(
ByteSize
::
from
(
8u64
));
other_region
.add
(
mock
(
7
,
2u64
),
bv
(
8
));
assert
!
(
region
!=
other_region
);
let
merged_region
=
region
.merge
(
&
other_region
);
assert_eq!
(
merged_region
.get
(
bv
(
8
),
ByteSize
::
from
(
2u64
)),
mock
(
7
,
2u64
)
);
assert_eq!
(
merged_region
.get
(
bv
(
-
3
),
ByteSize
::
from
(
11u64
)),
MockDomain
::
new_top
(
ByteSize
::
from
(
11u64
))
);
other_region
.add
(
mock
(
9
,
11u64
),
bv
(
-
3
));
assert_eq!
(
region
,
other_region
);
}
#[test]
fn
merge_test
()
{
let
data
:
fn
(
u64
)
->
DataDomain
<
IntervalDomain
>
=
|
val
|
DataDomain
::
from
(
Bitvector
::
from_u64
(
val
));
let
mut
region
:
MemRegion
<
DataDomain
<
IntervalDomain
>>
=
MemRegion
::
new
(
ByteSize
::
new
(
8
));
region
.add
(
data
(
0
),
Bitvector
::
from_u64
(
0
));
region
.add
(
data
(
8
),
Bitvector
::
from_u64
(
8
));
region
.add
(
data
(
22
),
Bitvector
::
from_u64
(
32
));
region
.add
(
data
(
42
),
Bitvector
::
from_u64
(
50
));
region
.add
(
data
(
70
),
Bitvector
::
from_u64
(
70
));
let
mut
other_region
:
MemRegion
<
DataDomain
<
IntervalDomain
>>
=
MemRegion
::
new
(
ByteSize
::
new
(
8
));
other_region
.add
(
data
(
1
),
Bitvector
::
from_u64
(
0
));
other_region
.add
(
data
(
15
),
Bitvector
::
from_u64
(
15
));
other_region
.add
(
data
(
26
),
Bitvector
::
from_u64
(
25
));
other_region
.add
(
data
(
42
),
Bitvector
::
from_u64
(
58
));
other_region
.add
(
Bitvector
::
from_u8
(
70
)
.into
(),
Bitvector
::
from_u64
(
70
));
let
merged_region
=
region
.merge
(
&&
other_region
);
// Merge elements at target address.
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
0
)),
Some
(
IntervalDomain
::
mock
(
0
,
1
)
.into
())
);
// Overlapping elements are not added to the merged memory region.
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
8
)),
None
);
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
15
)),
None
);
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
25
)),
None
);
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
32
)),
None
);
// Elements only contained in one region are merged with `Top`.
let
mut
elem_plus_top
:
DataDomain
<
IntervalDomain
>
=
Bitvector
::
from_u64
(
42
)
.into
();
elem_plus_top
.set_contains_top_flag
();
assert
!
(
!
elem_plus_top
.is_top
());
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
50
)),
Some
(
elem_plus_top
.clone
())
);
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
58
)),
Some
(
elem_plus_top
)
);
// Elements with differing bytesizes are not added to the merged domain.
assert_eq!
(
merged_region
.get_unsized
(
Bitvector
::
from_u64
(
70
)),
None
);
// Check that no other unexpected elements are contained in the merged region.
assert_eq!
(
merged_region
.values
()
.len
(),
3
);
}
#[test]
fn
do_not_save_top_elements
()
{
let
mut
region
:
MemRegion
<
MockDomain
>
=
MemRegion
::
new
(
ByteSize
::
from
(
8u64
));
region
.add
(
MockDomain
::
new_top
(
ByteSize
::
from
(
4u64
)),
bv
(
5
));
assert_eq!
(
region
.values
()
.len
(),
0
);
let
mut
other_region
:
MemRegion
<
MockDomain
>
=
MemRegion
::
new
(
ByteSize
::
from
(
8u64
));
region
.add
(
mock
(
5
,
4u64
),
bv
(
5
));
other_region
.add
(
mock
(
7
,
4u64
),
bv
(
5
));
let
merged_region
=
region
.merge
(
&
other_region
);
assert_eq!
(
region
.values
()
.len
(),
1
);
assert_eq!
(
other_region
.values
()
.len
(),
1
);
assert_eq!
(
merged_region
.values
()
.len
(),
0
);
}
#[test]
fn
value_removals
()
{
let
mut
region
:
MemRegion
<
MockDomain
>
=
MemRegion
::
new
(
ByteSize
::
from
(
8u64
));
region
.add
(
mock
(
1
,
8u64
),
bv
(
0
));
region
.add
(
mock
(
2
,
8u64
),
bv
(
8
));
region
.add
(
mock
(
3
,
8u64
),
bv
(
16
));
region
.add
(
mock
(
4
,
8u64
),
bv
(
24
));
region
.add
(
mock
(
5
,
8u64
),
bv
(
32
));
assert_eq!
(
region
.values
()
.len
(),
5
);
region
.remove
(
bv
(
2
),
bv
(
3
));
assert_eq!
(
region
.values
()
.len
(),
4
);
region
.remove
(
bv
(
7
),
bv
(
1
));
assert_eq!
(
region
.values
()
.len
(),
4
);
region
.remove
(
bv
(
7
),
bv
(
2
));
assert_eq!
(
region
.values
()
.len
(),
3
);
region
.clear_interval
(
15
,
1
);
assert_eq!
(
region
.values
()
.len
(),
3
);
region
.clear_interval
(
15
,
3
);
assert_eq!
(
region
.values
()
.len
(),
2
);
for
val
in
region
.values_mut
()
{
if
*
val
==
mock
(
5
,
8u64
)
{
*
val
=
mock
(
0
,
8u64
);
// This is a *Top* element
}
}
region
.clear_top_values
();
assert_eq!
(
region
.values
()
.len
(),
1
);
assert_eq!
(
region
.get
(
bv
(
24
),
ByteSize
::
from
(
8u64
)),
mock
(
4
,
8u64
));
}
#[test]
fn
merge_writes_with_top
()
{
let
data
:
DataDomain
<
IntervalDomain
>
=
DataDomain
::
from
(
Bitvector
::
from_u64
(
0
));
let
mut
data_with_top
=
data
.clone
();
data_with_top
.set_contains_top_flag
();
let
mut
region
:
MemRegion
<
DataDomain
<
IntervalDomain
>>
=
MemRegion
::
new
(
ByteSize
::
new
(
8
));
// Test `merge_write_top` method.
region
.add
(
data
.clone
(),
bv
(
0
));
region
.merge_write_top
(
bv
(
0
),
ByteSize
::
new
(
8
));
assert_eq!
(
region
.get_unsized
(
bv
(
0
)),
Some
(
data_with_top
.clone
()));
// `merge_write_top` removes intersecting values if position or size do not match.
region
.add
(
data
.clone
(),
bv
(
8
));
region
.merge_write_top
(
bv
(
5
),
ByteSize
::
new
(
8
));
assert
!
(
region
.inner.values
.is_empty
());
// Test `mark_interval_values_as_top` method.
region
.add
(
data
.clone
(),
bv
(
0
));
region
.add
(
data
.clone
(),
bv
(
8
));
region
.add
(
data
.clone
(),
bv
(
16
));
region
.mark_interval_values_as_top
(
9
,
16
,
ByteSize
::
new
(
1
));
assert_eq!
(
region
.get_unsized
(
bv
(
0
)),
Some
(
data
));
assert_eq!
(
region
.get_unsized
(
bv
(
8
)),
Some
(
data_with_top
.clone
()));
assert_eq!
(
region
.get_unsized
(
bv
(
16
)),
Some
(
data_with_top
.clone
()));
}
src/cwe_checker_lib/src/analysis/pointer_inference/object.rs
View file @
76936d8c
...
...
@@ -470,9 +470,14 @@ mod tests {
other_object
.set_value
(
new_data
(
0
),
&
bv
(
0
))
.unwrap
();
let
merged_object
=
object
.merge
(
&
other_object
);
assert_eq!
(
merged_object
.get_value
(
Bitvector
::
from_i64
(
-
12
),
ByteSize
::
new
(
8
)),
Data
::
new_top
(
ByteSize
::
new
(
8
))
merged_object
.get_value
(
Bitvector
::
from_i64
(
-
12
),
ByteSize
::
new
(
8
))
.get_absolute_value
(),
Some
(
&
IntervalDomain
::
mock
(
4
,
23
)
.with_stride
(
19
)
.into
())
);
assert
!
(
merged_object
.get_value
(
Bitvector
::
from_i64
(
-
12
),
ByteSize
::
new
(
8
))
.contains_top
());
assert_eq!
(
merged_object
.get_value
(
Bitvector
::
from_i64
(
0
),
ByteSize
::
new
(
8
)),
new_data
(
0
)
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/object_list.rs
View file @
76936d8c
...
...
@@ -491,10 +491,10 @@ mod tests {
let
mut
merged
=
obj_list
.merge
(
&
other_obj_list
);
assert_eq!
(
merged
.get_value
(
&
pointer
,
ByteSize
::
new
(
8
)),
bv
(
42
)
.into
());
assert_eq!
(
merged
.get_value
(
&
second_pointer
,
ByteSize
::
new
(
8
)),
Data
::
new_top
(
ByteSize
::
new
(
8
))
);
assert
!
(
merged
.get_value
(
&
second_pointer
,
ByteSize
::
new
(
8
))
.contains_top
()
);
assert_eq!
(
merged
.get_value
(
&
heap_pointer
,
ByteSize
::
new
(
8
)),
bv
(
3
)
.into
()
...
...
src/cwe_checker_lib/src/analysis/pointer_inference/state/tests.rs
View file @
76936d8c
...
...
@@ -61,12 +61,10 @@ fn state() {
let
merged_state
=
state
.merge
(
&
other_state
);
assert_eq!
(
merged_state
.register
[
&
register
(
"RAX"
)],
bv
(
42
)
.into
());
assert_eq!
(
merged_state
.register
.get
(
&
register
(
"RBX"
)),
None
);
assert_eq!
(
merged_state
.load_value
(
&
Var
(
register
(
"RSP"
)),
ByteSize
::
new
(
8
),
&
global_memory
)
.unwrap
(),
Data
::
new_top
(
ByteSize
::
new
(
8
))
);
assert
!
(
merged_state
.load_value
(
&
Var
(
register
(
"RSP"
)),
ByteSize
::
new
(
8
),
&
global_memory
)
.unwrap
()
.contains_top
());
// Test pointer adjustment on reads
state
.memory
.add_abstract_object
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment