Home > database >  Possible stack smashing?
Possible stack smashing?

Time:04-24

I was looking at the following example in a book, and it seems to me that it will cause stack smashing:

int read_line(char str[], int n)
{
    int ch, i = 0;

    while ((ch = getchar()) != '\n')
        if (i < n)
            str[i  ] = ch;
    str[i] = '\0';
    return i;
}

If I pass it an array with room for 10 chars, and n = 10, the if-statement will be true up to and including 9, and i will be incremented to 10. Then, it will write the '\0' character at str[10] which would be just past the end of the array?

It works just fine, though (tried building with gcc on Linux, clang on Mac and VS on Windows). VS on Windows is the only one showing an error when running the program, even though I have tried setting -fstack-protector in e.g. clang.

CodePudding user response:

Your assessment is correct, the code has undefined behavior if the user types n or more bytes before the newline. There is also a problem if the end of file is encountered before the end of the line: the function will then run an infinite loop.

Here is a corrected version:

#include <stdio.h>

int read_line(char str[], int n) {
    int ch, i = 0;

    while ((ch = getchar()) != EOF && ch != '\n') {
        if (i   1 < n)
            str[i] = ch;
        i  ;
    }
    if (n > 0) {
        str[i < n ? i : n - 1] = '\0';
    }
    if (i == 0 && ch == EOF) {
        /* end of file: no input */
        return -1;
    } else {
        /* return the complete line length, excluding the newline */
        return i;
    }
}

int main() {
    char buf[50];
    int count = read_line(buf, sizeof buf);

    if (count < 0) {
        printf("Empty file\n");
    } else
    if (count >= sizeof buf) {
        printf("Line was truncated: %s\n", buf);
    } else {
        printf("Read %d bytes: %s\n", count, buf);
    }
    return 0;
}
  •  Tags:  
  • c
  • Related