Example: pointer_copy_user_dataflow_indirect_bytewise.c
#include <stdio.h>
#include <string.h>
int x=1;
void user_memcpy2(unsigned char* dest,
unsigned char *src, size_t n) {
while (n > 0) {
*dest = ((*src) ^ 1) ^ 1;
src += 1;
dest += 1;
n -= 1;
}
}
int main() {
int *p = &x;
int *q;
user_memcpy2((unsigned char*)&q, (unsigned char*)&p,
sizeof(p));
*q = 11; // is this free of undefined behaviour?
printf("*p=%d *q=%d\n",*p,*q);
}
[link to test in Cerberus and Compiler Explorer]
Experimental data (what does this mean?)
gcc-8.1-O0 |   | *p=11 *q=11
|
gcc-8.1-O2 |   | *p=11 *q=11
|
gcc-8.1-O3 |   | *p=11 *q=11
|
gcc-8.1-O2-no-strict-aliasing |   | *p=11 *q=11
|
gcc-8.1-O3-no-strict-aliasing |   | *p=11 *q=11
|
clang-6.0-O0 |   | *p=11 *q=11
|
clang-6.0-O2 |   | *p=11 *q=11
|
clang-6.0-O3 |   | *p=11 *q=11
|
clang-6.0-O2-no-strict-aliasing |   | *p=11 *q=11
|
clang-6.0-O3-no-strict-aliasing |   | *p=11 *q=11
|
clang-6.0-UBSAN |   | *p=11 *q=11
|
clang-6.0-ASAN |   | *p=11 *q=11
|
clang-6.0-MSAN |   | *p=11 *q=11
|
icc-19-O0 |   | *p=11 *q=11
|
icc-19-O2 |   | *p=11 *q=11
|
icc-19-O3 |   | *p=11 *q=11
|
icc-19-O2-no-strict-aliasing |   | *p=11 *q=11
|
icc-19-O3-no-strict-aliasing |   | *p=11 *q=11
|
cerberus-concrete |   | BEGIN EXEC[0] Defined {value: "Specified(0)", stdout: "*p=11 *q=11\n", blocked: "false"} END EXEC[0] Time spent: 0.043690 seconds
|
cerberus-symbolic |   | exit codes: compile 0 / execute 1
cerberus: internal error, uncaught exception: Failure("TODO: Symbolic defacto, isWellAligned_ptrval")
|
gcc-4.9-shadowprov |   | *p=11 *q=11
|
CHERI:MIPS-O0 |   | *p=11 *q=11
|
CHERI:MIPS-O2 |   | *p=11 *q=11
|
CHERI:MIPS-O2-no-strict-aliasing |   | *p=11 *q=11
|
CHERI:CHERI-O0-uintcap-addr-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-uintcap-addr-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O0-uintcap-offset-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-uintcap-offset-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset-exact-equals |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O0-uintcap-addr |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-uintcap-addr |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-no-strict-aliasing-uintcap-addr |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O0-uintcap-offset |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-uintcap-offset |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
CHERI:CHERI-O2-no-strict-aliasing-uintcap-offset |   | exit codes: compile 0 / execute -1
Terminated with signal 34: In-address space security exception |
RV-Match |   | exit codes: compile 0 / execute 139
Indeterminate value used in an expression: > in main at pointer_copy_user_dataflow_indirect_bytewise.c:18:3
Undefined behavior (UB-CEE2): see C11 section 6.2.4 http://rvdoc.org/C11/6.2.4 see C11 section 6.7.9 http://rvdoc.org/C11/6.7.9 see C11 section 6.8 http://rvdoc.org/C11/6.8 see C11 section J.2:1 item 11 http://rvdoc.org/C11/J.2 see CERT-C section EXP33-C http://rvdoc.org/CERT-C/EXP33-C see MISRA-C section 8.9:1 http://rvdoc.org/MISRA-C/8.9 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Dereferencing a null pointer: > in main at pointer_copy_user_dataflow_indirect_bytewise.c:18:3
Undefined behavior (UB-CER3): see C11 section 6.5.3.2:4 http://rvdoc.org/C11/6.5.3.2 see C11 section J.2:1 item 43 http://rvdoc.org/C11/J.2 see CERT-C section EXP34-C http://rvdoc.org/CERT-C/EXP34-C see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Execution failed (configuration dumped)
|
ch2o |   | Fatal error: exception Main.CH2O_undef(_) Raised at file "format.ml", line 185, characters 41-52 Called from file "format.ml", line 427, characters 6-24
|
compcert-3.2 |   | *p=11 *q=11
|
compcert-3.2-O |   | *p=11 *q=11
|
compcert-3.2-interp |   | Time 0: calling main() --[step_internal_function]--> Time 1: in function main, statement p = &x; user_memcpy2((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)); *q = 11; printf(__stringlit_1, *p, *q); return 0; --[step_seq]--> Time 2: in function main, statement p = &x; user_memcpy2((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)); *q = 11; printf(__stringlit_1, *p, *q); --[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 user_memcpy2((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)); *q = 11; printf(__stringlit_1, *p, *q); --[step_seq]--> Time 11: in function main, statement user_memcpy2((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)); --[step_do_1]--> Time 12: in function main, expression user_memcpy2((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)) --[red_var_global]--> Time 13: in function main, expression <loc user_memcpy2>((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)) --[red_rvalof]--> Time 14: in function main, expression <ptr user_memcpy2>((unsigned char *) &q, (unsigned char *) &p, sizeof(int *)) --[red_var_local]--> Time 15: in function main, expression <ptr user_memcpy2>((unsigned char *) &<loc q>, (unsigned char *) &p, sizeof(int *)) --[red_addrof]--> Time 16: in function main, expression <ptr user_memcpy2>((unsigned char *) <ptr q>, (unsigned char *) &p, sizeof(int *)) --[red_cast]--> Time 17: in function main, expression <ptr user_memcpy2>(<ptr q>, (unsigned char *) &p, sizeof(int *)) --[red_var_local]--> Time 18: in function main, expression <ptr user_memcpy2>(<ptr q>, (unsigned char *) &<loc p>, sizeof(int *)) --[red_addrof]--> Time 19: in function main, expression <ptr user_memcpy2>(<ptr q>, (unsigned char *) <ptr p>, sizeof(int *)) --[red_cast]--> Time 20: in function main, expression <ptr user_memcpy2>(<ptr q>, <ptr p>, sizeof(int *)) --[red_sizeof]--> Time 21: in function main, expression <ptr user_memcpy2>(<ptr q>, <ptr p>, 4U) --[red_call]--> Time 22: calling user_memcpy2(<ptr>, <ptr>, 4) --[step_internal_function]--> Time 23: in function user_memcpy2, statement while (n > 0) { *dest = *. ^ 1 ^ 1; src += 1; dest += 1; n -= 1; } --[step_while]--> Time 24: in function user_memcpy2, expression n > 0 --[red_var_local]--> Time 25: in function user_memcpy2, expression <loc n> > 0 --[red_rvalof]--> Time 26: in function user_memcpy2, expression 4U > 0 --[red_binop]--> Time 27: in function user_memcpy2, expression 1 --[step_while_true]--> Time 28: in function user_memcpy2, statement *dest = *. ^ 1 ^ 1; src += 1; dest += 1; n -= 1; --[step_seq]--> Time 29: in function user_memcpy2, statement *dest = *. ^ 1 ^ 1; --[step_do_1]--> Time 30: in function user_memcpy2, expression *dest = *. ^ 1 ^ 1 --[red_var_local]--> Time 31: in function user_memcpy2, expression *<loc dest> = *. ^ 1 ^ 1 --[red_rvalof]--> Time 32: in function user_memcpy2, expression *<ptr> = *. ^ 1 ^ 1 --[red_deref]--> Time 33: in function user_memcpy2, expression <loc> = *. ^ 1 ^ 1 --[red_var_local]--> Time 34: in function user_memcpy2, expression <loc> = *. ^ 1 ^ 1 --[red_rvalof]--> Time 35: in function user_memcpy2, expression <loc> = *<ptr> ^ 1 ^ 1 --[red_deref]--> Time 36: in function user_memcpy2, expression <loc> = <loc> ^ 1 ^ 1 --[red_rvalof]--> Time 37: in function user_memcpy2, expression <loc> = <undef> ^ 1 ^ 1 Stuck state: in function user_memcpy2, expression <loc> = <undef> ^ 1 ^ 1 Stuck subexpression: <undef> ^ 1 ERROR: Undefined behavior In file included from pointer_copy_user_dataflow_indirect_bytewise.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.
|