Skip to content

Commit fe2c5f0

Browse files
committed
Perform pointer validity checks when doing pointer arithmetic
Arithmetic over pointers requires that they point to valid objects (or one past the end of an object). The test uncovered two further problems: 1) there was a typo in subtraction handling in bv_pointerst; 2) redundant assertions are removed, even when they refer to different expressions. Fixes: diffblue#5426
1 parent 751c986 commit fe2c5f0

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdlib.h>
2+
3+
int main()
4+
{
5+
int *p = malloc(sizeof(int) * 5);
6+
int *p2 = p + 10; // undefined behavior for indexing out of bounds
7+
int *p3 = p - 10; // undefined behavior for indexing out of bounds
8+
9+
int arr[5];
10+
int *p4 = arr + 10; // undefined behavior for indexing out of bounds
11+
int *p5 = arr - 10; // undefined behavior for indexing out of bounds
12+
return 0;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
CORE
2+
main.c
3+
--pointer-overflow-check --no-simplify
4+
^\[main.pointer_arithmetic.\d+\] line 7 pointer arithmetic: pointer outside dynamic object bounds in p + \(signed (long (long )?)?int\)10: FAILURE
5+
^\[main.pointer_arithmetic.\d+\] line 8 pointer arithmetic: pointer outside dynamic object bounds in p - \(signed (long (long )?)?int\)10: FAILURE
6+
^\[main.pointer_arithmetic.\d+\] line 11 pointer arithmetic: pointer outside object bounds in arr + \(signed (long (long )?)?int\)10: FAILURE
7+
^\[main.pointer_arithmetic.\d+\] line 12 pointer arithmetic: pointer outside object bounds in arr - \(signed (long (long )?)?int\)10: FAILURE
8+
^\*\* 4 of \d+ failed
9+
^VERIFICATION FAILED$
10+
^EXIT=10$
11+
^SIGNAL=0$
12+
--
13+
^warning: ignoring
14+
Invariant check failed
15+
--
16+
Uses --no-simplify to avoid removing repeated ASSERT FALSE statements.

src/analyses/goto_check.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,21 @@ void goto_checkt::pointer_overflow_check(
11721172
expr.find_source_location(),
11731173
expr,
11741174
guard);
1175+
1176+
// the result must be within object bounds or one past the end
1177+
const auto size = from_integer(0, size_type());
1178+
auto conditions = get_pointer_dereferenceable_conditions(expr, size);
1179+
1180+
for(const auto &c : conditions)
1181+
{
1182+
add_guarded_property(
1183+
c.assertion,
1184+
"pointer arithmetic: " + c.description,
1185+
"pointer arithmetic",
1186+
expr.find_source_location(),
1187+
expr,
1188+
guard);
1189+
}
11751190
}
11761191

11771192
void goto_checkt::pointer_validity_check(

src/solvers/flattening/bv_pointers.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
506506

507507
const bvt &bv = convert_bv(minus_expr.lhs());
508508

509-
typet pointer_sub_type = minus_expr.rhs().type().subtype();
509+
typet pointer_sub_type = minus_expr.lhs().type().subtype();
510510
mp_integer element_size;
511511

512512
if(pointer_sub_type.id()==ID_empty)

0 commit comments

Comments
 (0)