簡體   English   中英

調整gets()以避免緩沖區溢出

[英]Tweaking gets() to avoid buffer overflow

我正在編寫一個小的C代碼以接受一些用戶輸入,這將是一個字符串。 現在,我在很多地方讀到,使用gets()將非常不安全,因為它可能導致緩沖區溢出攻擊。 在大多數地方,我找到的替代方法是使用fgets(),就緩沖區溢出而言,這更安全。

現在我有一個問題場景,在此之前我不知道緩沖區大小。 只是無法確定。 可能是任何東西。 因此,在這種情況下,fgets()會很方便嗎?

另外,如果我使用gets()來解決此問題,那是什么錯誤呢?

char * temp_buffer_to_hold_user_input = NULL;
cahr * actual_buffer_that_stores_user_input = NULL;
int length_of_user_input =0;

/* taking user input, irrespective of its length using gets() */

gets(temp_buffer_to_hold_user_input);

/* now finding the length of the user input string and allocating the required number of bytes for proper (safe) usage */

length_of_user_input=length(temp_buffer_to_hold_user_input);
actual_buffer_that_stores_user_input = (char*)malloc(length_of_user_input*sizeof(char));
strcpy(actual_buffer_that_stores_user_input, temp_buffer_to_hold_user_input);

/* and now we work with our actual buffer */

那么上述gets()的用法是否仍然存在緩沖區溢出問題? 因為,在上面我們根本沒有聲明一個固定大小的緩沖區...因此,沒有緩沖區溢出是我所期望的。

如果我錯過了某些東西,請糾正我!

char * temp_buffer_to_hold_user_input = NULL;

您將指針設置為NULL 因此,根本沒有緩沖區,並且gets將因未定義的行為而失敗(實際上可能是分段錯誤)。

gets要求您提供一個指向緩沖區的有效指針。 空指針不指向任何內容,因此不滿足該前提條件。 由於所有緩沖區的長度都是有限的,並且用戶輸入的長度是未知的,因此根本無法避免潛在的緩沖區溢出(更不用說安全風險了)。 它是如此糟糕, gets來自官方的標准中刪除

正確的方法是使用fgets 但是,處理可變大小的輸入非常棘手,因此您有兩個選擇:

  • fgets使用“我的所有情況都足夠大”的緩沖區大小。 簡單的出路。 最糟糕的情況是您會丟失一些輸入。
  • 重復使用fgets並連接到一些動態分配的數組(不要忘記根據需要調整該數組的大小!),直到到達定界符為止。 注意:不過,根據對字符串的處理方式,您甚至可能不需要保留整個內容,從而簡化了事情。

如果您不知道緩沖區的大小,可以看一下getline() ,或者構建自己的函數並重新realloc字符串,例如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char buf[8], *s = NULL, *p;
    size_t i = 0;

    while (fgets(buf, sizeof buf, stdin)) {
        if (i++ == 0) {
            s = malloc(sizeof buf);
            if (s == NULL) {
                perror("malloc");
                exit(EXIT_FAILURE);
            }
            strcpy(s, buf);
        } else {
            s = realloc(s, (i + 1) * sizeof(buf));
            if (s == NULL) {
                perror("realloc");
                exit(EXIT_FAILURE);
            }
            strcat(s, buf);
        }
        if ((p = strchr(s, '\n'))) {
            *p = '\0';
            break;
        }
    }
    printf("%s\n", s);
    free(s);
    return 0;
}

沒有中間緩沖區:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_LEN 8

int main(void)
{
    size_t len = BUF_LEN;
    char *s, *p;

    p = s = malloc(len);
    if (s == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    while (fgets(p, BUF_LEN, stdin)) {
        if ((p = strchr(p, '\n'))) {
            *p = '\0';
            break;
        } else {
            len += BUF_LEN - 1;
            s = realloc(s, len);
            if (s == NULL) {
                perror("realloc");
                exit(EXIT_FAILURE);
            }
            p = s + len - BUF_LEN;
        }
    }
    printf("%s\n", s);
    free(s);
    return 0;
}

調整gets()以避免緩沖區溢出

其他人已經解決了您體內的問題。 這是一個快速解答,用於解決標題中的問題。

標准C通過gets_s提供了gets的“更安全”的變體。 它已通過ISO / IEC TR 24731-1被添加到C標准中。 除其他外,TR 24731-1的安全功能檢查目標緩沖區的大小,以避免其“不安全”副本的許多緩沖區溢出問題。

來自文檔:

在此處輸入圖片說明

因此,您實際上不需要進行任何調整。 您只需要使用正確的功能即可;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM