elixir elixir - 5 months ago 11
Linux Question

Why is SIGFPE not triggered after adding a printf line?

I am playing with a simple program (source code below). And my computer configuration:

Linux mymachine 3.13.0-49-generic #83-Ubuntu SMP Fri Apr 10 20:11:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void catcher(int a){
setresuid(geteuid(),geteuid(),geteuid());
printf("WIN!\n");
system("/bin/sh");
exit(0);
}

int main(int argc, char **argv){
puts("source code is available in level02.c\n");

if (argc != 3 || !atoi(argv[2]))
//printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
return 1;
signal(SIGFPE, catcher);
printf("end\n");

return abs(atoi(argv[1])) / atoi(argv[2]);
}


I intend to trigger the SIGFPE in this program by calling the executable in this way:

$./a.out -2147483648 -1
source code is available in level02.c

end
WIN!


As you can see, the SIGFPE is successfully triggered. However, if I uncomment a single printf line in the argument checking "if" condition:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void catcher(int a){
setresuid(geteuid(),geteuid(),geteuid());
printf("WIN!\n");
system("/bin/sh");
exit(0);
}

int main(int argc, char **argv){
puts("source code is available in level02.c\n");

if (argc != 3 || !atoi(argv[2]))
printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
return 1;
signal(SIGFPE, catcher);
printf("end\n");

return abs(atoi(argv[1])) / atoi(argv[2]);
}


And then I recompile the program and try to trigger SIGFPE using the same way. I only get this:

source code is available in level02.c


What is happening?

Answer

Because now your source code is mis-indented compared to how it is actually parsed.

if (argc != 3 || !atoi(argv[2]))
    printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
return 1;

Consider putting both statements in a block instead to avoid this.

Comments