我有一个函数接受包含敏感数据(在struct *
数组中)的char
指针作为参数(一种小型库)。
两个struct
模型如下:
struct struct1 {
char str[1024]; /* maybe even 4096 or 10KB+ */
size_t str_length;
}
struct struct2 {
char *str;
size_t str_length;
}
测试功能是:
/* Read str_length bytes from the char array. */
void foo(struct struct1/struct2 *s) {
int i;
for (i = 0; i < s->str_length; i++) {
printf("%c\n", s->str[i]);
}
}
我担心的是,由于 str_length 参数是一个任意值,可以故意将其设置为导致缓冲区溢出(实际上有人愚蠢到故意在自己的程序中创建安全漏洞,但我觉得我必须考虑这些情况)。但是,通过使用 struct1 模型,我只需使用以下命令检查可能的缓冲区溢出:
if (s->str_length > sizeof(s->str)) {
/* ERROR */
}
问题是长度数组在编译时实际上是未知。所以我不知道是否使用char *
指针( struct2 样式,因此没有溢出检查)或定义一个非常大的数组( struct1 ),会限制最大长度(我想避免的东西),并且会在大部分时间分配不必要的空间(这可能会在内存稀少的嵌入式系统中出现问题,我想)。我知道我必须做出妥协,我个人会使用 struct2 模型,但我不确定它是否是安全方面的好选择。
答案 0 :(得分:0)
把大阵列放在最后......
struct struct1 {
anyType thisVar;
someType anotherVar
size_t str_length;
char str[10240000]; /
}
让用户将其按照他们希望的“真实”尺寸进行游戏。如果他们设置'str_length'错了,那么无论你做什么,你都无法做到这一点:(
答案 1 :(得分:0)
你的库的用户从哪里获取struct2实例传递给函数?我不认为他是自己创建它然后将它的地址传递给你的函数,这将是一种传递参数的奇怪方法。它很可能是从库中的另一个函数返回的,在这种情况下,你可以使struct2成为一个不透明的数据类型,用户不能直接改变(或者只能用hacky方式):
/* in the header file */
typedef struct2_s struct2;
/* in the implementation file, where allocation is handled as well
* so you know str_length is set to the proper value.
*/
struct struct2_s {
char *str;
size_t str_length;
};