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
b571c3eb
Unverified
Commit
b571c3eb
authored
Jul 01, 2021
by
Melvin Klimke
Committed by
GitHub
Jul 01, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Error Handling for Parameter Parsing (#193)
parent
2de59afc
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
50 deletions
+78
-50
parameter_detection.rs
...er_lib/src/checkers/cwe_78/context/parameter_detection.rs
+26
-15
arguments.rs
src/cwe_checker_lib/src/utils/arguments.rs
+47
-30
tests.rs
src/cwe_checker_lib/src/utils/arguments/tests.rs
+5
-5
No files found.
src/cwe_checker_lib/src/checkers/cwe_78/context/parameter_detection.rs
View file @
b571c3eb
...
...
@@ -74,30 +74,36 @@ impl<'a> Context<'a> {
.pointer_inference_results
.get_node_value
(
call_source_node
)
{
let
parameters
=
arguments
::
get_variable_number_parameters
(
if
let
Ok
(
parameters
)
=
arguments
::
get_variable_number_parameters
(
self
.project
,
pi_state
,
user_input_symbol
,
&
self
.symbol_maps.format_string_index
,
self
.runtime_memory_image
,
);
if
!
parameters
.is_empty
()
{
match
user_input_symbol
.name
.as_str
()
{
"scanf"
|
"__isoc99_scanf"
=>
{
self
.process_scanf
(
call_source_node
,
&
mut
new_state
,
pi_state
,
parameters
)
}
"sscanf"
|
"__isoc99_sscanf"
=>
{
let
source_string_register
=
user_input_symbol
.parameters
.get
(
0
)
.unwrap
();
self
.process_sscanf
(
)
{
if
!
parameters
.is_empty
()
{
match
user_input_symbol
.name
.as_str
()
{
"scanf"
|
"__isoc99_scanf"
=>
self
.process_scanf
(
call_source_node
,
&
mut
new_state
,
pi_state
,
parameters
,
source_string_register
,
)
),
"sscanf"
|
"__isoc99_sscanf"
=>
{
let
source_string_register
=
user_input_symbol
.parameters
.get
(
0
)
.unwrap
();
self
.process_sscanf
(
&
mut
new_state
,
pi_state
,
parameters
,
source_string_register
,
)
}
_
=>
panic!
(
"Invalid user input symbol."
),
}
_
=>
panic!
(
"Invalid user input symbol."
),
}
}
// TODO: Log errors that came up during the parameter parsing.
}
new_state
}
...
...
@@ -222,13 +228,18 @@ impl<'a> Context<'a> {
if
self
.is_relevant_string_function_call
(
string_symbol
,
pi_state
,
&
mut
new_state
)
{
let
mut
parameters
=
string_symbol
.parameters
.clone
();
if
string_symbol
.has_var_args
{
parameters
=
arguments
::
get_variable_number_parameters
(
if
let
Ok
(
args
)
=
arguments
::
get_variable_number_parameters
(
self
.project
,
pi_state
,
string_symbol
,
&
self
.symbol_maps.format_string_index
,
self
.runtime_memory_image
,
);
)
{
parameters
=
args
;
}
else
{
// TODO: Log errors that came up during the parameter parsing.
parameters
=
vec!
[]
}
}
self
.taint_function_parameters
(
&
mut
new_state
,
pi_state
,
parameters
);
}
...
...
src/cwe_checker_lib/src/utils/arguments.rs
View file @
b571c3eb
...
...
@@ -2,6 +2,8 @@
use
std
::
collections
::
HashMap
;
use
crate
::
prelude
::
*
;
use
regex
::
Regex
;
use
crate
::{
...
...
@@ -33,40 +35,46 @@ pub fn get_input_format_string(
format_string_index
:
usize
,
stack_pointer_register
:
&
Variable
,
runtime_memory_image
:
&
RuntimeMemoryImage
,
)
->
String
{
)
->
Result
<
String
,
Error
>
{
if
let
Some
(
format_string
)
=
extern_symbol
.parameters
.get
(
format_string_index
)
{
if
let
Ok
(
address
)
=
pi_state
.eval_parameter_arg
(
if
let
Ok
(
DataDomain
::
Value
(
address
)
)
=
pi_state
.eval_parameter_arg
(
format_string
,
&
stack_pointer_register
,
runtime_memory_image
,
)
{
parse_format_string_destination_and_return_content
(
address
,
runtime_memory_image
)
}
else
{
panic!
(
"Could not parse target address of format string pointer."
);
return
parse_format_string_destination_and_return_content
(
address
,
runtime_memory_image
,
);
}
}
else
{
panic!
(
"No format string parameter at specified index {} for function {}"
,
format_string_index
,
extern_symbol
.name
);
return
Err
(
anyhow!
(
"Format string not in global memory."
));
}
Err
(
anyhow!
(
"No format string parameter at specified index {} for function {}"
,
format_string_index
,
extern_symbol
.name
))
}
/// Parses the destiniation address of the format string.
/// It checks whether the address points to another pointer in memory.
/// If so, it will use the target address of that pointer read the format string from memory.
pub
fn
parse_format_string_destination_and_return_content
(
address
:
DataDomain
<
IntervalDomain
>
,
address
:
IntervalDomain
,
runtime_memory_image
:
&
RuntimeMemoryImage
,
)
->
String
{
)
->
Result
<
String
,
Error
>
{
if
let
Ok
(
address_vector
)
=
address
.try_to_bitvec
()
{
match
runtime_memory_image
.read_string_until_null_terminator
(
&
address_vector
)
{
Ok
(
format_string
)
=>
format_string
.to_string
(),
Err
(
e
)
=>
panic!
(
"{}"
,
e
),
}
}
else
{
panic!
(
"Could not translate format string address to bitvector."
);
return
match
runtime_memory_image
.read_string_until_null_terminator
(
&
address_vector
)
{
Ok
(
format_string
)
=>
Ok
(
format_string
.to_string
()),
Err
(
e
)
=>
Err
(
anyhow!
(
"{}"
,
e
)),
};
}
Err
(
anyhow!
(
"Could not translate format string address to bitvector."
))
}
/// Parses the format string parameters using a regex, determines their data types,
...
...
@@ -115,30 +123,39 @@ pub fn get_variable_number_parameters(
extern_symbol
:
&
ExternSymbol
,
format_string_index_map
:
&
HashMap
<
String
,
usize
>
,
runtime_memory_image
:
&
RuntimeMemoryImage
,
)
->
Vec
<
Arg
>
{
)
->
Result
<
Vec
<
Arg
>
,
Error
>
{
let
format_string_index
=
match
format_string_index_map
.get
(
&
extern_symbol
.name
)
{
Some
(
index
)
=>
*
index
,
None
=>
panic!
(
"External Symbol does not contain a format string parameter."
),
};
let
format_string
=
get_input_format_string
(
let
format_string_results
=
get_input_format_string
(
pi_state
,
extern_symbol
,
format_string_index
,
&
project
.stack_pointer_register
,
runtime_memory_image
,
);
let
parameters
=
parse_format_string_parameters
(
format_string
.as_str
(),
&
project
.datatype_properties
);
if
parameters
.iter
()
.any
(|(
specifier
,
_
)|
is_string
(
specifier
))
{
return
calculate_parameter_locations
(
project
,
parameters
,
extern_symbol
.get_calling_convention
(
project
),
format_string_index
,
);
if
let
Ok
(
format_string
)
=
format_string_results
{
let
parameters
=
parse_format_string_parameters
(
format_string
.as_str
(),
&
project
.datatype_properties
);
if
parameters
.iter
()
.any
(|(
specifier
,
_
)|
is_string
(
specifier
))
{
return
Ok
(
calculate_parameter_locations
(
project
,
parameters
,
extern_symbol
.get_calling_convention
(
project
),
format_string_index
,
));
}
return
Ok
(
vec!
[]);
}
vec!
[]
Err
(
anyhow!
(
"Could not parse variable parameters: {}"
,
format_string_results
.unwrap_err
()
))
}
/// Calculates the register and stack positions of format string parameters.
...
...
src/cwe_checker_lib/src/utils/arguments/tests.rs
View file @
b571c3eb
...
...
@@ -43,6 +43,7 @@ fn test_get_variable_number_parameters() {
&
format_string_index_map
,
&
mem_image
,
)
.unwrap
()
);
output
.push
(
Arg
::
Stack
{
...
...
@@ -65,6 +66,7 @@ fn test_get_variable_number_parameters() {
&
format_string_index_map
,
&
mem_image
,
)
.unwrap
()
);
}
...
...
@@ -89,6 +91,7 @@ fn test_get_input_format_string() {
&
Variable
::
mock
(
"RSP"
,
8
as
u64
),
&
mem_image
)
.unwrap
()
);
}
...
...
@@ -96,14 +99,11 @@ fn test_get_input_format_string() {
fn
test_parse_format_string_destination_and_return_content
()
{
let
mem_image
=
RuntimeMemoryImage
::
mock
();
let
string_address_vector
=
Bitvector
::
from_str_radix
(
16
,
"3002"
)
.unwrap
();
let
string_address
=
DataDomain
::
Value
(
IntervalDomain
::
new
(
string_address_vector
.clone
(),
string_address_vector
,
));
let
string_address
=
IntervalDomain
::
new
(
string_address_vector
.clone
(),
string_address_vector
);
assert_eq!
(
"Hello World"
,
parse_format_string_destination_and_return_content
(
string_address
,
&
mem_image
)
parse_format_string_destination_and_return_content
(
string_address
,
&
mem_image
)
.unwrap
()
);
}
...
...
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