Skip to content

Commit cc941d3

Browse files
committed
Value sets: Support bit operations over pointers
Bit operations on pointers are used to defend against side channels resulting from speculative execution. Hence we need to support these. Without the support in value sets we silently just returned "unknown" and thus subsequent dereferencing would fail.
1 parent adbc5fb commit cc941d3

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include <stdlib.h>
2+
3+
int main()
4+
{
5+
int a = 42;
6+
size_t mask = ~(size_t)0;
7+
// applying bitmasks to pointers is used to defend against speculative
8+
// execution side channels, hence we need to support this
9+
__CPROVER_assert(*(int *)(mask & (size_t)&a) == 42, "");
10+
11+
// the following bitmasks are for completeness of the test only, they aren't
12+
// necessarily as useful in practice
13+
size_t mask_zero = 0;
14+
__CPROVER_assert(*(int *)(mask_zero | (size_t)&a) == 42, "");
15+
__CPROVER_assert(*(int *)(mask_zero ^ (size_t)&a) == 42, "");
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/pointer-analysis/value_set.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,11 @@ void value_sett::get_value_set_rec(
642642
else
643643
insert(dest, exprt(ID_unknown, original_type));
644644
}
645-
else if(expr.id()==ID_plus ||
646-
expr.id()==ID_minus)
645+
else if(
646+
expr.id() == ID_plus || expr.id() == ID_minus || expr.id() == ID_bitor ||
647+
expr.id() == ID_bitand || expr.id() == ID_bitxor ||
648+
expr.id() == ID_bitnand || expr.id() == ID_bitnor ||
649+
expr.id() == ID_bitxnor)
647650
{
648651
if(expr.operands().size()<2)
649652
throw expr.id_string()+" expected to have at least two operands";
@@ -653,8 +656,9 @@ void value_sett::get_value_set_rec(
653656

654657
// special case for pointer+integer
655658

656-
if(expr.operands().size()==2 &&
657-
expr_type.id()==ID_pointer)
659+
if(
660+
expr.operands().size() == 2 && expr_type.id() == ID_pointer &&
661+
(expr.id() == ID_plus || expr.id() == ID_minus))
658662
{
659663
exprt ptr_operand;
660664

0 commit comments

Comments
 (0)