C语言中strdup与strcat使用异常:堆缓冲区溢出问题排查
堆缓冲区溢出问题分析与修复
你的代码触发堆缓冲区溢出的核心原因:
strdup(server->vhost.root_dir)仅分配了刚好容纳root_dir字符串(含末尾\0)的内存空间strcat(path, request.Request_target)需要在path现有内存基础上,额外容纳Request_target的所有字符加结束符,但当前path没有多余空间,直接写入会越界,触发堆溢出
从AddressSanitizer报错也能验证:分配的30字节区域刚好到0x6030000002ce,而你要写入的位置就是这个地址,刚好超出分配的内存范围。
修复方案
必须先计算两个字符串的总长度,分配足够内存后再拼接,以下是两种可靠实现:
方式1:手动计算长度分配内存
// 计算总长度:root_dir长度 + Request_target长度 + 1(结束符) size_t total_len = strlen(server->vhost.root_dir) + strlen(request.Request_target) + 1; char *path = malloc(total_len); if (path == NULL) { return; } // 先复制root_dir,再拼接Request_target strcpy(path, server->vhost.root_dir); strcat(path, request.Request_target); // 注意:使用完path后需调用free(path)避免内存泄漏
方式2:用snprintf更安全(推荐)
snprintf可直接指定缓冲区大小,规避手动拼接的风险:
size_t root_len = strlen(server->vhost.root_dir); size_t target_len = strlen(request.Request_target); size_t total_len = root_len + target_len + 1; char *path = malloc(total_len); if (path == NULL) { return; } // 一次性完成拼接 snprintf(path, total_len, "%s%s", server->vhost.root_dir, request.Request_target); // 使用完后调用free(path)
另外注意:原代码中strcat的返回值永远不会是NULL,所以if (path == NULL)的判断完全无效,可直接删除。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

