为什么我在这段 C 代码中会出现堆缓冲区溢出?

Why am I getting heap-buffer-overflow in this C code?

#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 编译,我知道堆缓冲区溢出发生在 printf("%s\n", buf);

但我不知道为什么会这样。我尝试使用 STDIN 修复它,但没有成功。有人可以检查一下吗?

  1. 您没有用空字符终止 buf

    *buf = '\n';
    *buf = '[=10=]';
    

    确保在为 buf.

    分配内存时为 null 字符保留 space
  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  = '[=13=]';  
        printf("%s\n", buf);
    
        return startAddress;
    }