3 ms·
I ran the following code through GCC: #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(void) { if (getuid() !=
by spc476 13y ago
I ran the following code through GCC:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
if (getuid() != 0 && geteuid == 0)
{
printf("only root\n");
return 1;
}
printf("okay\n");
return 0;
}
With just a plain GCC (no options), the code compiled and exhibited the bug (it always printed "okay"). That's to be expected. What was not expected what when I compiled the code with "gcc -ansi -Wall -Wextra -pedantic". NOT ONE ERROR OR WARNING!
How is that happening?
Well, C allows function pointers. Also, in C, a value of 0 used in a pointer context is treated as a NULL pointer. So that one line is seen as:
if (getuid() != 0 && geteuid == NULL)
Now, let's play compiler. geteuid() is a function and it's defined. So the compiler can generate:
if (getuid() != 0 && false)
The result of this expression can never be true. But because the call to getuid() could cause side-effects (the prototype for getuid() does not include the GCC extension marking it as a "pure" function) the compiler has to emit a call to the function, but otherwise, it ignores the result since it doesn't matter what the result is. The resultant code is:
int main(void)
{
getuid();
printf("okay\n");
return 0;
}
And thus, it's possible, even with the commonly used "-Wall -Wextra" options to GCC. To detect this, you will also need to add "-Wunreachable-code" (why that isn't included with '-Wall' is a good question).
- CUViper 13y ago> "gcc -ansi -Wall -Wextra -pedantic". NOT ONE ERROR OR WARNING! $ rpm -q gcc gcc-4.8.2-7.fc20.x86_64 $ gcc -ansi -Wall -Wextra -pedantic test.c test.c: In function ‘main’: test.c:7:36: warning: the comparison will always evaluate as ‘false’ for the address of ‘geteuid’ will never be NULL [-Waddress] if (getuid() != 0 && geteuid == 0) ^ If fact, just -Wall is enough to enable that warning. Maybe the coverage of -Waddress has changed since your version?
- spc476 13y agoCould very well be. I am using a slightly older version of GCC.
- w-m 13y agohuh? gcc 4.2 -Wall: warning: the address of ‘geteuid’ will never be NULL gcc 4.8 -Wall: warning: the comparison will always evaluate as 'false' for the address of 'geteuid' will never be NULL [-Waddress] if (getuid() != 0 && geteuid == 0) Also, as came up in the goto fail discussion, -Wunreachable-code was removed from gcc and doesn't warn on anything.
- spc476 13y agoIt appears that GCC has changed a bit since that article was originally written (2010). And I'm using a GCC that is a bit old.
- nkeets 13y agoIt appears that you are spreading FUD. In a thread discussing if one line bugs could be written on purpose, it is only fitting to discuss if you demonstrated gcc's failing by using a version older than 4.2 was also on purpose. By the way, I'm interested to know which version you used.
- spc476 13y agoHow am I spreading FUD? By using an older version of GCC and reporting what I saw? Should I edit my post to remove all mentions of GCC and just leave how the code is interpreted as is?
- nkeets 13y agoIt has to be before 4.2 (you never said which version you used), which is really old. And you went to all this trouble but never occurred to you that compiler version could be a factor? Sure it could be an honest mistake, but that's also true for Apple's bug (and the rest).