Example: provenance_lost_escape_1.c
#include <stdio.h>
#include <string.h>
#include <stdint.h>
int x=1;
int main() {
int *p = &x; // assume allocated at 0x6009b8
uintptr_t i1 = (intptr_t)p; // value 0x6009b8 provenance x
uintptr_t i2 = i1 & 0x00000000FFFFFFFF; //
uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x
uintptr_t i4 = i3 + 0x6009b8; // value 0x6009b8 provenance x
int *q = (int *)i4;
printf("Addresses: p=%p\n",(void*)p);
if (memcmp(&i1, &i4, sizeof(i1)) == 0) {
*q = 11; // does this have defined behaviour?
printf("x=%d *p=%d *q=%d\n",x,*p,*q);
}
return 0;
}
[link to test in Cerberus and Compiler Explorer]
Experimental data (what does this mean?)
SOURCES MISMATCH
gcc-8.1-O0 |   | Addresses: p=0x600a50
|
gcc-8.1-O2 |   | Addresses: p=0x6009a8
|
gcc-8.1-O3 |   | Addresses: p=0x6009a8
|
gcc-8.1-O2-no-strict-aliasing |   | Addresses: p=0x6009a8
|
gcc-8.1-O3-no-strict-aliasing |   | Addresses: p=0x6009a8
|
clang-6.0-O0 |   | Addresses: p=0x601038
|
clang-6.0-O2 |   | Addresses: p=0x601038
|
clang-6.0-O3 |   | Addresses: p=0x601038
|
clang-6.0-O2-no-strict-aliasing |   | Addresses: p=0x601038
|
clang-6.0-O3-no-strict-aliasing |   | Addresses: p=0x601038
|
clang-6.0-UBSAN |   | Addresses: p=0x631b50
|
clang-6.0-ASAN |   | Addresses: p=0x716b60
|
clang-6.0-MSAN |   | Addresses: p=0x6b7af0
|
icc-19-O0 |   | Addresses: p=0x600b70
|
icc-19-O2 |   | Addresses: p=0x6046c0
|
icc-19-O3 |   | Addresses: p=0x6046c0
|
icc-19-O2-no-strict-aliasing |   | Addresses: p=0x6046c0
|
icc-19-O3-no-strict-aliasing |   | Addresses: p=0x6046c0
|
cerberus-concrete |   | BEGIN EXEC[0] Defined {value: "Specified(0)", stdout: "Addresses: p=<5>:60\n", blocked: "false"} END EXEC[0] Time spent: 0.034947 seconds
|
cerberus-symbolic |   | |
gcc-4.9-shadowprov |   | Addresses: p=0x414148
|
CHERI:MIPS-O0 |   | Addresses: p=0x30020
|
CHERI:MIPS-O2 |   | Addresses: p=0x30020
|
CHERI:MIPS-O2-no-strict-aliasing |   | Addresses: p=0x30020
|
CHERI:CHERI-O0-uintcap-addr-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-uintcap-addr-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O0-uintcap-offset-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-uintcap-offset-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset-exact-equals |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O0-uintcap-addr |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-uintcap-addr |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O0-uintcap-offset |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-uintcap-offset |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset |   | provenance_lost_escape_1.c:8:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i2 = i1 & 0x00000000FFFFFFFF; // ~~ ^ ~~~~~~~~~~~~~~~~~~ provenance_lost_escape_1.c:9:21: warning: using bitwise and on capability types may give surprising results; if this is an alignment check use __builtin_{is_aligned,align_up,align_down}(); if you are operating on integer values only consider using size_t/vaddr_t; if you are attempting to store data in the low pointer bits use the cheri_{get,set,clear}_low_ptr_bits() macros. [-Wcheri-bitwise-operations] uintptr_t i3 = i2 & 0xFFFFFFFF00000000; // value 0x0, provenance x ~~ ^ ~~~~~~~~~~~~~~~~~~ 2 warnings generated. Addresses: p=0x120020010
|
RV-Match |   | exit codes: compile 0 / execute 139
Encountered an unknown error. This may be due to encountering undefined behavior, an unsupported language feature, or a bug in this tool. Compile with '-frecover-all-errors' to enable error recovery: > in main at provenance_lost_escape_1.c:7:3
Unknown error (UNK-2)
Execution failed (configuration dumped)
|
ch2o |   | In file included from /usr/local/Cellar/gcc/7.3.0_1/lib/gcc/7/gcc/x86_64-apple-darwin17.3.0/7.3.0/include/stdint.h:9:0, from provenance_lost_escape_1.c:3: /usr/local/Cellar/gcc/7.3.0_1/lib/gcc/7/gcc/x86_64-apple-darwin17.3.0/7.3.0/include-fixed/stdint.h:27:10: fatal error: sys/_types/_int8_t.h: No such file or directory #include <sys/_types/_int8_t.h> ^~~~~~~~~~~~~~~~~~~~~~ compilation terminated.
|
compcert-3.2 |   | Addresses: p=0x601040
|
compcert-3.2-O |   | Addresses: p=0x601040
|
compcert-3.2-interp |   | Time 0: calling main() --[step_internal_function]--> Time 1: in function main, statement p = &x; i1 = (int) p; i2 = i1 & 4294967295U; i3 = i2 & 18446744069414584320LLU; i4 = i3 + 140448848947392LL; q = (int *) i4; printf(__stringlit_1, (void *) p); if (memcmp(&i1, &i4, sizeof(unsigned int)) == 0) { *q = 11; printf(__stringlit_2, x, *., *.); } return 0; return 0; --[step_seq]--> Time 2: in function main, statement p = &x; i1 = (int) p; i2 = i1 & 4294967295U; i3 = i2 & 18446744069414584320LLU; i4 = i3 + 140448848947392LL; q = (int *) i4; printf(__stringlit_1, (void *) p); if (memcmp(&i1, &i4, sizeof(unsigned int)) == 0) { *q = 11; printf(__stringlit_2, x, *., *.); } return 0; --[step_seq]--> Time 3: in function main, statement p = &x; --[step_do_1]--> Time 4: in function main, expression p = &x --[red_var_local]--> Time 5: in function main, expression <loc p> = &x --[red_var_global]--> Time 6: in function main, expression <loc p> = &<loc x> --[red_addrof]--> Time 7: in function main, expression <loc p> = <ptr x> --[red_assign]--> Time 8: in function main, expression <ptr x> --[step_do_2]--> Time 9: in function main, statement /*skip*/; --[step_skip_seq]--> Time 10: in function main, statement i1 = (int) p; i2 = i1 & 4294967295U; i3 = i2 & 18446744069414584320LLU; i4 = i3 + 140448848947392LL; q = (int *) i4; printf(__stringlit_1, (void *) p); if (memcmp(&i1, &i4, sizeof(unsigned int)) == 0) { *q = 11; printf(__stringlit_2, x, *., *.); } return 0; --[step_seq]--> Time 11: in function main, statement i1 = (int) p; --[step_do_1]--> Time 12: in function main, expression i1 = (int) p --[red_var_local]--> Time 13: in function main, expression <loc i1> = (int) p --[red_var_local]--> Time 14: in function main, expression <loc i1> = (int) <loc p> --[red_rvalof]--> Time 15: in function main, expression <loc i1> = (int) <ptr x> --[red_cast]--> Time 16: in function main, expression <loc i1> = <ptr x> --[red_assign]--> Time 17: in function main, expression <ptr x> --[step_do_2]--> Time 18: in function main, statement /*skip*/; --[step_skip_seq]--> Time 19: in function main, statement i2 = i1 & 4294967295U; i3 = i2 & 18446744069414584320LLU; i4 = i3 + 140448848947392LL; q = (int *) i4; printf(__stringlit_1, (void *) p); if (memcmp(&i1, &i4, sizeof(unsigned int)) == 0) { *q = 11; printf(__stringlit_2, x, *., *.); } return 0; --[step_seq]--> Time 20: in function main, statement i2 = i1 & 4294967295U; --[step_do_1]--> Time 21: in function main, expression i2 = i1 & 4294967295U --[red_var_local]--> Time 22: in function main, expression <loc i2> = i1 & 4294967295U --[red_var_local]--> Time 23: in function main, expression <loc i2> = <loc i1> & 4294967295U --[red_rvalof]--> Time 24: in function main, expression <loc i2> = <ptr x> & 4294967295U Stuck state: in function main, expression <loc i2> = <ptr x> & 4294967295U Stuck subexpression: <ptr x> & 4294967295U ERROR: Undefined behavior In file included from provenance_lost_escape_1.c:1: In file included from /usr/include/stdio.h:64: In file included from /usr/include/_stdio.h:68: /usr/include/sys/cdefs.h:81:2: warning: "Unsupported compiler detected" [-W#warnings] #warning "Unsupported compiler detected" ^ 1 warning generated.
|