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
0d2777b0
Unverified
Commit
0d2777b0
authored
Jul 30, 2020
by
Enkelmann
Committed by
GitHub
Jul 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Clippy and Rust fmt to CI-pipeline (#75)
parent
7e992eea
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
118 additions
and
200 deletions
+118
-200
.travis_run_tests.sh
.travis_run_tests.sh
+4
-1
Makefile
Makefile
+4
-0
Cargo.toml
cwe_checker_rs/Cargo.toml
+1
-0
graph.rs
cwe_checker_rs/src/analysis/graph.rs
+10
-15
interprocedural_fixpoint.rs
cwe_checker_rs/src/analysis/interprocedural_fixpoint.rs
+3
-3
mem_region.rs
cwe_checker_rs/src/analysis/mem_region.rs
+10
-12
context.rs
cwe_checker_rs/src/analysis/pointer_inference/context.rs
+11
-14
data.rs
cwe_checker_rs/src/analysis/pointer_inference/data.rs
+1
-1
identifier.rs
cwe_checker_rs/src/analysis/pointer_inference/identifier.rs
+6
-7
mod.rs
cwe_checker_rs/src/analysis/pointer_inference/mod.rs
+8
-13
object.rs
cwe_checker_rs/src/analysis/pointer_inference/object.rs
+5
-7
object_list.rs
cwe_checker_rs/src/analysis/pointer_inference/object_list.rs
+18
-21
state.rs
cwe_checker_rs/src/analysis/pointer_inference/state.rs
+13
-14
analysis.rs
cwe_checker_rs/src/ffi/analysis.rs
+4
-4
serde.rs
cwe_checker_rs/src/ffi/serde.rs
+19
-23
symbol.rs
cwe_checker_rs/src/term/symbol.rs
+1
-1
fast_cmp_arc.rs
cwe_checker_rs/src/utils/fast_cmp_arc.rs
+0
-63
mod.rs
cwe_checker_rs/src/utils/mod.rs
+0
-1
No files found.
.travis_run_tests.sh
View file @
0d2777b0
#!/bin/bash
#!/bin/bash
docker run
--rm
-t
cwe-checker cargo
test
&&
docker run
--rm
-t
cwe-checker dune runtest
&&
pytest
docker run
--rm
-t
cwe-checker make codestyle-check
\
&&
docker run
--rm
-t
cwe-checker cargo
test
\
&&
docker run
--rm
-t
cwe-checker dune runtest
\
&&
pytest
Makefile
View file @
0d2777b0
...
@@ -18,6 +18,10 @@ test:
...
@@ -18,6 +18,10 @@ test:
cd test
/artificial_samples
;
scons
;
cd
../..
cd test
/artificial_samples
;
scons
;
cd
../..
pytest
-v
--ignore
=
_build
pytest
-v
--ignore
=
_build
codestyle-check
:
cargo fmt
--
--check
cargo clippy
--
-D
clippy::all
clean
:
clean
:
cargo clean
cargo clean
rm
-f
src/libcwe_checker_rs.a
rm
-f
src/libcwe_checker_rs.a
...
...
cwe_checker_rs/Cargo.toml
View file @
0d2777b0
...
@@ -14,6 +14,7 @@ petgraph = { version = "0.5", features = ["default", "serde-1"] }
...
@@ -14,6 +14,7 @@ petgraph = { version = "0.5", features = ["default", "serde-1"] }
fnv
=
"1.0"
# a faster hash function for small keys like integers
fnv
=
"1.0"
# a faster hash function for small keys like integers
anyhow
=
"1.0"
# for easy error types
anyhow
=
"1.0"
# for easy error types
crossbeam-channel
=
"0.4"
crossbeam-channel
=
"0.4"
derive_more
=
"0.99"
[lib]
[lib]
name
=
"cwe_checker_rs"
name
=
"cwe_checker_rs"
...
...
cwe_checker_rs/src/analysis/graph.rs
View file @
0d2777b0
...
@@ -95,7 +95,7 @@ impl<'a> GraphBuilder<'a> {
...
@@ -95,7 +95,7 @@ impl<'a> GraphBuilder<'a> {
/// add all subs to the jump targets so that call instructions can be linked to the starting block of the corresponding sub.
/// add all subs to the jump targets so that call instructions can be linked to the starting block of the corresponding sub.
fn
add_subs_to_jump_targets
(
&
mut
self
)
{
fn
add_subs_to_jump_targets
(
&
mut
self
)
{
for
sub
in
self
.program.term.subs
.iter
()
{
for
sub
in
self
.program.term.subs
.iter
()
{
if
sub
.term.blocks
.len
()
>
0
{
if
!
sub
.term.blocks
.is_empty
()
{
let
start_block
=
&
sub
.term.blocks
[
0
];
let
start_block
=
&
sub
.term.blocks
[
0
];
let
target_index
=
self
.jump_targets
[
&
start_block
.tid
];
let
target_index
=
self
.jump_targets
[
&
start_block
.tid
];
self
.jump_targets
.insert
(
sub
.tid
.clone
(),
target_index
);
self
.jump_targets
.insert
(
sub
.tid
.clone
(),
target_index
);
...
@@ -140,7 +140,7 @@ impl<'a> GraphBuilder<'a> {
...
@@ -140,7 +140,7 @@ impl<'a> GraphBuilder<'a> {
self
.return_addresses
self
.return_addresses
.entry
(
target_tid
.clone
())
.entry
(
target_tid
.clone
())
.and_modify
(|
vec
|
vec
.push
((
source
,
return_index
)))
.and_modify
(|
vec
|
vec
.push
((
source
,
return_index
)))
.or_insert
(
vec!
[(
source
,
return_index
)]);
.or_insert
_with
(||
vec!
[(
source
,
return_index
)]);
}
}
// TODO: Non-returning calls and tail calls both have no return target in BAP.
// TODO: Non-returning calls and tail calls both have no return target in BAP.
// Thus we need to distinguish them somehow to correctly handle tail calls.
// Thus we need to distinguish them somehow to correctly handle tail calls.
...
@@ -189,8 +189,7 @@ impl<'a> GraphBuilder<'a> {
...
@@ -189,8 +189,7 @@ impl<'a> GraphBuilder<'a> {
.term
.term
.jmps
.jmps
.iter
()
.iter
()
.filter
(|
jump
|
matches!
(
jump
.term.kind
,
JmpKind
::
Call
(
_
)))
.find
(|
jump
|
matches!
(
jump
.term.kind
,
JmpKind
::
Call
(
_
)))
.next
()
.unwrap
();
.unwrap
();
let
cr_combine_node
=
self
.graph
.add_node
(
Node
::
CallReturn
(
call_block
));
let
cr_combine_node
=
self
.graph
.add_node
(
Node
::
CallReturn
(
call_block
));
self
.graph
self
.graph
...
@@ -210,8 +209,7 @@ impl<'a> GraphBuilder<'a> {
...
@@ -210,8 +209,7 @@ impl<'a> GraphBuilder<'a> {
.term
.term
.jmps
.jmps
.iter
()
.iter
()
.find
(|
jmp
|
matches!
(
jmp
.term.kind
,
JmpKind
::
Return
(
_
)))
.any
(|
jmp
|
matches!
(
jmp
.term.kind
,
JmpKind
::
Return
(
_
)))
.is_some
()
{
{
let
return_from_node
=
self
.jump_targets
[
&
block
.tid
]
.
1
;
let
return_from_node
=
self
.jump_targets
[
&
block
.tid
]
.
1
;
self
.add_call_return_node_and_edges
(
sub
,
return_from_node
);
self
.add_call_return_node_and_edges
(
sub
,
return_from_node
);
...
@@ -242,7 +240,7 @@ impl<'a> GraphBuilder<'a> {
...
@@ -242,7 +240,7 @@ impl<'a> GraphBuilder<'a> {
/// This function builds the interprocedural control flow graph for a program term.
/// This function builds the interprocedural control flow graph for a program term.
pub
fn
get_program_cfg
(
program
:
&
Term
<
Program
>
,
extern_subs
:
HashSet
<
Tid
>
)
->
Graph
{
pub
fn
get_program_cfg
(
program
:
&
Term
<
Program
>
,
extern_subs
:
HashSet
<
Tid
>
)
->
Graph
{
let
builder
=
GraphBuilder
::
new
(
program
,
extern_subs
);
let
builder
=
GraphBuilder
::
new
(
program
,
extern_subs
);
return
builder
.build
();
builder
.build
()
}
}
/// For a given set of block TIDs generate a map from the TIDs to the indices of the BlkStart and BlkEnd nodes
/// For a given set of block TIDs generate a map from the TIDs to the indices of the BlkStart and BlkEnd nodes
...
@@ -255,17 +253,14 @@ pub fn get_indices_of_block_nodes<'a, I: Iterator<Item = &'a Tid>>(
...
@@ -255,17 +253,14 @@ pub fn get_indices_of_block_nodes<'a, I: Iterator<Item = &'a Tid>>(
let
mut
tid_to_indices_map
=
HashMap
::
new
();
let
mut
tid_to_indices_map
=
HashMap
::
new
();
for
node_index
in
graph
.node_indices
()
{
for
node_index
in
graph
.node_indices
()
{
if
let
Some
(
tid
)
=
tids
.get
(
&
graph
[
node_index
]
.get_block
()
.tid
)
{
if
let
Some
(
tid
)
=
tids
.get
(
&
graph
[
node_index
]
.get_block
()
.tid
)
{
match
graph
[
node_index
]
{
if
let
Node
::
BlkStart
(
_block_term
)
=
graph
[
node_index
]
{
Node
::
BlkStart
(
_block_term
)
=>
{
let
start_index
=
node_index
;
let
start_index
=
node_index
;
let
end_index
=
graph
.neighbors
(
start_index
)
.next
()
.unwrap
();
let
end_index
=
graph
.neighbors
(
start_index
)
.next
()
.unwrap
();
tid_to_indices_map
.insert
(
tid
.clone
(),
(
start_index
,
end_index
));
tid_to_indices_map
.insert
(
tid
.clone
(),
(
start_index
,
end_index
));
}
_
=>
(),
}
}
}
}
}
}
return
tid_to_indices_map
;
tid_to_indices_map
}
}
#[cfg(test)]
#[cfg(test)]
...
...
cwe_checker_rs/src/analysis/interprocedural_fixpoint.rs
View file @
0d2777b0
...
@@ -172,11 +172,11 @@ impl<'a, T: Problem<'a>> GeneralFPProblem for GeneralizedProblem<'a, T> {
...
@@ -172,11 +172,11 @@ impl<'a, T: Problem<'a>> GeneralFPProblem for GeneralizedProblem<'a, T> {
Edge
::
ExternCallStub
(
call
)
=>
self
Edge
::
ExternCallStub
(
call
)
=>
self
.problem
.problem
.update_call_stub
(
node_value
.unwrap_value
(),
call
)
.update_call_stub
(
node_value
.unwrap_value
(),
call
)
.map
(
|
val
|
NodeValue
::
Value
(
val
)
),
.map
(
NodeValue
::
Value
),
Edge
::
Jump
(
jump
,
untaken_conditional
)
=>
self
Edge
::
Jump
(
jump
,
untaken_conditional
)
=>
self
.problem
.problem
.update_jump
(
node_value
.unwrap_value
(),
jump
,
*
untaken_conditional
)
.update_jump
(
node_value
.unwrap_value
(),
jump
,
*
untaken_conditional
)
.map
(
|
val
|
NodeValue
::
Value
(
val
)
),
.map
(
NodeValue
::
Value
),
}
}
}
}
}
}
...
@@ -192,7 +192,7 @@ impl<'a, T: Problem<'a>> Computation<'a, T> {
...
@@ -192,7 +192,7 @@ impl<'a, T: Problem<'a>> Computation<'a, T> {
let
generalized_problem
=
GeneralizedProblem
::
new
(
problem
);
let
generalized_problem
=
GeneralizedProblem
::
new
(
problem
);
let
computation
=
super
::
fixpoint
::
Computation
::
new
(
let
computation
=
super
::
fixpoint
::
Computation
::
new
(
generalized_problem
,
generalized_problem
,
default_value
.map
(
|
val
|
NodeValue
::
Value
(
val
)
),
default_value
.map
(
NodeValue
::
Value
),
);
);
Computation
{
Computation
{
generalized_computation
:
computation
,
generalized_computation
:
computation
,
...
...
cwe_checker_rs/src/analysis/mem_region.rs
View file @
0d2777b0
...
@@ -21,8 +21,10 @@ Implementation needs is_top() to be a member function of the ValueDomain trait.
...
@@ -21,8 +21,10 @@ Implementation needs is_top() to be a member function of the ValueDomain trait.
use
super
::
abstract_domain
::
*
;
use
super
::
abstract_domain
::
*
;
use
crate
::
bil
::{
BitSize
,
Bitvector
};
use
crate
::
bil
::{
BitSize
,
Bitvector
};
use
apint
::{
Int
,
Width
};
use
apint
::{
Int
,
Width
};
use
derive_more
::
Deref
;
use
serde
::{
Deserialize
,
Serialize
};
use
serde
::{
Deserialize
,
Serialize
};
use
std
::
collections
::
BTreeMap
;
use
std
::
collections
::
BTreeMap
;
use
std
::
ops
::
DerefMut
;
use
std
::
sync
::
Arc
;
use
std
::
sync
::
Arc
;
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
...
@@ -31,21 +33,17 @@ struct Element<T> {
...
@@ -31,21 +33,17 @@ struct Element<T> {
value
:
T
,
value
:
T
,
}
}
#[derive(Serialize,
Deserialize,
Debug,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
Hash,
Clone,
PartialEq,
Eq,
Deref)]
#[deref(forward)]
pub
struct
MemRegion
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
(
Arc
<
MemRegionData
<
T
>>
);
pub
struct
MemRegion
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
(
Arc
<
MemRegionData
<
T
>>
);
impl
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
PartialEq
for
MemRegion
<
T
>
{
impl
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
DerefMut
for
MemRegion
<
T
>
{
fn
eq
(
&
self
,
other
:
&
Self
)
->
bool
{
fn
deref_mut
(
&
mut
self
)
->
&
mut
MemRegionData
<
T
>
{
if
Arc
::
ptr_eq
(
&
self
.
0
,
&
other
.
0
)
{
Arc
::
make_mut
(
&
mut
self
.
0
)
true
}
else
{
self
.
0
==
other
.
0
}
}
}
}
}
impl
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
Eq
for
MemRegion
<
T
>
{}
// TODO: most of the functions in this impl block should be moved to MemRegionData (or removed, if they are only thin wrappers).
impl
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
MemRegion
<
T
>
{
impl
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
MemRegion
<
T
>
{
pub
fn
new
(
address_bitsize
:
BitSize
)
->
Self
{
pub
fn
new
(
address_bitsize
:
BitSize
)
->
Self
{
MemRegion
(
Arc
::
new
(
MemRegionData
::
new
(
address_bitsize
)))
MemRegion
(
Arc
::
new
(
MemRegionData
::
new
(
address_bitsize
)))
...
@@ -90,7 +88,7 @@ impl<T: AbstractDomain + ValueDomain + std::fmt::Debug> MemRegion<T> {
...
@@ -90,7 +88,7 @@ impl<T: AbstractDomain + ValueDomain + std::fmt::Debug> MemRegion<T> {
/// An abstract domain representing a continuous region of memory. See the module level description for more.
/// An abstract domain representing a continuous region of memory. See the module level description for more.
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone)]
struct
MemRegionData
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
{
pub
struct
MemRegionData
<
T
:
AbstractDomain
+
ValueDomain
+
std
::
fmt
::
Debug
>
{
address_bitsize
:
BitSize
,
address_bitsize
:
BitSize
,
values
:
BTreeMap
<
i64
,
T
>
,
values
:
BTreeMap
<
i64
,
T
>
,
}
}
...
@@ -162,7 +160,7 @@ impl<T: AbstractDomain + ValueDomain + std::fmt::Debug> MemRegionData<T> {
...
@@ -162,7 +160,7 @@ impl<T: AbstractDomain + ValueDomain + std::fmt::Debug> MemRegionData<T> {
}
}
}
}
let
bitsize
=
8
*
size
as
u16
;
let
bitsize
=
8
*
size
as
u16
;
return
T
::
new_top
(
bitsize
);
T
::
new_top
(
bitsize
)
}
}
/// Remove all elements intersecting the provided interval.
/// Remove all elements intersecting the provided interval.
...
...
cwe_checker_rs/src/analysis/pointer_inference/context.rs
View file @
0d2777b0
...
@@ -166,7 +166,6 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -166,7 +166,6 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
}
else
{
}
else
{
panic!
(
"Malformed control flow graph: Encountered call edge with a non-call jump term."
)
panic!
(
"Malformed control flow graph: Encountered call edge with a non-call jump term."
)
};
};
let
stack_offset_domain
=
self
.get_current_stack_offset
(
state
);
if
let
Label
::
Direct
(
ref
callee_tid
)
=
call
.target
{
if
let
Label
::
Direct
(
ref
callee_tid
)
=
call
.target
{
let
callee_stack_id
=
AbstractIdentifier
::
new
(
let
callee_stack_id
=
AbstractIdentifier
::
new
(
...
@@ -177,7 +176,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -177,7 +176,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
call_term
.tid
.clone
(),
call_term
.tid
.clone
(),
AbstractLocation
::
from_var
(
&
self
.project.stack_pointer_register
)
.unwrap
(),
AbstractLocation
::
from_var
(
&
self
.project.stack_pointer_register
)
.unwrap
(),
);
);
let
stack_offset_adjustment
=
s
tack_offset_domain
.clone
(
);
let
stack_offset_adjustment
=
s
elf
.get_current_stack_offset
(
state
);
let
address_bitsize
=
self
.project.stack_pointer_register
.bitsize
()
.unwrap
();
let
address_bitsize
=
self
.project.stack_pointer_register
.bitsize
()
.unwrap
();
let
mut
callee_state
=
state
.clone
();
let
mut
callee_state
=
state
.clone
();
...
@@ -214,9 +213,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -214,9 +213,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
);
);
// set the list of caller stack ids to only this caller id
// set the list of caller stack ids to only this caller id
callee_state
.caller_stack_ids
=
BTreeSet
::
new
();
callee_state
.caller_stack_ids
=
BTreeSet
::
new
();
callee_state
callee_state
.caller_stack_ids
.insert
(
new_caller_stack_id
);
.caller_stack_ids
.insert
(
new_caller_stack_id
.clone
());
// Remove non-referenced objects and objects, only the caller knows about, from the state.
// Remove non-referenced objects and objects, only the caller knows about, from the state.
callee_state
.ids_known_to_caller
=
BTreeSet
::
new
();
callee_state
.ids_known_to_caller
=
BTreeSet
::
new
();
callee_state
.remove_unreferenced_objects
();
callee_state
.remove_unreferenced_objects
();
...
@@ -224,7 +221,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -224,7 +221,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
callee_state
.ids_known_to_caller
=
callee_state
.memory
.get_all_object_ids
();
callee_state
.ids_known_to_caller
=
callee_state
.memory
.get_all_object_ids
();
callee_state
.ids_known_to_caller
.remove
(
&
callee_stack_id
);
callee_state
.ids_known_to_caller
.remove
(
&
callee_stack_id
);
return
callee_state
;
callee_state
}
else
{
}
else
{
panic!
(
"Indirect call edges not yet supported."
)
panic!
(
"Indirect call edges not yet supported."
)
// TODO: Support indirect call edges!
// TODO: Support indirect call edges!
...
@@ -277,7 +274,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -277,7 +274,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
state_after_return
.merge_callee_stack_to_caller_stack
(
state_after_return
.merge_callee_stack_to_caller_stack
(
callee_stack_id
,
callee_stack_id
,
original_caller_stack_id
,
original_caller_stack_id
,
&
(
-
stack_offset_on_call
.clone
()
),
&
(
-
stack_offset_on_call
),
);
);
state_after_return
.stack_id
=
original_caller_stack_id
.clone
();
state_after_return
.stack_id
=
original_caller_stack_id
.clone
();
state_after_return
.caller_stack_ids
=
state_before_call
.caller_stack_ids
.clone
();
state_after_return
.caller_stack_ids
=
state_before_call
.caller_stack_ids
.clone
();
...
@@ -382,11 +379,11 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -382,11 +379,11 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
new_state
.set_register
(
return_register
,
pointer
.into
()),
new_state
.set_register
(
return_register
,
pointer
.into
()),
Some
(
&
call
.tid
),
Some
(
&
call
.tid
),
);
);
return
Some
(
new_state
);
Some
(
new_state
)
}
else
{
}
else
{
// We cannot track the new object, since we do not know where to store the pointer to it.
// We cannot track the new object, since we do not know where to store the pointer to it.
// TODO: Return a diagnostics message to the user here.
// TODO: Return a diagnostics message to the user here.
return
Some
(
new_state
);
Some
(
new_state
)
}
}
}
}
"free"
=>
{
"free"
=>
{
...
@@ -412,16 +409,16 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -412,16 +409,16 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
}
}
}
// TODO: add diagnostics for else case
}
// TODO: add diagnostics for else case
new_state
.remove_unreferenced_objects
();
new_state
.remove_unreferenced_objects
();
return
Some
(
new_state
);
Some
(
new_state
)
}
else
{
}
else
{
// TODO: add diagnostics message for the user here
// TODO: add diagnostics message for the user here
return
Some
(
new_state
);
Some
(
new_state
)
}
}
}
}
Err
(
err
)
=>
{
Err
(
err
)
=>
{
// We do not know which memory object to free
// We do not know which memory object to free
self
.log_debug
(
Err
(
err
),
Some
(
&
call
.tid
));
self
.log_debug
(
Err
(
err
),
Some
(
&
call
.tid
));
return
Some
(
new_state
);
Some
(
new_state
)
}
}
}
}
}
}
...
@@ -431,7 +428,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -431,7 +428,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
Some
(
&
call
.tid
),
Some
(
&
call
.tid
),
);
);
let
mut
possible_referenced_ids
=
BTreeSet
::
new
();
let
mut
possible_referenced_ids
=
BTreeSet
::
new
();
if
extern_symbol
.arguments
.
len
()
==
0
{
if
extern_symbol
.arguments
.
is_empty
()
{
// TODO: We assume here that we do not know the parameters and approximate them by all parameter registers.
// TODO: We assume here that we do not know the parameters and approximate them by all parameter registers.
// This approximation is wrong if the function is known but has neither parameters nor return values.
// This approximation is wrong if the function is known but has neither parameters nor return values.
// We need to somehow distinguish these two cases.
// We need to somehow distinguish these two cases.
...
@@ -465,7 +462,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
...
@@ -465,7 +462,7 @@ impl<'a> crate::analysis::interprocedural_fixpoint::Problem<'a> for Context<'a>
.memory
.memory
.mark_mem_object_as_untracked
(
id
,
&
possible_referenced_ids
);
.mark_mem_object_as_untracked
(
id
,
&
possible_referenced_ids
);
}
}
return
Some
(
new_state
);
Some
(
new_state
)
}
}
}
}
}
else
{
}
else
{
...
...
cwe_checker_rs/src/analysis/pointer_inference/data.rs
View file @
0d2777b0
...
@@ -54,7 +54,7 @@ impl Data {
...
@@ -54,7 +54,7 @@ impl Data {
}
}
})
})
.collect
();
.collect
();
if
remaining_targets
.
len
()
==
0
{
if
remaining_targets
.
is_empty
()
{
*
self
=
Data
::
new_top
(
self
.bitsize
());
*
self
=
Data
::
new_top
(
self
.bitsize
());
}
else
{
}
else
{
*
self
=
Data
::
Pointer
(
PointerDomain
::
with_targets
(
remaining_targets
));
*
self
=
Data
::
Pointer
(
PointerDomain
::
with_targets
(
remaining_targets
));
...
...
cwe_checker_rs/src/analysis/pointer_inference/identifier.rs
View file @
0d2777b0
use
crate
::
bil
::
variable
::
*
;
use
crate
::
bil
::
variable
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
prelude
::
*
;
use
crate
::
utils
::
fast_cmp_arc
::
FastCmpArc
;
use
derive_more
::
Deref
;
use
std
::
sync
::
Arc
;
use
std
::
sync
::
Arc
;
// TODO: Right now abstract locations are used as giving the location where a pointer to an object is located.
// TODO: Right now abstract locations are used as giving the location where a pointer to an object is located.
...
@@ -14,8 +14,10 @@ use std::sync::Arc;
...
@@ -14,8 +14,10 @@ use std::sync::Arc;
/// The time identifier is given by a `Tid`.
/// The time identifier is given by a `Tid`.
/// If it is the Tid of a basic block, then it describes the point in time *before* execution of the first instruction in the block.
/// If it is the Tid of a basic block, then it describes the point in time *before* execution of the first instruction in the block.
/// If it is the Tid of a Def or Jmp, then it describes the point in time *after* the execution of the Def or Jmp.
/// If it is the Tid of a Def or Jmp, then it describes the point in time *after* the execution of the Def or Jmp.
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
PartialOrd,
Ord)]
pub
struct
AbstractIdentifier
(
FastCmpArc
<
AbstractIdentifierData
>
);
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
PartialOrd,
Ord,
Deref)]
#[deref(forward)]
pub
struct
AbstractIdentifier
(
Arc
<
AbstractIdentifierData
>
);
/// The data contained in an abstract identifier
/// The data contained in an abstract identifier
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
PartialOrd,
Ord)]
#[derive(Serialize,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Clone,
PartialOrd,
Ord)]
...
@@ -27,10 +29,7 @@ pub struct AbstractIdentifierData {
...
@@ -27,10 +29,7 @@ pub struct AbstractIdentifierData {
impl
AbstractIdentifier
{
impl
AbstractIdentifier
{
/// create a new abstract identifier
/// create a new abstract identifier
pub
fn
new
(
time
:
Tid
,
location
:
AbstractLocation
)
->
AbstractIdentifier
{
pub
fn
new
(
time
:
Tid
,
location
:
AbstractLocation
)
->
AbstractIdentifier
{
AbstractIdentifier
(
FastCmpArc
(
Arc
::
new
(
AbstractIdentifierData
{
AbstractIdentifier
(
Arc
::
new
(
AbstractIdentifierData
{
time
,
location
}))
time
,
location
,
})))
}
}
}
}
...
...
cwe_checker_rs/src/analysis/pointer_inference/mod.rs
View file @
0d2777b0
...
@@ -55,7 +55,7 @@ impl<'a> PointerInference<'a> {
...
@@ -55,7 +55,7 @@ impl<'a> PointerInference<'a> {
if
let
Some
((
start_node_index
,
_end_node_index
))
=
if
let
Some
((
start_node_index
,
_end_node_index
))
=
tid_to_graph_indices_map
.get
(
&
block_tid
)
tid_to_graph_indices_map
.get
(
&
block_tid
)
{
{
Some
((
sub_tid
.clone
(),
start_node_index
.clone
()
))
Some
((
sub_tid
.clone
(),
*
start_node_index
))
}
else
{
}
else
{
None
None
}
}
...
@@ -147,8 +147,7 @@ impl<'a> PointerInference<'a> {
...
@@ -147,8 +147,7 @@ impl<'a> PointerInference<'a> {
.term
.term
.extern_symbols
.extern_symbols
.iter
()
.iter
()
.find
(|
symbol
|
symbol
.tid
==
sub
.tid
)
.any
(|
symbol
|
symbol
.tid
==
sub
.tid
)
.is_some
()
{
{
continue
;
// We ignore functions marked as extern symbols.
continue
;
// We ignore functions marked as extern symbols.
}
}
...
@@ -160,19 +159,15 @@ impl<'a> PointerInference<'a> {
...
@@ -160,19 +159,15 @@ impl<'a> PointerInference<'a> {
let
mut
new_entry_points
=
Vec
::
new
();
let
mut
new_entry_points
=
Vec
::
new
();
for
(
node_id
,
node
)
in
graph
.node_references
()
{
for
(
node_id
,
node
)
in
graph
.node_references
()
{
if
let
Node
::
BlkStart
(
block
)
=
node
{
if
let
Node
::
BlkStart
(
block
)
=
node
{
if
start_block_to_sub_map
.get
(
&
block
.tid
)
.is_some
()
if
!
(
start_block_to_sub_map
.get
(
&
block
.tid
)
.is_none
()
&&
self
.computation
.get_node_value
(
node_id
)
.is_none
()
||
self
.computation
.get_node_value
(
node_id
)
.is_some
()
{
||
only_cfg_roots
if
only_cfg_roots
&&
graph
&&
graph
.neighbors_directed
(
node_id
,
Direction
::
Incoming
)
.neighbors_directed
(
node_id
,
Direction
::
Incoming
)
.next
()
.next
()
.is_none
()
.is_some
())
{
{
new_entry_points
.push
(
node_id
);
new_entry_points
.push
(
node_id
);
}
else
if
!
only_cfg_roots
{
new_entry_points
.push
(
node_id
);
}
}
}
}
}
}
}
...
...
cwe_checker_rs/src/analysis/pointer_inference/object.rs
View file @
0d2777b0
...
@@ -210,7 +210,7 @@ impl AbstractObjectInfo {
...
@@ -210,7 +210,7 @@ impl AbstractObjectInfo {
}
else
{
}
else
{
self
.memory
=
MemRegion
::
new
(
self
.memory
.get_address_bitsize
());
self
.memory
=
MemRegion
::
new
(
self
.memory
.get_address_bitsize
());
}
}
return
Ok
(());
Ok
(())
}
}
fn
get_all_possible_pointer_targets
(
&
self
)
->
BTreeSet
<
AbstractIdentifier
>
{
fn
get_all_possible_pointer_targets
(
&
self
)
->
BTreeSet
<
AbstractIdentifier
>
{
...
@@ -222,7 +222,7 @@ impl AbstractObjectInfo {
...
@@ -222,7 +222,7 @@ impl AbstractObjectInfo {
}
}
};
};
}
}
return
targets
;
targets
}
}
/// For pointer values replace an abstract identifier with another one and add the offset_adjustment to the pointer offsets.
/// For pointer values replace an abstract identifier with another one and add the offset_adjustment to the pointer offsets.
...
@@ -245,11 +245,9 @@ impl AbstractObjectInfo {
...
@@ -245,11 +245,9 @@ impl AbstractObjectInfo {
pub
fn
set_state
(
&
mut
self
,
new_state
:
Option
<
ObjectState
>
)
{
pub
fn
set_state
(
&
mut
self
,
new_state
:
Option
<
ObjectState
>
)
{
if
self
.is_unique
{
if
self
.is_unique
{
self
.state
=
new_state
;
self
.state
=
new_state
;
}
else
{
}
else
if
self
.state
!=
new_state
{
if
self
.state
!=
new_state
{
self
.state
=
None
;
self
.state
=
None
;
}
// else don't change the state
}
// else don't change the state
}
}
}
/// Remove the provided IDs from the target lists of all pointers in the memory object.
/// Remove the provided IDs from the target lists of all pointers in the memory object.
...
...
cwe_checker_rs/src/analysis/pointer_inference/object_list.rs
View file @
0d2777b0
...
@@ -55,7 +55,7 @@ impl AbstractObjectList {
...
@@ -55,7 +55,7 @@ impl AbstractObjectList {
}
}
}
}
}
}
return
false
;
false
}
}
/// Get the value at a given address.
/// Get the value at a given address.
...
@@ -87,7 +87,7 @@ impl AbstractObjectList {
...
@@ -87,7 +87,7 @@ impl AbstractObjectList {
break
;
break
;
}
}
}
}
merged_value
.ok_or
(
anyhow!
(
"Pointer without targets encountered."
))
merged_value
.ok_or
_else
(||
anyhow!
(
"Pointer without targets encountered."
))
}
}
}
}
}
}
...
@@ -102,7 +102,7 @@ impl AbstractObjectList {
...
@@ -102,7 +102,7 @@ impl AbstractObjectList {
for
(
id
,
_offset
)
in
pointer
.iter_targets
()
{
for
(
id
,
_offset
)
in
pointer
.iter_targets
()
{
target_object_set
.insert
(
self
.ids
.get
(
id
)
.unwrap
()
.
0
);
target_object_set
.insert
(
self
.ids
.get
(
id
)
.unwrap
()
.
0
);
}
}
if
target_object_set
.
len
()
==
0
{
if
target_object_set
.
is_empty
()
{
return
Err
(
anyhow!
(
"Pointer without targets encountered"
));
return
Err
(
anyhow!
(
"Pointer without targets encountered"
));
}
}
if
target_object_set
.len
()
==
1
{
if
target_object_set
.len
()
==
1
{
...
@@ -170,7 +170,7 @@ impl AbstractObjectList {
...
@@ -170,7 +170,7 @@ impl AbstractObjectList {
let
mut
merged_objects
=
self
.objects
.clone
();
let
mut
merged_objects
=
self
.objects
.clone
();
let
mut
merged_ids
=
self
.ids
.clone
();
let
mut
merged_ids
=
self
.ids
.clone
();
for
(
other_id
,
(
other_index
,
other_offset
))
in
other
.ids
.iter
()
{
for
(
other_id
,
(
other_index
,
other_offset
))
in
other
.ids
.iter
()
{
if
let
Some
((
index
,
offset
))
=
merged_ids
.get
(
&
other_id
)
.clone
()
{
if
let
Some
((
index
,
offset
))
=
merged_ids
.get
(
&
other_id
)
{
let
(
index
,
offset
)
=
(
*
index
,
offset
.clone
());
let
(
index
,
offset
)
=
(
*
index
,
offset
.clone
());
merged_ids
.insert
(
other_id
.clone
(),
(
index
,
offset
.merge
(
&
other_offset
)));
merged_ids
.insert
(
other_id
.clone
(),
(
index
,
offset
.merge
(
&
other_offset
)));
if
index
<
self
.objects
.len
()
{
if
index
<
self
.objects
.len
()
{
...
@@ -322,24 +322,22 @@ impl AbstractObjectList {
...
@@ -322,24 +322,22 @@ impl AbstractObjectList {
}
}
Arc
::
make_mut
(
object
)
.set_state
(
None
);
Arc
::
make_mut
(
object
)
.set_state
(
None
);
}
}
}
else
{
}
else
if
let
Some
(
id
)
=
ids
.iter
()
.next
()
{
if
let
Some
(
id
)
=
ids
.iter
()
.next
()
{
let
object
=
&
mut
self
.objects
[
self
.ids
[
&
id
]
.
0
];
let
object
=
&
mut
self
.objects
[
self
.ids
[
&
id
]
.
0
];
if
let
AbstractObject
::
Memory
(
tracked_mem
)
=
Arc
::
deref
(
object
)
{
if
let
AbstractObject
::
Memory
(
tracked_mem
)
=
Arc
::
deref
(
object
)
{
if
tracked_mem
.state
!=
Some
(
ObjectState
::
Alive
)
{
if
tracked_mem
.state
!=
Some
(
ObjectState
::
Alive
)
{
// Possible double free detected
// Possible double free detected
// TODO: Check rate of false positives.
// TODO: Check rate of false positives.
// If too high, only mark those with explicit dangling state.
// If too high, only mark those with explicit dangling state.
possible_double_free_ids
.push
(
id
.clone
());
possible_double_free_ids
.push
(
id
.clone
());
}
}
}
Arc
::
make_mut
(
object
)
.set_state
(
Some
(
ObjectState
::
Dangling
));
}
}
Arc
::
make_mut
(
object
)
.set_state
(
Some
(
ObjectState
::
Dangling
));
}
}
if
possible_double_free_ids
.is_empty
()
{
if
possible_double_free_ids
.is_empty
()
{
return
Ok
(());
Ok
(())
}
else
{
}
else
{
return
Err
(
possible_double_free_ids
);
Err
(
possible_double_free_ids
)
}
}
}
}
...
@@ -380,11 +378,10 @@ impl AbstractObjectList {
...
@@ -380,11 +378,10 @@ impl AbstractObjectList {
}
}
}
}
let
mut
old_to_new_index_map
:
BTreeMap
<
usize
,
usize
>
=
BTreeMap
::
new
();
let
mut
old_to_new_index_map
:
BTreeMap
<
usize
,
usize
>
=
BTreeMap
::
new
();
for
old_index
in
0
..
other_object_list
.objects
.len
()
{
for
(
old_index
,
old_object
)
in
other_object_list
.objects
.iter
()
.enumerate
()
{
if
objects_already_known
[
old_index
]
==
false
{
if
!
objects_already_known
[
old_index
]
{
old_to_new_index_map
.insert
(
old_index
,
self
.objects
.len
());
old_to_new_index_map
.insert
(
old_index
,
self
.objects
.len
());
self
.objects
self
.objects
.push
(
old_object
.clone
());
.push
(
other_object_list
.objects
[
old_index
]
.clone
());
}
}
}
}
for
(
id
,
(
old_index
,
offset
))
in
other_object_list
.ids
.iter
()
{
for
(
id
,
(
old_index
,
offset
))
in
other_object_list
.ids
.iter
()
{
...
...
cwe_checker_rs/src/analysis/pointer_inference/state.rs
View file @
0d2777b0
...
@@ -98,7 +98,7 @@ impl State {
...
@@ -98,7 +98,7 @@ impl State {
}
}
Ok
(())
Ok
(())
}
else
{
}
else
{
return
Err
(
anyhow!
(
"Variable is not a register type"
));
Err
(
anyhow!
(
"Variable is not a register type"
))
}
}
}
}
...
@@ -138,8 +138,7 @@ impl State {
...
@@ -138,8 +138,7 @@ impl State {
.filter_map
(|(
register
,
value
)|
{
.filter_map
(|(
register
,
value
)|
{
if
callee_saved_register_names
if
callee_saved_register_names
.iter
()
.iter
()
.find
(|
reg_name
|
**
reg_name
==
register
.name
)
.any
(|
reg_name
|
**
reg_name
==
register
.name
)
.is_some
()
{
{
Some
((
register
.clone
(),
value
.clone
()))
Some
((
register
.clone
(),
value
.clone
()))
}
else
{
}
else
{
...
@@ -284,11 +283,11 @@ impl State {
...
@@ -284,11 +283,11 @@ impl State {
// A more precise solution would write to every caller memory region separately,
// A more precise solution would write to every caller memory region separately,
// but would also need to check first whether the target memory region is unique or not.
// but would also need to check first whether the target memory region is unique or not.
self
.memory
.set_value
(
pointer
,
value
.clone
())
?
;
self
.memory
.set_value
(
pointer
,
value
.clone
())
?
;
return
Ok
(());
Ok
(())
}
else
{
}
else
{
// TODO: Implement recognition of stores to global memory.
// TODO: Implement recognition of stores to global memory.
// Needs implementation of reads from global data first.
// Needs implementation of reads from global data first.
return
Err
(
anyhow!
(
"Memory write to non-pointer data"
));
Err
(
anyhow!
(
"Memory write to non-pointer data"
))
}
}
}
}
...
@@ -313,10 +312,10 @@ impl State {
...
@@ -313,10 +312,10 @@ impl State {
size
,
size
,
}
=
store_exp
}
=
store_exp
{
{
let
data
=
self
.eval
(
value
)
.unwrap_or
(
Data
::
new_top
(
*
size
));
let
data
=
self
.eval
(
value
)
.unwrap_or
_else
(|
_
|
Data
::
new_top
(
*
size
));
assert_eq!
(
data
.bitsize
(),
*
size
);
assert_eq!
(
data
.bitsize
(),
*
size
);
// TODO: At the moment, both memory and endianness are ignored. Change that!
// TODO: At the moment, both memory and endianness are ignored. Change that!
return
self
.write_to_address
(
address
,
&
data
);
self
.write_to_address
(
address
,
&
data
)
}
else
{
}
else
{
panic!
(
"Expected store expression"
)
panic!
(
"Expected store expression"
)
}
}
...
@@ -343,7 +342,7 @@ impl State {
...
@@ -343,7 +342,7 @@ impl State {
}
}
}
}
// We only return the last error encountered.
// We only return the last error encountered.
re
turn
result_log
;
re
sult_log
}
}
/// merge two states
/// merge two states
...
@@ -353,7 +352,7 @@ impl State {
...
@@ -353,7 +352,7 @@ impl State {
for
(
register
,
other_value
)
in
other
.register
.iter
()
{
for
(
register
,
other_value
)
in
other
.register
.iter
()
{
if
let
Some
(
value
)
=
self
.register
.get
(
register
)
{
if
let
Some
(
value
)
=
self
.register
.get
(
register
)
{
let
merged_value
=
value
.merge
(
other_value
);
let
merged_value
=
value
.merge
(
other_value
);
if
merged_value
.is_top
()
==
false
{
if
!
merged_value
.is_top
()
{
// We only have to keep non-top elements.
// We only have to keep non-top elements.
merged_register
.insert
(
register
.clone
(),
merged_value
);
merged_register
.insert
(
register
.clone
(),
merged_value
);
}
}
...
@@ -393,7 +392,7 @@ impl State {
...
@@ -393,7 +392,7 @@ impl State {
match
offset
{
match
offset
{
BitvectorDomain
::
Value
(
offset_val
)
=>
{
BitvectorDomain
::
Value
(
offset_val
)
=>
{
if
offset_val
.try_to_i64
()
.unwrap
()
>=
0
if
offset_val
.try_to_i64
()
.unwrap
()
>=
0
&&
self
.caller_stack_ids
.len
()
>
0
&&
!
self
.caller_stack_ids
.is_empty
()
{
{
for
caller_id
in
self
.caller_stack_ids
.iter
()
{
for
caller_id
in
self
.caller_stack_ids
.iter
()
{
new_targets
.add_target
(
caller_id
.clone
(),
offset
.clone
());
new_targets
.add_target
(
caller_id
.clone
(),
offset
.clone
());
...
@@ -415,9 +414,9 @@ impl State {
...
@@ -415,9 +414,9 @@ impl State {
new_targets
.add_target
(
id
.clone
(),
offset
.clone
());
new_targets
.add_target
(
id
.clone
(),
offset
.clone
());
}
}
}
}
return
Data
::
Pointer
(
new_targets
);
Data
::
Pointer
(
new_targets
)
}
else
{
}
else
{
return
address
.clone
();
address
.clone
()
}
}
}
}
...
@@ -486,7 +485,7 @@ impl State {
...
@@ -486,7 +485,7 @@ impl State {
}
}
}
}
}
}
return
ids
;
ids
}
}
/// Merge the callee stack with the caller stack.
/// Merge the callee stack with the caller stack.
...
@@ -531,7 +530,7 @@ impl State {
...
@@ -531,7 +530,7 @@ impl State {
.register
.register
.clone
()
.clone
()
.into_iter
()
.into_iter
()
.filter
(|(
register
,
_value
)|
register
.is_temp
==
false
)
.filter
(|(
register
,
_value
)|
!
register
.is_temp
)
.collect
();
.collect
();
}
}
...
...
cwe_checker_rs/src/ffi/analysis.rs
View file @
0d2777b0
...
@@ -15,12 +15,12 @@ fn run_pointer_inference(program_jsonbuilder_val: ocaml::Value) -> (Vec<CweWarni
...
@@ -15,12 +15,12 @@ fn run_pointer_inference(program_jsonbuilder_val: ocaml::Value) -> (Vec<CweWarni
}
}
caml!
(
rs_run_pointer_inference
(
program_jsonbuilder_val
)
{
caml!
(
rs_run_pointer_inference
(
program_jsonbuilder_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
let
cwe_warnings_and_log
=
run_pointer_inference
(
program_jsonbuilder_val
);
let
cwe_warnings_and_log
=
run_pointer_inference
(
program_jsonbuilder_val
);
let
cwe_warnings_and_log_json
=
serde_json
::
to_string
(
&
cwe_warnings_and_log
)
.unwrap
();
let
cwe_warnings_and_log_json
=
serde_json
::
to_string
(
&
cwe_warnings_and_log
)
.unwrap
();
let
ocaml_string
=
ocaml
::
Str
::
from
(
&
cwe_warnings_and_log_json
as
&
str
);
let
ocaml_string
=
ocaml
::
Str
::
from
(
&
cwe_warnings_and_log_json
as
&
str
);
ocaml
::
Value
::
from
(
ocaml_string
)
ocaml
::
Value
::
from
(
ocaml_string
)
})
;
})
});
});
fn
run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
:
ocaml
::
Value
)
{
fn
run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
:
ocaml
::
Value
)
{
...
@@ -33,8 +33,8 @@ fn run_pointer_inference_and_print_debug(program_jsonbuilder_val: ocaml::Value)
...
@@ -33,8 +33,8 @@ fn run_pointer_inference_and_print_debug(program_jsonbuilder_val: ocaml::Value)
}
}
caml!
(
rs_run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
)
{
caml!
(
rs_run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
);
run_pointer_inference_and_print_debug
(
program_jsonbuilder_val
);
ocaml
::
Value
::
unit
()
ocaml
::
Value
::
unit
()
})
;
})
});
});
cwe_checker_rs/src/ffi/serde.rs
View file @
0d2777b0
...
@@ -73,10 +73,10 @@ impl From<&JsonBuilder> for serde_json::Value {
...
@@ -73,10 +73,10 @@ impl From<&JsonBuilder> for serde_json::Value {
}
}
caml!
(
rs_finalize_json_builder
(
builder_val
)
{
caml!
(
rs_finalize_json_builder
(
builder_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
JsonBuilder
::
ocaml_finalize
(
builder_val
);
JsonBuilder
::
ocaml_finalize
(
builder_val
);
ocaml
::
Value
::
unit
()
ocaml
::
Value
::
unit
()
})
;
})
});
});
/// Build JsonBuilder::Null as Ocaml value
/// Build JsonBuilder::Null as Ocaml value
...
@@ -85,9 +85,9 @@ fn build_serde_null() -> ocaml::Value {
...
@@ -85,9 +85,9 @@ fn build_serde_null() -> ocaml::Value {
}
}
caml!
(
rs_build_serde_null
(
_unit
)
{
caml!
(
rs_build_serde_null
(
_unit
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_null
()
build_serde_null
()
})
;
})
});
});
/// Build JsonBuilder::Bool as Ocaml value
/// Build JsonBuilder::Bool as Ocaml value
...
@@ -97,9 +97,9 @@ fn build_serde_bool(bool_val: ocaml::Value) -> ocaml::Value {
...
@@ -97,9 +97,9 @@ fn build_serde_bool(bool_val: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_build_serde_bool
(
bool_val
)
{
caml!
(
rs_build_serde_bool
(
bool_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_bool
(
bool_val
)
build_serde_bool
(
bool_val
)
})
;
})
});
});
/// Build JsonBuilder::Number as Ocaml value
/// Build JsonBuilder::Number as Ocaml value
...
@@ -109,9 +109,9 @@ fn build_serde_number(num: ocaml::Value) -> ocaml::Value {
...
@@ -109,9 +109,9 @@ fn build_serde_number(num: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_build_serde_number
(
number
)
{
caml!
(
rs_build_serde_number
(
number
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_number
(
number
)
build_serde_number
(
number
)
})
;
})
});
});
/// Build JsonBuilder::Object representing a bitvector from a string generated by `Bitvector.to_string` in Ocaml
/// Build JsonBuilder::Object representing a bitvector from a string generated by `Bitvector.to_string` in Ocaml
...
@@ -127,7 +127,7 @@ fn build_serde_bitvector(bitvector_string_val: ocaml::Value) -> ocaml::Value {
...
@@ -127,7 +127,7 @@ fn build_serde_bitvector(bitvector_string_val: ocaml::Value) -> ocaml::Value {
if
number_slice
.starts_with
(
"0x"
)
{
if
number_slice
.starts_with
(
"0x"
)
{
number_slice
=
&
number_slice
[
2
..
];
number_slice
=
&
number_slice
[
2
..
];
}
}
while
number_slice
.len
()
>
0
{
while
!
number_slice
.is_empty
()
{
if
number_slice
.len
()
>
16
{
if
number_slice
.len
()
>
16
{
let
digit
=
u64
::
from_str_radix
(
&
number_slice
[(
number_slice
.len
()
-
16
)
..
],
16
)
let
digit
=
u64
::
from_str_radix
(
&
number_slice
[(
number_slice
.len
()
-
16
)
..
],
16
)
.expect
(
"Bitvector value parsing failed"
);
.expect
(
"Bitvector value parsing failed"
);
...
@@ -151,18 +151,14 @@ fn build_serde_bitvector(bitvector_string_val: ocaml::Value) -> ocaml::Value {
...
@@ -151,18 +151,14 @@ fn build_serde_bitvector(bitvector_string_val: ocaml::Value) -> ocaml::Value {
(
"digits"
.to_string
(),
Rc
::
new
(
JsonBuilder
::
Array
(
num_list
))),
(
"digits"
.to_string
(),
Rc
::
new
(
JsonBuilder
::
Array
(
num_list
))),
(
"width"
.to_string
(),
Rc
::
new
(
JsonBuilder
::
Array
(
width_list
))),
(
"width"
.to_string
(),
Rc
::
new
(
JsonBuilder
::
Array
(
width_list
))),
]);
]);
// TODO: remove deserialization check
let
check_serde
=
serde_json
::
to_string
(
&
serde_json
::
Value
::
from
(
&
result
))
.unwrap
();
let
_bitv
:
apint
::
ApInt
=
serde_json
::
from_str
(
&
check_serde
)
.expect
(
&
format!
(
"Invalid value generated: {}"
,
check_serde
));
result
.to_ocaml
()
result
.to_ocaml
()
}
}
caml!
(
rs_build_serde_bitvector
(
bitvector_string
)
{
caml!
(
rs_build_serde_bitvector
(
bitvector_string
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_bitvector
(
bitvector_string
)
build_serde_bitvector
(
bitvector_string
)
})
;
})
});
});
/// Build JsonBuilder::String as Ocaml value
/// Build JsonBuilder::String as Ocaml value
...
@@ -172,9 +168,9 @@ fn build_serde_string(string_val: ocaml::Value) -> ocaml::Value {
...
@@ -172,9 +168,9 @@ fn build_serde_string(string_val: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_build_serde_string
(
string_val
)
{
caml!
(
rs_build_serde_string
(
string_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_string
(
string_val
)
build_serde_string
(
string_val
)
})
;
})
});
});
/// Build JsonBuilder::Array as Ocaml value from an Ocaml list
/// Build JsonBuilder::Array as Ocaml value from an Ocaml list
...
@@ -189,9 +185,9 @@ fn build_serde_array_from_list(list_val: ocaml::Value) -> ocaml::Value {
...
@@ -189,9 +185,9 @@ fn build_serde_array_from_list(list_val: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_build_serde_array_from_list
(
list_val
)
{
caml!
(
rs_build_serde_array_from_list
(
list_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_array_from_list
(
list_val
)
build_serde_array_from_list
(
list_val
)
})
;
})
});
});
/// Build JsonBuilder::Object as Ocaml value from an Ocaml list of tuples
/// Build JsonBuilder::Object as Ocaml value from an Ocaml list of tuples
...
@@ -217,9 +213,9 @@ fn build_serde_object(tuple_list_val: ocaml::Value) -> ocaml::Value {
...
@@ -217,9 +213,9 @@ fn build_serde_object(tuple_list_val: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_build_serde_object
(
tuple_list_val
)
{
caml!
(
rs_build_serde_object
(
tuple_list_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
build_serde_object
(
tuple_list_val
)
build_serde_object
(
tuple_list_val
)
})
;
})
});
});
/// Get the Json string corresponding to a JsonBuilder object and return it as an Ocaml value.
/// Get the Json string corresponding to a JsonBuilder object and return it as an Ocaml value.
...
@@ -230,7 +226,7 @@ fn get_json_string(builder_val: ocaml::Value) -> ocaml::Value {
...
@@ -230,7 +226,7 @@ fn get_json_string(builder_val: ocaml::Value) -> ocaml::Value {
}
}
caml!
(
rs_convert_json_to_string
(
builder_val
)
{
caml!
(
rs_convert_json_to_string
(
builder_val
)
{
return
failwith_on_panic
(
||
{
failwith_on_panic
(
||
{
get_json_string
(
builder_val
)
get_json_string
(
builder_val
)
})
;
})
});
});
cwe_checker_rs/src/term/symbol.rs
View file @
0d2777b0
...
@@ -29,7 +29,7 @@ impl ExternSymbol {
...
@@ -29,7 +29,7 @@ impl ExternSymbol {
}
}
match
&
return_args
[
0
]
.location
{
match
&
return_args
[
0
]
.location
{
Expression
::
Var
(
var
)
=>
Ok
(
var
),
Expression
::
Var
(
var
)
=>
Ok
(
var
),
_
=>
Err
(
anyhow!
(
"Return location is not a register"
))
?
,
_
=>
Err
(
anyhow!
(
"Return location is not a register"
)),
}
}
}
}
...
...
cwe_checker_rs/src/utils/fast_cmp_arc.rs
deleted
100644 → 0
View file @
7e992eea
use
crate
::
analysis
::
abstract_domain
::
AbstractDomain
;
use
crate
::
prelude
::
*
;
use
std
::
ops
::{
Deref
,
DerefMut
};
use
std
::
sync
::
Arc
;
// TODO: This is a helper not only for abstract domains! It needs its own source file!
#[derive(Serialize,
Deserialize,
Debug,
Hash,
Clone)]
pub
struct
FastCmpArc
<
T
>
(
pub
Arc
<
T
>
);
impl
<
T
:
PartialEq
+
Eq
>
PartialEq
for
FastCmpArc
<
T
>
{
fn
eq
(
&
self
,
other
:
&
Self
)
->
bool
{
if
Arc
::
ptr_eq
(
&
self
.
0
,
&
other
.
0
)
{
true
}
else
{
self
.
0
.eq
(
&
other
.
0
)
}
}
}
impl
<
T
:
Eq
>
Eq
for
FastCmpArc
<
T
>
{}
impl
<
T
:
AbstractDomain
+
Clone
>
AbstractDomain
for
FastCmpArc
<
T
>
{
fn
top
(
&
self
)
->
Self
{
FastCmpArc
(
Arc
::
new
(
self
.
0
.top
()))
}
fn
merge
(
&
self
,
other
:
&
Self
)
->
Self
{
if
Arc
::
ptr_eq
(
&
self
.
0
,
&
other
.
0
)
{
self
.clone
()
}
else
{
FastCmpArc
(
Arc
::
new
(
self
.
0
.merge
(
&
other
.
0
)))
}
}
}
impl
<
T
:
PartialOrd
+
Ord
>
PartialOrd
for
FastCmpArc
<
T
>
{
fn
partial_cmp
(
&
self
,
other
:
&
Self
)
->
Option
<
std
::
cmp
::
Ordering
>
{
Some
(
self
.cmp
(
other
))
}
}
impl
<
T
:
PartialOrd
+
Ord
>
Ord
for
FastCmpArc
<
T
>
{
fn
cmp
(
&
self
,
other
:
&
Self
)
->
std
::
cmp
::
Ordering
{
if
Arc
::
ptr_eq
(
&
self
.
0
,
&
other
.
0
)
{
std
::
cmp
::
Ordering
::
Equal
}
else
{
self
.
0
.cmp
(
&
other
.
0
)
}
}
}
impl
<
T
>
Deref
for
FastCmpArc
<
T
>
{
type
Target
=
T
;
fn
deref
(
&
self
)
->
&
T
{
&
self
.
0
}
}
impl
<
T
:
Clone
>
DerefMut
for
FastCmpArc
<
T
>
{
fn
deref_mut
(
&
mut
self
)
->
&
mut
T
{
Arc
::
make_mut
(
&
mut
self
.
0
)
}
}
cwe_checker_rs/src/utils/mod.rs
View file @
0d2777b0
pub
mod
fast_cmp_arc
;
pub
mod
log
;
pub
mod
log
;
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