防止结构中的char指针溢出

时间:2016-03-25 20:52:49

标签: c struct buffer-overflow

我有一个函数接受包含敏感数据(在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 模型,但我不确定它是否是安全方面的好选择。

2 个答案:

答案 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;
};