防止结构中的字符指针溢出
Preventing char pointer overflow in struct
我有一个函数接受包含敏感数据(在 char
数组中)的 struct *
指针作为参数(类似于小型库)。
两个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),这会限制最大长度(这是我想避免的)并且大多数时候会分配不必要的 space(我想这在内存不足的嵌入式系统中可能会出现问题)。我知道我必须做出妥协,我个人会使用 struct2 模型,但我不确定它是否是安全方面的好选择。
把大数组放在最后..
struct struct1 {
anyType thisVar;
someType anotherVar
size_t str_length;
char str[10240000]; /
}
让用户将其 malloc 到他们想要的任何 'real' 大小。如果他们设置 'str_length' 错误,那么,无论您做什么,您都无能为力:(
您的库的用户从哪里获取要传递给函数的 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;
};
我有一个函数接受包含敏感数据(在 char
数组中)的 struct *
指针作为参数(类似于小型库)。
两个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),这会限制最大长度(这是我想避免的)并且大多数时候会分配不必要的 space(我想这在内存不足的嵌入式系统中可能会出现问题)。我知道我必须做出妥协,我个人会使用 struct2 模型,但我不确定它是否是安全方面的好选择。
把大数组放在最后..
struct struct1 {
anyType thisVar;
someType anotherVar
size_t str_length;
char str[10240000]; /
}
让用户将其 malloc 到他们想要的任何 'real' 大小。如果他们设置 'str_length' 错误,那么,无论您做什么,您都无能为力:(
您的库的用户从哪里获取要传递给函数的 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;
};