Home > Software engineering >  Why am I getting heap-buffer-overflow in this C code?
Why am I getting heap-buffer-overflow in this C code?

Time:10-12

#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);
}

When I compile with no flags, I just get two empty line. Compiling with -fsanitize=address and I know heap-buffer-overflow happens at the line printf("%s\n", buf);

But I don't know why this happen. I tried STDIN to fix it but didn't work. Can someone check this please?

CodePudding user response:

  1. You are not terminating the buf with null character.

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

    Make sure you reserve the space for null character while allocating memory to buf.

  2. Free the memory if number of bytes read are less than 0.

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

    to

    if (nread < 0)  {
        free(startAddress);
        return (NULL);
    }
    
  3. You can have temporary pointer to preserve the starting address of buf instead of calculating the starting address.


    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;
    }
  • Related