You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

代码漏洞判定咨询:属于栈溢出(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:20:33