Skip to content

Commit 6275272

Browse files
committed
Make user input non-deterministic
Signed-off-by: František Nečas <[email protected]>
1 parent 4542064 commit 6275272

File tree

8 files changed

+153
-0
lines changed

8 files changed

+153
-0
lines changed

regression/overflows/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
default: tests.log
2+
3+
FLAGS = --verbosity 10
4+
5+
test:
6+
@../test.pl -p -c "../../../src/2ls/2ls $(FLAGS)"
7+
8+
tests.log: ../test.pl
9+
@../test.pl -p -c "../../../src/2ls/2ls $(FLAGS)"
10+
11+
show:
12+
@for dir in *; do \
13+
if [ -d "$$dir" ]; then \
14+
vim -o "$$dir/*.c" "$$dir/*.out"; \
15+
fi; \
16+
done;
17+
18+
clean:
19+
@rm -f *.log
20+
@for dir in *; do rm -f $$dir/*.out; done;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Inspired by SV-comp:
2+
// https://sv-comp.sosy-lab.org/2023/results/sv-benchmarks/c/Juliet_Test/CWE190_Integer_Overflow__int64_t_fscanf_add_01_bad.i
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <time.h>
7+
8+
void printLine(const char * line);
9+
void printLongLine(long longNumber);
10+
11+
void CWE190_Integer_Overflow__int64_t_fscanf_add_01_bad()
12+
{
13+
int64_t data;
14+
data = 0LL;
15+
fscanf (stdin, "%" "l" "d", &data);
16+
{
17+
int64_t result = data + 1;
18+
printLongLongLine(result);
19+
}
20+
}
21+
int main(int argc, char * argv[])
22+
{
23+
srand( (unsigned)time(((void *)0)) );
24+
printLine("Calling bad()...");
25+
CWE190_Integer_Overflow__int64_t_fscanf_add_01_bad();
26+
printLine("Finished bad()");
27+
return 0;
28+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--signed-overflow-check
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Inspired by SV-comp:
2+
// https://sv-comp.sosy-lab.org/2023/results/sv-benchmarks/c/Juliet_Test/CWE190_Integer_Overflow__int64_t_fscanf_add_01_good.i
3+
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <time.h>
7+
8+
void printLine(const char * line);
9+
void printLongLine(long longNumber);
10+
void printLongLongLine(int64_t longLongIntNumber);
11+
12+
static void goodG2B()
13+
{
14+
int64_t data;
15+
data = 0LL;
16+
data = 2;
17+
{
18+
int64_t result = data + 1;
19+
printLongLongLine(result);
20+
}
21+
}
22+
static void goodB2G()
23+
{
24+
int64_t data;
25+
data = 0LL;
26+
fscanf (stdin, "%" "l" "d", &data);
27+
if (data < 0x7fffffffffffffffLL)
28+
{
29+
int64_t result = data + 1;
30+
printLongLongLine(result);
31+
}
32+
else
33+
{
34+
printLine("data value is too large to perform arithmetic safely.");
35+
}
36+
}
37+
void CWE190_Integer_Overflow__int64_t_fscanf_add_01_good()
38+
{
39+
goodG2B();
40+
goodB2G();
41+
}
42+
int main(int argc, char * argv[])
43+
{
44+
srand( (unsigned)time(((void *)0)) );
45+
printLine("Calling good()...");
46+
CWE190_Integer_Overflow__int64_t_fscanf_add_01_good();
47+
printLine("Finished good()");
48+
return 0;
49+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--signed-overflow-check
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$

src/2ls/2ls_parse_options.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,8 @@ bool twols_parse_optionst::process_goto_program(
10481048
if(options.get_bool_option("competition-mode"))
10491049
assert_no_builtin_functions(goto_model);
10501050

1051+
make_scanf_nondet(goto_model);
1052+
10511053
#if REMOVE_MULTIPLE_DEREFERENCES
10521054
remove_multiple_dereferences(goto_model);
10531055
#endif

src/2ls/2ls_parse_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class twols_parse_optionst:
190190
void fix_goto_targets(goto_modelt &goto_model);
191191
void make_assertions_false(goto_modelt &goto_model);
192192
void make_symbolic_array_indices(goto_modelt &goto_model);
193+
void make_scanf_nondet(goto_modelt &goto_model);
193194
};
194195

195196
#endif

src/2ls/preprocessing_util.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,3 +849,44 @@ void twols_parse_optionst::make_symbolic_array_indices(goto_modelt &goto_model)
849849
}
850850
goto_model.goto_functions.update();
851851
}
852+
853+
/// Makes user input nondeterministic, i.e. arguments of fscanf starting
854+
/// from the second one are assigned a nondeterministic value.
855+
void twols_parse_optionst::make_scanf_nondet(goto_modelt &goto_model)
856+
{
857+
for(auto &f_it : goto_model.goto_functions.function_map)
858+
{
859+
Forall_goto_program_instructions(i_it, f_it.second.body)
860+
{
861+
if(!i_it->is_function_call())
862+
continue;
863+
auto name = to_symbol_expr(i_it->call_function()).get_identifier();
864+
// FIXME: this is a bit hacky and should probably be handled better in
865+
// coordination with CBMC.
866+
int start;
867+
if(name == "__isoc99_fscanf" || name == "fscanf")
868+
start = 2;
869+
else if(name == "__isoc99_scanf" || name == "scanf")
870+
start = 1;
871+
else
872+
continue;
873+
int i = 0;
874+
for(const auto &arg : i_it->call_arguments()) {
875+
if(i >= start)
876+
{
877+
if(arg.id() == ID_address_of)
878+
{
879+
auto lhs=dereference_exprt(arg);
880+
side_effect_expr_nondett rhs(
881+
to_address_of_expr(arg).object().type(),
882+
i_it->source_location());
883+
f_it.second.body.insert_after(
884+
i_it,
885+
goto_programt::make_assignment(lhs, rhs));
886+
}
887+
}
888+
i++;
889+
}
890+
}
891+
}
892+
}

0 commit comments

Comments
 (0)