【问题标题】:Preventing char pointer overflow in struct防止结构中的字符指针溢出
【发布时间】:2016-07-13 16:13:48
【问题描述】:

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

【问题讨论】:

  • 如果你想要一个带有全功能范围检查的软垫舞台教练,你绝对不应该使用 C。例如,如果用户更改指针怎么办?
  • 习惯上在 struct 的末尾定义一个绝对巨大的数组以供您的 lib 使用,并让用户管理它的实际分配并传入一个指针和“真实”大小。您保持灵活性,不会浪费任何实际空间。当然不能直接复制struct!
  • 安全?它是 C - 你已经没有安全性了:)

标签: c struct buffer-overflow


【解决方案1】:

您的库的用户从哪里获取 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 数组以便由函数处理。我希望我解释得足够好......
【解决方案2】:

把大数组放在最后..

struct struct1 {
    anyType thisVar;
    someType anotherVar
    size_t str_length;
    char str[10240000]; /
}

让用户将其分配到他们想要的任何“真实”大小。如果他们设置 'str_length' 错误,那么,无论你做什么,你都无能为力:(

【讨论】:

  • 但是,在这种情况下,用户仍然可以通过传递错误的 str_length 值来溢出缓冲区。我认为你是对的,没有一个简单的解决方案:(
猜你喜欢
  • 1970-01-01
  • 2011-02-17
  • 1970-01-01
  • 2022-11-25
  • 2020-03-23
  • 2012-07-31
  • 2016-12-30
  • 2021-07-12
  • 1970-01-01
相关资源
最近更新 更多