简体   繁体   中英

C prompt being overwritten

I'm new to C and I encountered a weird problem.

This code is part of a bigger program, but the problem is within here but I can't seem to figure it out.

#include <stdio.h>
#include <string.h>
#define WORDSIZE 512

int read_stdNum(const char prompt[], char store[], size_t n) {
    char inHold[WORDSIZE];
    char process[10];
    int status = 0;

    while (1) {
        fprintf(stderr, "%s", prompt);

        if(fgets(inHold, WORDSIZE, stdin) == NULL) {
            return 0;
        }

        sscanf(inHold, "%s", process);

        status = sscanf(process, "%s", store);

        if (status > 0 && strlen(store) == n) {
            return 1;
        } else if (status == -1) {
            continue;
        } else {
            continue;
        }
    }
}

int main(void) {
    char arrow[] = "\n==> ";
    char stdNum[10];

    printf("%s\n", "store_student called.");

    fprintf(stderr, "%s", "\nEnter a student number (axxxxxxxx)\n");
    read_stdNum(arrow, stdNum, 9);
    return 0;
}

The program asks for user input, and the test here is for the program to truncate the extra digits, but when I type something like " a123456789101112131415 ", the output is nothing, which works fine, but then the prompt gets over written and the prompt looks like this:

==> a123456789101112131415
131415_

The underscore is where I can still enter in input. The the character array 'process' is also storing more than 9 characters. I've asked some of my classmates, and also one of them said that it worked fine on his computer. I know I'm going to get flamed for being dumb but I really want to know why this is not working. Thanks.

scanf function with " %s " may be unsafe and create buffer overflow (it may write more bytes into output string than the space allocated for the string, overwriting some useful data), check https://cwe.mitre.org/data/definitions/120.html "CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')" & example 1

https://en.wikipedia.org/wiki/Scanf_format_string#Vulnerabilities

This means that uses of %s placeholders without length specifiers are inherently insecure and exploitable for buffer overflows.

Documentation of scanf has some requirements about s format usage (array must be long enough) http://man7.org/linux/man-pages/man3/scanf.3.html

  s Matches a sequence of non-white-space characters; the next pointer must be a pointer to the initial element of a character array that is long enough to hold the input sequence and the terminating null byte ('\\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first. 

The safer usage of scanf-like functions is to use "maximum field width" like %9s or m for dynamic memory allocation.

(Your check with strlen is too late; sscanf already did the overflow/overwrite of string because it had no limit on length to read.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM