[英]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.