gpt4 book ai didi

c - 仔细检查缓冲区的大小

转载 作者:行者123 更新时间:2023-11-30 15:19:29 25 4
gpt4 key购买 nike

我对我开发的库中潜在的缓冲区溢出有疑问,其中有以下 API 可以从外部应用程序调用。我试图找到一种可能的解决方案,但我还没有找到“正确”的解决方案。 API如下:

char* strftime_ISO8601(uint64_t ns, char* buf, size_t buflen) {
if (buf) {
//The standard format ISO 8601 is 20 bytes + 1 null
char datetime[21];
struct tm tm;
struct timespec ts = //convert nanoseconds into timespec

gmtime_r(&ts.tv_sec, &tm);
strftime(datetime, sizeof(datetime), "+%FT%T", &tm);
snprintf(buf, buflen, "%s.%.9ld", datetime, ts.tv_nsec);
}
return buf;
}

我需要提供足够安全的代码来防止“缓冲区溢出”。因此,我使用 snprintf,其中目标缓冲区的大小作为参数给出,并且生成的字符串以 NULL 结尾。我还使用一些静态分析工具(例如 RATS)来突出潜在的漏洞。在这种情况下,我有以下通知:

Double check that your buffer is as big as you specify. When using functions that accept a number n of bytes to copy, such as strncpy, be aware that if the destination buffer size = n it may not NULL-terminate the string.

关于 snprintf

snprintf(buf, buflen, "%s.%.9ld", datetime, ts.tv_nsec);

使用 snprintf 我确信该字符串将以 NULL 结尾,但是如何双重检查输入中给出的缓冲区的大小是否确实为 buflen?

我的意思是,如果用户使用错误的大小调用 API,例如:

...
char bad[5]
strftime_ISO8601(x, bad, 1024);
....

或者甚至最糟糕的是使用像这样的未初始化的缓冲区:

...
char *bad;
strftime_ISO8601(x, bad, 1024);
...

由于潜在的段错误,我在上述 API 中没有发现任何特定的漏洞。但是我如何验证 API 接收作为输入的 buflen 大小是否正确?

谢谢大家!

最佳答案

简单地说 - 你不能...
无法确定作为指针接收的内存地址的“长度”,因为没有实体可以在运行时验证它。这就是您首先要求长度的原因!

您的情况的唯一解决方案是您自己分配内存并将其返回给用户,将管理该内存的责任转移给用户:

char* strftime_ISO8601(uint64_t ns) {
//The standard format ISO 8601 is 20 bytes + 1 null
char datetime[21];
char *res = malloc(EXPECTED_SIZE)
struct tm tm;
struct timespec ts = //convert nanoseconds into timespec

gmtime_r(&ts.tv_sec, &tm);
strftime(datetime, sizeof(datetime), "+%FT%T", &tm);
snprintf(res, EXPECTED_SIZE, "%s.%.9ld", datetime, ts.tv_nsec);

return res;
}

这样,您就可以控制内存分配,从而防止缓冲区溢出

关于c - 仔细检查缓冲区的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30625357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com