Skip to content

Commit 4a31d62

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 4a31d62

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed
Lines changed: 13 additions & 0 deletions
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+
}
Lines changed: 16 additions & 0 deletions
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

Lines changed: 15 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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)