1 2 #include <stdlib.h> 3 4 typedef unsigned long Ulong; 5 6 int main(void) 7 { 8 long* x = malloc(sizeof(long) * 10); 9 long* y = malloc(sizeof(long) * 10); 10 long* y2 = y + 3; 11 12 // ok -- same segment 13 long w = y2 - y; 14 15 // ok -- different heap segments (result can only be used to index off 16 // 'x', but glibc's strcpy() does this...) 17 long* z = (long*)((long)x - (long)y); 18 19 w = (long)y2 + (long)y; // bad (same segment) 20 21 w = (long)x & (long)y; // bad (different segments) 22 23 w = (long)y2 / (long)4; // bad, but indistinguishable from 24 // acceptable '%' cases... 25 26 w = (long)y2 % (long)4; // ok 27 w = (long)y2 % (long)y; // bad -- modulor(?) is a pointer 28 w = (long)0xffffffff % (long)y; // bad -- modulend(?) is a non-pointer 29 30 w = (Ulong)y2 % (Ulong)4; // ok 31 w = (Ulong)y2 % (Ulong)y; // bad -- modulor(?) is a pointer 32 w = (Ulong)0xffffffff % (Ulong)y; // bad -- modulend(?) is a non-pointer 33 34 w = (long)y * (long)y2; // bad 35 36 w = (long)y >> (long)2; // ok 37 w = (long)y << (long)2; // ok 38 39 w = (long)y & 0xffff; // ok 40 w = (long)y | 0xffff; // ok 41 w = (long)y ^ (long)y2; // ok 42 43 w = ~((long)y); // ok 44 45 w = -((long)y); // bad -- operand is a non-polonger 46 47 w = (long)x ^ (long)x; // xor(ptr,ptr) --> constant (0) 48 z = x + w; // ok, because xor result was zero 49 50 w = (long)x ^ ((long)x+1); // xor(ptr,ptr') --> constant (small) 51 z = x + w; // ok, because xor result was constant 52 53 w = (long)x ^ (long)y; // xor(ptr,ptr') --> constant (small) 54 z = x + w; // ok, because xor result was constant 55 56 return (long)z; 57 } 58