我用C编写了一个简单的程序,它为字符串向量分配内存然后打印出来.
#include <stdio.h>
#include <string.h>
int main() {
char str_a[20];
strcpy(str_a, "Hello, world!\n");
printf(str_a);
}
Run Code Online (Sandbox Code Playgroud)
使用编译器gcc,这会产生编译错误:
char_array2.c:8:12: warning: format string is not a string literal
(potentially insecure) [-Wformat-security]
printf(str_a);
1 warning generated.
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我会收到警告.有人可以向我解释一下吗?
oua*_*uah 15
使用:
printf("%s", str_a);
Run Code Online (Sandbox Code Playgroud)
-Wformat-security启用后摆脱警告.
诊断信息可以避免格式字符串漏洞.例如:
strcpy(str_a, "%x%x%x%x");
printf(str_a);
Run Code Online (Sandbox Code Playgroud)
相当于:
printf("%x%x%x%x");
Run Code Online (Sandbox Code Playgroud)
缺少必需的参数,攻击者可以使用它来转储堆栈(假设str_a是在用户控制下,在程序中不是这种情况,但是gcc不够智能).
其他答案更好。但如果所有其他方法都失败,您可以告诉编译器忽略该错误。
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
printf(str_a);
#pragma clang diagnostic pop
Run Code Online (Sandbox Code Playgroud)
考虑3个printf()陈述.如果存在格式不匹配,编译器可以检测哪个?
void foo(const char *str_a,int x) {
printf("Hello %d\n", x); // Compiler sees this is good
printf("Hello %d\n"); // Compiler sees this is bad --> warning/error
printf(str_a, x); // Compiler cannot tell - thus the warning
}
Run Code Online (Sandbox Code Playgroud)