[opensuse-factory] how to know when fortify source prototypes are shadowed ?
Suppose I have a large body of code, of which programmers are lazy and do something like this: (note that this is a silly example to make my point, the real thing is much more scary) cat lazy.c int printf(const char *format, ...); int main(void) { printf("Problem?"); return 0; } If you compile that with -Wall -Wextra -pedantic or -WWhatever no warning is emitted and the resulting code calls ..call printf .. instead of call __printf_chk .. as it would when <stdio.h> is included. I couldn't find any warning (or much better an error) that I could use to uncover it.. something like -Wshadow-fortify-stuff :-) -- Cristian "I don't know the key to success, but the key to failure is trying to please everybody." -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On 2014-05-07 01:31, Cristian Rodríguez wrote:
Suppose I have a large body of code, of which programmers are lazy and do something like this:
(note that this is a silly example to make my point, the real thing is much more scary)
cat lazy.c
int printf(const char *format, ...);
int main(void) { printf("Problem?"); return 0; }
If you compile that with -Wall -Wextra -pedantic or -WWhatever no warning is emitted and the resulting code calls
Forgive me, my C is rusty and not familiar with Linux coding, but, the above code should call your own version of printf(), not the library one. It is no mistake or error. Yes, your function has the same name as the library one... You mean that the compiler should warn you of the situation? AFAIK, the compiler would only see a problem if you do include the library header for printf(), having doubts as to which one to use. -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar)
El 06/05/14 20:07, Carlos E. R. escribió:
Forgive me, my C is rusty and not familiar with Linux coding, but, the above code should call your own version of printf(),
Yes, if there is one..
Yes, your function has the same name as the library one... You mean that the compiler should warn you of the situation? AFAIK, the compiler would only see a problem if you do include the library header for printf(), having doubts as to which one to use.
I do not mean it should warn by default, since the above example is valid C.. the compiler already warns when: a) there is no prototype warning: incompatible implicit declaration of built-in function ‘printf’ b) the prototype is incompatible .c:2:6: warning: conflicting types for built-in function ‘printf’ long printf(const char *format, ...); and that's gonna be caught by the buildsystem, abort and mark the package as "failed". but not when the prototype is compatible.. since it is valid code, the result however may not be desirable. -- Cristian "I don't know the key to success, but the key to failure is trying to please everybody." -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On Wednesday 2014-05-07 02:07, Carlos E. R. wrote:
On 2014-05-07 01:31, Cristian Rodríguez wrote:
int printf(const char *format, ...);
int main(void) { printf("Problem?"); return 0; }
Forgive me, my C is rusty and not familiar with Linux coding, but, the above code should call your own version of printf(), not the library one.
A personal version of printf() cannot be called - namely because the above sample does not have *any* included.
Yes, your function has the same name as the library one... You mean that the compiler should warn you of the situation? AFAIK, the compiler would only see a problem if you do include the library header for printf(), having doubts as to which one to use.
There is no problem; the rules for name resolution are rather clear cut in C (and even C++). -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On Wednesday 2014-05-07 01:31, Cristian Rodríguez wrote:
Suppose I have a large body of code, of which programmers are lazy and do something like this:
$ cat lazy.c int printf(const char *format, ...); int main(void) { printf("Problem?"); return 0; }
and the resulting code calls ..call printf .. instead of call __printf_chk .. as it would when <stdio.h> is included.
__printf_chk is called. The presence of a redundant identical function declarations/prototypes does not change the program behavior. -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
El 06/05/14 20:28, Jan Engelhardt escribió:
On Wednesday 2014-05-07 01:31, Cristian Rodríguez wrote:
Suppose I have a large body of code, of which programmers are lazy and do something like this:
$ cat lazy.c int printf(const char *format, ...); int main(void) { printf("Problem?"); return 0; }
and the resulting code calls ..call printf .. instead of call __printf_chk .. as it would when <stdio.h> is included.
__printf_chk is called. The presence of a redundant identical function declarations/prototypes does not change the program behavior.
Ok, let me throw in another example .. #include <stdio.h> char *strcpy(char *dest, const char *src); int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; } This is valid but obviously buggy on purpose.. with <string.h> included I get the obvious warning.. In function ‘strcpy’, inlined from ‘main’ at c.c:10:5: /usr/include/bits/string3.h:104:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); No <string.h> and the compiler is silent though the program still crashes. this is more in line with the actual concern I have. -- Cristian "I don't know the key to success, but the key to failure is trying to please everybody." -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On Tue, May 06, 2014 at 08:59:59PM -0400, Cristian Rodríguez wrote:
El 06/05/14 20:28, Jan Engelhardt escribió:
On Wednesday 2014-05-07 01:31, Cristian Rodríguez wrote:
Suppose I have a large body of code, of which programmers are lazy and do something like this:
$ cat lazy.c int printf(const char *format, ...); int main(void) { printf("Problem?"); return 0; }
and the resulting code calls ..call printf .. instead of call __printf_chk .. as it would when <stdio.h> is included.
__printf_chk is called. The presence of a redundant identical function declarations/prototypes does not change the program behavior.
Ok, let me throw in another example ..
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
This is valid but obviously buggy on purpose..
with <string.h> included I get the obvious warning..
In function ‘strcpy’, inlined from ‘main’ at c.c:10:5: /usr/include/bits/string3.h:104:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
No <string.h> and the compiler is silent though the program still crashes. this is more in line with the actual concern I have.
If they want to shoot themselves in the foot, it is hard to avoid. Ciao, Marcus -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On Wed, 7 May 2014, Marcus Meissner wrote:
On Tue, May 06, 2014 at 08:59:59PM -0400, Cristian Rodríguez wrote:
El 06/05/14 20:28, Jan Engelhardt escribió:
On Wednesday 2014-05-07 01:31, Cristian Rodríguez wrote:
Suppose I have a large body of code, of which programmers are lazy and do something like this:
$ cat lazy.c int printf(const char *format, ...); int main(void) { printf("Problem?"); return 0; }
and the resulting code calls ..call printf .. instead of call __printf_chk .. as it would when <stdio.h> is included.
__printf_chk is called. The presence of a redundant identical function declarations/prototypes does not change the program behavior.
Ok, let me throw in another example ..
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
This is valid but obviously buggy on purpose..
with <string.h> included I get the obvious warning..
In function ‘strcpy’, inlined from ‘main’ at c.c:10:5: /usr/include/bits/string3.h:104:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
No <string.h> and the compiler is silent though the program still crashes. this is more in line with the actual concern I have.
If they want to shoot themselves in the foot, it is hard to avoid.
Yep. And as all the fortify stuff is transparent to GCC there is no way GCC can warn about missing fortification. Richard. -- Richard Biener <rguenther@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer
El 07/05/14 03:48, Richard Biener escribió:
Yep. And as all the fortify stuff is transparent to GCC there is no way GCC can warn about missing fortification.
Ok, got it. thanks. -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On Wednesday 2014-05-07 02:59, Cristian Rodríguez wrote:
Ok, let me throw in another example ..
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
This is valid but obviously buggy on purpose..
with <string.h> included I get the obvious warning..
In function ‘strcpy’, inlined from ‘main’ at c.c:10:5: /usr/include/bits/string3.h:104:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
No <string.h> and the compiler is silent though the program still crashes. this is more in line with the actual concern I have.
So, force inclusion of string.h into all compiled files. There's -include you can put into CFLAGS. -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On 2014-05-07 02:59, Cristian Rodríguez wrote:
Ok, let me throw in another example ..
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
This is valid but obviously buggy on purpose..
with <string.h> included I get the obvious warning..
In function ‘strcpy’, inlined from ‘main’ at c.c:10:5: /usr/include/bits/string3.h:104:3: warning: call to __builtin___memcpy_chk will always overflow destination buffer return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
No <string.h> and the compiler is silent though the program still crashes. this is more in line with the actual concern I have.
Interesting. Yes, C is rather (c)rude, it allows you to silently shoot your own foot. The idea is that the programmer is master of the universe and knows what he is doing best, not silly dumb machines. That's why I do not like C. Like assembler on steroids. Even though gcc produces a ton of warnings about things that older compilers said nothing about... IMHO, (about) only the kernel should me made in C. Just as an example, if you do the above example in Pascal, it will always use the local function, the one defined in the same file. To call the system library function of the same name, you would have to explicitly call something like system.strcpy(), so no confusion would be possible, and variable checking would work correctly. Not that I say that you should program in Pascal... it is just an example :-) -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar)
On Wednesday 2014-05-07 14:01, Carlos E. R. wrote:
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
Just as an example, if you do the above example in Pascal, it will always use the local function, the one defined in the same file.
Well, let it be noted you still did not define a strcpy in the same file. Once you do, it's quite clear what will practically happen: it will either get used, or you get a linker error, depending on the keywords you slap onto your own implementation. -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
On 2014-05-07 14:08, Jan Engelhardt wrote:
On Wednesday 2014-05-07 14:01, Carlos E. R. wrote:
#include <stdio.h> char *strcpy(char *dest, const char *src);
int main(void) { char c[3]; strcpy(c, "fuuuuuuuuuuuuuuuuuuuuuuuuuckme"); printf("%s", c); return 0; }
Just as an example, if you do the above example in Pascal, it will always use the local function, the one defined in the same file.
Well, let it be noted you still did not define a strcpy in the same file. Once you do, it's quite clear what will practically happen: it will either get used, or you get a linker error, depending on the keywords you slap onto your own implementation.
Well, yes, it is only the function header in the same file. Where is the actual function code itself is unclear (to me, at least). Does it use the system library code? -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar)
El 07/05/14 08:01, Carlos E. R. escribió:
Yes, C is rather (c)rude, it allows you to silently shoot your own foot. The idea is that the programmer is master of the universe and knows what he is doing best, not silly dumb machines.
Most languages allow you to shoot your own foot, C just gives you a tank instead of a handgun ;-) -- Cristian "I don't know the key to success, but the key to failure is trying to please everybody." -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
Cristian Rodríguez <crrodriguez@opensuse.org> writes:
cat lazy.c
int printf(const char *format, ...);
int main(void) { printf("Problem?"); return 0; }
If you compile that with -Wall -Wextra -pedantic or -WWhatever no warning is emitted and the resulting code calls
..call printf ..
instead of
call __printf_chk .. as it would when <stdio.h> is included.
This program contains nothing about __printf_chk, so why do you think there should be a call to it? Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org
participants (6)
-
Andreas Schwab
-
Carlos E. R.
-
Cristian Rodríguez
-
Jan Engelhardt
-
Marcus Meissner
-
Richard Biener