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