【问题标题】:Why am I getting heap-buffer-overflow in this C code?为什么我在这个 C 代码中得到堆缓冲区溢出?
【发布时间】:2021-11-30 06:02:49
【问题描述】:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

char *get_next_line(int fd);

int main (void)
{
    int i = 0;
    char *s;
    int fd;

    fd = open("./text", O_RDONLY);
    s = get_next_line (fd);

}

char *get_next_line(int fd)
{
    char    *buf;
    char    c;
    int     nread;
    int     cnt;


    if (fd < 0 || BUFFER_SIZE < 1)
        return (NULL);
    buf = (char*)malloc(BUFFER_SIZE + 1);
    if (!buf)
        return (NULL);

    while(nread = (read(fd, &c, 1)) > 0)
    {
        *buf = c;
        buf++;
        cnt++;
        if (c == '\n')
            break;
    }
    if (nread < 0)
        return (NULL);
    *buf = '\n';
    printf("%s\n", buf);

    return (buf - cnt - 1);
}

当我在没有标志的情况下编译时,我只得到两个空行。使用 -fsanitize=address 编译,我知道 heap-buffer-overflow 发生在 printf("%s\n", buf);

但我不知道为什么会这样。我尝试了 STDIN 来修复它,但没有奏效。有人可以检查一下吗?

【问题讨论】:

  • 如果函数返回除buf 之外的任何内容,您也会得到泄漏,因为没有人再跟踪该段的起始地址。

标签: c heap-memory


【解决方案1】:
  1. 您没有用空字符终止buf

    *buf = '\n';
    *buf = '\0';
    

    确保在为buf 分配内存时为null 字符保留空间。

  2. 如果读取的字节数小于 0,则释放内存。

    if (nread < 0) {
        return (NULL);
    } 
    

    if (nread < 0)  {
        free(startAddress);
        return (NULL);
    }
    
  3. 您可以使用临时指针来保存buf 的起始地址,而不是计算起始地址。


    char *get_next_line(int fd)
    {
        char    *buf;
        char    c;
        int     nread;
    
    
        if (fd < 0 || BUFFER_SIZE < 1)
            return (NULL);
        buf = (char*)malloc(BUFFER_SIZE + 2);
        if (!buf)
            return (NULL);
    
        char *startAddress = buf;
        while(nread = (read(fd, &c, 1)) > 0)
        {
            *buf = c;
            buf++;
            if (c == '\n')
                break;
        }
        if (nread < 0)  {
            free(startAddress);
            return (NULL);
        }
        *buf  = '\0';  
        printf("%s\n", buf);
    
        return startAddress;
    }

【讨论】:

  • 天哪,原来是 \0.. 非常感谢!
猜你喜欢
  • 2020-02-09
  • 1970-01-01
  • 2010-09-28
  • 1970-01-01
  • 2010-11-10
  • 2022-01-22
  • 1970-01-01
  • 2017-06-26
  • 2010-11-11
相关资源
最近更新 更多