为什么这段实现get_next_line的C代码会触发heap-buffer-overflow?
错误原因排查
1. 变量未初始化问题
cnt变量定义时未赋初始值,计数逻辑完全不可控,后续指针回退、内存操作都会因随机值出错nread变量在while循环外未初始化,极端情况下如果read直接失败,nread < 0的判断逻辑可能误判
2. 操作优先级逻辑错误
while循环的判断语句nread = (read(fd, &c, 1)) > 0存在优先级错误:>运算符优先级高于=,实际是把read返回值>0的布尔值赋值给nread,永远拿不到read的真实返回值,nread < 0的错误判断逻辑完全失效。
3. 缓冲区越界问题
- 你申请的缓冲区大小为
BUFFER_SIZE + 1,但while循环中没有判断cnt是否超过缓冲区容量,如果单行长超过BUFFER_SIZE,会直接往堆内存非法地址写数据,触发堆溢出 - 循环中不断对原始
buf指针做自增操作,循环结束后buf已经偏移到你申请的内存区域之外,此时执行*buf = '\n'相当于直接写入非法堆地址 - printf时传入的是已经偏移到非法地址的
buf,且你在*buf = '\n'后没有添加字符串结束符\0,printf("%s")会一直向后读内存直到碰到随机的\0,必然触发越界访问
4. 字符串格式错误
C语言字符串要求以\0作为结束标志,你循环结束后给末尾赋值的是\n而非\0,构造出的内容根本不是合法C字符串,输出必然异常。同时你没有保存内存申请的原始首地址,后续无法正常释放内存,会产生内存泄漏。
修复参考
你可以按以下方向修改:
- 所有局部变量定义时初始化:
cnt = 0、nread = 0 - 额外保存缓冲区原始首地址:
char *buf_start = buf;,后续优先用下标偏移操作,不要修改原始指针 - while循环中增加缓冲区长度判断:
cnt < BUFFER_SIZE,避免写满后越界 - 修正优先级错误:
(nread = read(fd, &c, 1)) > 0 - 循环结束后给字符串末尾加
\0作为结束标志,不要额外添加多余的\n - 输出、返回时都使用缓冲区原始首地址,不要用偏移后的指针
内容的提问来源于stack exchange,提问作者acho
相关产品推荐
相关产品推荐

