在c中使用getline()从stdin读取不安全吗?

问题描述 投票:0回答:1

我知道不正确地使用

scanf()
来读取用户输入可能会导致程序中出现未定义的行为和潜在的安全漏洞。我看到很多人建议最好使用
fgets()
而不是
scanf()
,但我知道只要您尝试读取的行大于缓冲区,
getline()
就会自动重新分配。 我认为
getline()
不安全的唯一情况是,当用户向 stdin 发送太长的字符串时,它会尝试分配比操作系统更多的内存。我对此有点困惑。 这就是为什么人们似乎更喜欢
fgets()
而不是
getline()
或者与此无关?

我还没有在代码中尝试过这个。 我只是想听听有经验的人对此有何看法。

c memory io getline
1个回答
0
投票

这是一个示例程序:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>

int main() {
    char *lineptr = NULL;
    size_t n;
    ssize_t rv = getline(&lineptr, &n, stdin);
    if(rv == -1) perror("");
}

如果您按照以下方式向其发送 1 TB:

$ dd if=/dev/zero of=/dev/stdout bs=$((1024*1024)) count=$((1024*1024))| ./a.out
Killed

并且 dmesg 显示该程序由于内存不足而被杀死:

[855440.629377] Out of memory: Killed process 1387599 (a.out) total-vm:134252960kB, anon-rss:55714256kB, file-rss:1164kB, shmem-rss:0kB, UID:1000 pgtables:229544kB oom_score_adj:0

我在运行时正在播放 YouTube 视频,出现了一些音频故障,但没有观察到不良影响。

您可以使用 ulimit 来施加较小的限制:

$ ulimit -v $((1024*1024))
$ dd if=/dev/zero of=/dev/stdout bs=$((1024*1024)) count=$((1024*1024))| ./a.out 
Cannot allocate memory
© www.soinside.com 2019 - 2024. All rights reserved.