代码漏洞判定咨询:属于栈溢出(Stack Smashing)还是格式化字符串漏洞?
代码漏洞分析及问题解答
首先明确:这段代码的问题不是栈溢出(Stack Smashing),栈溢出针对栈上缓冲区越界场景,而代码里的key和input_pwd都是通过malloc在堆上分配的内存,核心问题是野指针导致的未定义行为,搭配多处逻辑错误,具体分析如下:
核心问题拆解
重复释放
key引发野指针:key是在main函数开头分配的堆内存,但while循环的每次迭代都会执行free(key)。第一次循环结束后,key就变成了野指针(指向已被释放的无效内存)。后续循环中,strcmp(input_pwd, key)是用合法内存和野指针指向的未知内存做比较,此时行为完全未定义——可能随机出现strcmp返回0的情况,进而触发detonate_bomb,这就是你观察到“输入错误密码却提示验证通过”的直接原因。strcpy的潜在越界风险:
代码中strcpy(key, "TiTan15m1D\n")复制的字符串包含换行符,总长度(含末尾的\0终止符)刚好等于MAX_INPUT的值,当前不会越界,但如果后续修改字符串长度超过MAX_INPUT,就会导致堆缓冲区溢出。sizeof(char)不是问题根源:
C标准规定sizeof(char)恒等于1,所以malloc(MAX_INPUT * sizeof(char))和malloc(MAX_INPUT)完全等价,这部分代码没有问题。
代码修正建议
- 把
free(key)移出while循环,仅在程序结束前释放一次; - 确保
key的字符串长度(含\0)不超过MAX_INPUT; - 处理
input_pwd中的换行符,避免因换行符导致strcmp匹配失败。
修正后的示例代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> void detonate_bomb () { puts("Approved: bomb detonated!"); exit(1); } #define MAX_INPUT 12 int main() { char *key = malloc(MAX_INPUT * sizeof(char)); // 去掉换行符,确保字符串长度(含\0)不超过MAX_INPUT strcpy(key, "TiTan15m1D"); while (!feof(stdin)) { char *input_pwd = malloc(MAX_INPUT * sizeof(char)); fgets(input_pwd, MAX_INPUT, stdin); // 去除input_pwd中的换行符 input_pwd[strcspn(input_pwd, "\n")] = '\0'; if (strcmp(input_pwd, key) == 0) { detonate_bomb(); } free(input_pwd); puts("Wrong password, try again!"); } // 循环结束后释放key free(key); return 0; }
内容的提问来源于stack exchange,提问作者Agent Programmer 001
相关产品推荐
相关产品推荐

