/* Run at CSE like this $ clang -Wno-everything invalid3.c -o invalid3 $ ./invalid3 I hate you. $ */ #include #include #include void f(void); int main(void) { f(); printf("I love you and will never say,\n"); printf("I hate you.\n"); return 0; } void f(void) { uint64_t a[1]; #ifdef __clang__ #if __clang_major__ >= 16 #error "Don't know the correct offset for this clang version" #elif __clang_major__ >= 14 a[2] += 14; #elif __clang_major__ >= 4 a[2] += 17; #elif __clang_major__ == 3 #if __clang_minor__ >= 5 a[2] += 17; #elif __clang_minor__ >= 4 a[2] += 15; #else // clang 3.0-3.3 are broken on godbolt.org #error "Don't know the correct offset for this clang version" #endif #else // clang <3.0 are not avalible on godbolt.org #error "Don't know the correct offset for this clang version" #endif #else #error "This program must be compiled with clang" #endif // function f has it return address on the stack // the call of function f from main should return to // the next statement which is: printf("I love you and will never say,\n"); // // on CSE servers (clang 11.0 x86_64/Linux) // f's return address is stored where a[2] would be // // so changing a[2] changes where the function returns // // adding 17 to a[12] happens to cause it to return 2 statements later // at: printf("I hate you.\n"); }