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.