Example: pointer_offset_from_subtraction_realloc_1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
int main() {
// malloc a region and initialise some data within it
void *p=malloc(2*sizeof(int)); // allocation P
assert(p != NULL); // pick out the interesting execution
int *i=(int*)p;
*(i+0)=10;
*(i+1)=11;
// construct some pointers to that data
int *j0 = i+0;
int *j1 = i+1;
// realloc the region
void *q=realloc(p,65536*sizeof(int)); // allocation Q
assert(q != NULL && q != p); // pick out the interesting execution (UB?)
// calculate the offset between the two allocations
ptrdiff_t offset=(unsigned char*)q-(unsigned char*)p;// does this have UB?
// try to adapt the data pointers to new allocation by adding the offset
int *k0 = (int*)((unsigned char *)j0 + offset); // do these have UB?
int *k1 = (int*)((unsigned char *)j1 + offset);
// and use one of those for an access
*k0=20; // does this have UB?
printf("Addresses: p=%p q=%p\n",(void*)p,(void*)q); // does this have UB?
printf("*k0=%d *k1=%d\n",*k0,*k1);
return 0;
}
[link to test in Cerberus and Compiler Explorer]
Experimental data (what does this mean?)
gcc-8.1-O0 |   | Addresses: p=0x1487010 q=0x7fc01b8c6010 *k0=20 *k1=11
|
gcc-8.1-O2 |   | Addresses: p=0x2081010 q=0x7f466953e010 *k0=20 *k1=11
|
gcc-8.1-O3 |   | Addresses: p=0x1c16010 q=0x7f6819acc010 *k0=20 *k1=11
|
gcc-8.1-O2-no-strict-aliasing |   | Addresses: p=0x17c5010 q=0x7faf14afc010 *k0=20 *k1=11
|
gcc-8.1-O3-no-strict-aliasing |   | Addresses: p=0x25f3010 q=0x7f1fe5d33010 *k0=20 *k1=11
|
clang-6.0-O0 |   | Addresses: p=0x10ae010 q=0x7f1f439cf010 *k0=20 *k1=11
|
clang-6.0-O2 |   | Addresses: p=0xcb6010 q=0x7f656f38e010 *k0=20 *k1=11
|
clang-6.0-O3 |   | Addresses: p=0x1df8010 q=0x7fcdcee6b010 *k0=20 *k1=11
|
clang-6.0-O2-no-strict-aliasing |   | Addresses: p=0x9f1010 q=0x7f05b3a9d010 *k0=20 *k1=11
|
clang-6.0-O3-no-strict-aliasing |   | Addresses: p=0x21be010 q=0x7f4966829010 *k0=20 *k1=11
|
clang-6.0-UBSAN |   | Addresses: p=0x243e040 q=0x7f54f8a7a010 *k0=20 *k1=11
|
clang-6.0-ASAN |   | exit codes: compile 0 / execute 1
================================================================= ==3769==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 262144 byte(s) in 1 object(s) allocated from: #0 0x4ba8f2 in realloc /tmp/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:107:3 #1 0x4e7278 in main (/auto/homes/vb358/charon2/pointer_offset_from_subtraction_realloc_1.c.clang-6.0-ASAN.out+0x4e7278)
SUMMARY: AddressSanitizer: 262144 byte(s) leaked in 1 allocation(s).
|
clang-6.0-MSAN |   | Addresses: p=0x701000000000 q=0x7f53bf355000 *k0=20 *k1=11
|
icc-19-O0 |   | Addresses: p=0x2194010 q=0x7f776dcc5010 *k0=20 *k1=11
|
icc-19-O2 |   | Addresses: p=0x8db010 q=0x7fcd6b137010 *k0=20 *k1=11
|
icc-19-O3 |   | Addresses: p=0x1ffd010 q=0x7f735f810010 *k0=20 *k1=11
|
icc-19-O2-no-strict-aliasing |   | Addresses: p=0x989010 q=0x7f27d6c5f010 *k0=20 *k1=11
|
icc-19-O3-no-strict-aliasing |   | Addresses: p=0x2060010 q=0x7fe8cd837010 *k0=20 *k1=11
|
cerberus-concrete |   | BEGIN EXEC[0] Killed {msg: ill-formed program: `calling an unknown procedure: Symbol(495, Just ("realloc"))'} END EXEC[0] Time spent: 0.042463 seconds
|
cerberus-symbolic |   | exit codes: compile 0 / execute 1
cerberus: internal error, uncaught exception: Failure("TODO: Symbolic defacto, isWellAligned_ptrval")
|
gcc-4.9-shadowprov |   | exit codes: compile 0 / execute 134
|
CHERI:MIPS-O0 |   | Addresses: p=0x4003e008 q=0x40be8e80 *k0=20 *k1=11
|
CHERI:MIPS-O2 |   | Addresses: p=0x4003e008 q=0x40be8e80 *k0=20 *k1=11
|
CHERI:MIPS-O2-no-strict-aliasing |   | Addresses: p=0x4003e008 q=0x40be8e80 *k0=20 *k1=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
Referring to an object outside of its lifetime: > in main at pointer_offset_from_subtraction_realloc_1.c:18:2
Undefined behavior (UB-CEE4): see C11 section 6.2.4:2 http://rvdoc.org/C11/6.2.4 see C11 section J.2:1 item 9 http://rvdoc.org/C11/J.2 see CERT-C section DCL21-C http://rvdoc.org/CERT-C/DCL21-C see CERT-C section DCL30-C http://rvdoc.org/CERT-C/DCL30-C see CERT-C section MEM30-C http://rvdoc.org/CERT-C/MEM30-C see MISRA-C section 8.18:6 http://rvdoc.org/MISRA-C/8.18 see MISRA-C section 8.22:6 http://rvdoc.org/MISRA-C/8.22 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Referring to an object outside of its lifetime: > in main at pointer_offset_from_subtraction_realloc_1.c:20:3
Undefined behavior (UB-CEE4): see C11 section 6.2.4:2 http://rvdoc.org/C11/6.2.4 see C11 section J.2:1 item 9 http://rvdoc.org/C11/J.2 see CERT-C section DCL21-C http://rvdoc.org/CERT-C/DCL21-C see CERT-C section DCL30-C http://rvdoc.org/CERT-C/DCL30-C see CERT-C section MEM30-C http://rvdoc.org/CERT-C/MEM30-C see MISRA-C section 8.18:6 http://rvdoc.org/MISRA-C/8.18 see MISRA-C section 8.22:6 http://rvdoc.org/MISRA-C/8.22 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Computing pointer difference between two different objects: > in main at pointer_offset_from_subtraction_realloc_1.c:20:3
Undefined behavior (UB-CEA5): see C11 section 6.5.6:9 http://rvdoc.org/C11/6.5.6 see C11 section J.2:1 item 48 http://rvdoc.org/C11/J.2 see CERT-C section ARR36-C http://rvdoc.org/CERT-C/ARR36-C see MISRA-C section 8.18:2 http://rvdoc.org/MISRA-C/8.18 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Referring to an object outside of its lifetime: > in main at pointer_offset_from_subtraction_realloc_1.c:22:3
Undefined behavior (UB-CEE4): see C11 section 6.2.4:2 http://rvdoc.org/C11/6.2.4 see C11 section J.2:1 item 9 http://rvdoc.org/C11/J.2 see CERT-C section DCL21-C http://rvdoc.org/CERT-C/DCL21-C see CERT-C section DCL30-C http://rvdoc.org/CERT-C/DCL30-C see CERT-C section MEM30-C http://rvdoc.org/CERT-C/MEM30-C see MISRA-C section 8.18:6 http://rvdoc.org/MISRA-C/8.18 see MISRA-C section 8.22:6 http://rvdoc.org/MISRA-C/8.22 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Referring to an object outside of its lifetime: > in main at pointer_offset_from_subtraction_realloc_1.c:23:3
Undefined behavior (UB-CEE4): see C11 section 6.2.4:2 http://rvdoc.org/C11/6.2.4 see C11 section J.2:1 item 9 http://rvdoc.org/C11/J.2 see CERT-C section DCL21-C http://rvdoc.org/CERT-C/DCL21-C see CERT-C section DCL30-C http://rvdoc.org/CERT-C/DCL30-C see CERT-C section MEM30-C http://rvdoc.org/CERT-C/MEM30-C see MISRA-C section 8.18:6 http://rvdoc.org/MISRA-C/8.18 see MISRA-C section 8.22:6 http://rvdoc.org/MISRA-C/8.22 see MISRA-C section 8.1:3 http://rvdoc.org/MISRA-C/8.1
Dereferencing a null pointer: > in main at pointer_offset_from_subtraction_realloc_1.c:25: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 |   | pointer_offset_from_subtraction_realloc_1.c:5:10: fatal error: assert.h: No such file or directory #include <assert.h> ^~~~~~~~~~ compilation terminated.
|
compcert-3.2 |   | Addresses: p=0x25ee010 q=0x7f3917414010 *k0=20 *k1=11
|
compcert-3.2-O |   | Addresses: p=0x1db4010 q=0x7f6876e91010 *k0=20 *k1=11
|
compcert-3.2-interp |   | Time 0: calling main() --[step_internal_function]--> Time 1: in function main, statement p = malloc(2 * sizeof(int)); (void) (p != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())); i = (int *) p; *(i + 0) = 10; *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; return 0; --[step_seq]--> Time 2: in function main, statement p = malloc(2 * sizeof(int)); (void) (p != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())); i = (int *) p; *(i + 0) = 10; *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 3: in function main, statement p = malloc(2 * sizeof(int)); --[step_do_1]--> Time 4: in function main, expression p = malloc(2 * sizeof(int)) --[red_var_local]--> Time 5: in function main, expression <loc p> = malloc(2 * sizeof(int)) --[red_var_global]--> Time 6: in function main, expression <loc p> = <loc malloc>(2 * sizeof(int)) --[red_rvalof]--> Time 7: in function main, expression <loc p> = <ptr malloc>(2 * sizeof(int)) --[red_sizeof]--> Time 8: in function main, expression <loc p> = <ptr malloc>(2 * 4U) --[red_binop]--> Time 9: in function main, expression <loc p> = <ptr malloc>(8U) --[red_call]--> Time 10: calling malloc(8) --[step_external_function]--> Time 11: returning <ptr> --[step_returnstate]--> Time 12: in function main, expression <loc p> = <ptr> --[red_assign]--> Time 13: in function main, expression <ptr> --[step_do_2]--> Time 14: in function main, statement /*skip*/; --[step_skip_seq]--> Time 15: in function main, statement (void) (p != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())); i = (int *) p; *(i + 0) = 10; *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 16: in function main, statement (void) (p != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())); --[step_do_1]--> Time 17: in function main, expression (void) (p != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())) --[red_var_local]--> Time 18: in function main, expression (void) (<loc p> != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())) --[red_rvalof]--> Time 19: in function main, expression (void) (<ptr> != (void *) 0 ? (void) 0 : ((void) printf(., ., ., .), abort())) --[red_cast]--> Time 20: in function main, expression (void) (<ptr> != 0 ? (void) 0 : ((void) printf(., ., ., .), abort())) --[red_binop]--> Time 21: in function main, expression (void) (1 ? (void) 0 : ((void) printf(., ., ., .), abort())) --[red_condition]--> Time 22: in function main, expression (void) (void) (void) 0 --[red_cast]--> Time 23: in function main, expression (void) (void) 0 --[red_paren]--> Time 24: in function main, expression (void) 0 --[red_cast]--> Time 25: in function main, expression 0 --[step_do_2]--> Time 26: in function main, statement /*skip*/; --[step_skip_seq]--> Time 27: in function main, statement i = (int *) p; *(i + 0) = 10; *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 28: in function main, statement i = (int *) p; --[step_do_1]--> Time 29: in function main, expression i = (int *) p --[red_var_local]--> Time 30: in function main, expression <loc i> = (int *) p --[red_var_local]--> Time 31: in function main, expression <loc i> = (int *) <loc p> --[red_rvalof]--> Time 32: in function main, expression <loc i> = (int *) <ptr> --[red_cast]--> Time 33: in function main, expression <loc i> = <ptr> --[red_assign]--> Time 34: in function main, expression <ptr> --[step_do_2]--> Time 35: in function main, statement /*skip*/; --[step_skip_seq]--> Time 36: in function main, statement *(i + 0) = 10; *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 37: in function main, statement *(i + 0) = 10; --[step_do_1]--> Time 38: in function main, expression *(i + 0) = 10 --[red_var_local]--> Time 39: in function main, expression *(<loc i> + 0) = 10 --[red_rvalof]--> Time 40: in function main, expression *(<ptr> + 0) = 10 --[red_binop]--> Time 41: in function main, expression *<ptr> = 10 --[red_deref]--> Time 42: in function main, expression <loc> = 10 --[red_assign]--> Time 43: in function main, expression 10 --[step_do_2]--> Time 44: in function main, statement /*skip*/; --[step_skip_seq]--> Time 45: in function main, statement *(i + 1) = 11; j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 46: in function main, statement *(i + 1) = 11; --[step_do_1]--> Time 47: in function main, expression *(i + 1) = 11 --[red_var_local]--> Time 48: in function main, expression *(<loc i> + 1) = 11 --[red_rvalof]--> Time 49: in function main, expression *(<ptr> + 1) = 11 --[red_binop]--> Time 50: in function main, expression *<ptr> = 11 --[red_deref]--> Time 51: in function main, expression <loc> = 11 --[red_assign]--> Time 52: in function main, expression 11 --[step_do_2]--> Time 53: in function main, statement /*skip*/; --[step_skip_seq]--> Time 54: in function main, statement j0 = i + 0; j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 55: in function main, statement j0 = i + 0; --[step_do_1]--> Time 56: in function main, expression j0 = i + 0 --[red_var_local]--> Time 57: in function main, expression <loc j0> = i + 0 --[red_var_local]--> Time 58: in function main, expression <loc j0> = <loc i> + 0 --[red_rvalof]--> Time 59: in function main, expression <loc j0> = <ptr> + 0 --[red_binop]--> Time 60: in function main, expression <loc j0> = <ptr> --[red_assign]--> Time 61: in function main, expression <ptr> --[step_do_2]--> Time 62: in function main, statement /*skip*/; --[step_skip_seq]--> Time 63: in function main, statement j1 = i + 1; q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 64: in function main, statement j1 = i + 1; --[step_do_1]--> Time 65: in function main, expression j1 = i + 1 --[red_var_local]--> Time 66: in function main, expression <loc j1> = i + 1 --[red_var_local]--> Time 67: in function main, expression <loc j1> = <loc i> + 1 --[red_rvalof]--> Time 68: in function main, expression <loc j1> = <ptr> + 1 --[red_binop]--> Time 69: in function main, expression <loc j1> = <ptr> --[red_assign]--> Time 70: in function main, expression <ptr> --[step_do_2]--> Time 71: in function main, statement /*skip*/; --[step_skip_seq]--> Time 72: in function main, statement q = realloc(p, 65536 * sizeof(int)); (void) (q != (void *) 0 && q != p ? (void) 0 : ((void) printf(., ., ., .), abort())); offset = (unsigned char *) q - (unsigned char *) p; k0 = (int *) ((unsigned char *) j0 + offset); k1 = (int *) ((unsigned char *) j1 + offset); *k0 = 20; printf(__stringlit_5, (void *) p, (void *) q); printf(__stringlit_6, *k0, *k1); return 0; --[step_seq]--> Time 73: in function main, statement q = realloc(p, 65536 * sizeof(int)); --[step_do_1]--> Time 74: in function main, expression q = realloc(p, 65536 * sizeof(int)) --[red_var_local]--> Time 75: in function main, expression <loc q> = realloc(p, 65536 * sizeof(int)) --[red_var_global]--> Time 76: in function main, expression <loc q> = <loc realloc>(p, 65536 * sizeof(int)) --[red_rvalof]--> Time 77: in function main, expression <loc q> = <ptr realloc>(p, 65536 * sizeof(int)) --[red_var_local]--> Time 78: in function main, expression <loc q> = <ptr realloc>(<loc p>, 65536 * sizeof(int)) --[red_rvalof]--> Time 79: in function main, expression <loc q> = <ptr realloc>(<ptr>, 65536 * sizeof(int)) --[red_sizeof]--> Time 80: in function main, expression <loc q> = <ptr realloc>(<ptr>, 65536 * 4U) --[red_binop]--> Time 81: in function main, expression <loc q> = <ptr realloc>(<ptr>, 262144U) --[red_call]--> Time 82: calling realloc(<ptr>, 262144) Stuck state: calling realloc(<ptr>, 262144) ERROR: Undefined behavior In file included from pointer_offset_from_subtraction_realloc_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.
|