c - 使 C 免受缓冲区溢出和其他错误影响的选项?

标签 c security buffer-overflow

是否有任何东西可以证明 C 不受缓冲区溢出的影响(编辑:以及由于 C 通常未经检查编译而产生的其他错误,即可能是某种边界检查)?并且还足够兼容以用于大型生产代码(编辑:用于所有内容)?

我用 mudflap 尝试了 gcc,它允许它运行而没有错误。

#include <stdio.h>
int main()
{
    int a[2];
    a[-1] = 5;
    printf("%u\n", a[-1]);
    return 0;
}

所以看起来 mudflap 和我试过的其他人一样不完整,只会降低利用的可能性。此外,它似乎旨在调试而不是生产用途。我想知道可证明的不可利用性。可以办到。关于为什么它没有被普遍使用的任何想法?轻微的性能损失(甚至慢 10 倍,但可能慢 2 倍)对于此类漏洞利用允许的数十亿甚至数万亿美元的损失来说似乎是一个很小的代价。

编辑:澄清:

所谓“缓冲区溢出”,我的意思不是程序员的代码允许溢出,而是编译器允许目标变量/数组/(m)allocblock 之外的内存由它写入(或读取)(例如:int a ,b; *(&b-1) 应该被编译器捕获而不仅仅是 a).

“证明”,我的意思是通俗地说,如“旧的简单 Pascal 不允许缓冲区溢出,我们可以说它已被证明的可能性接近 100%”,尽管它可能使用不安全的系统函数,如果它们也是用边界检查 Pascal 编写的,那么它们也不会有超限。我用“证明”这个词来区别于各种不完善的加固工具。

“可利用性”是指“缓冲区溢出可利用性”,这是一个简单的问题,在其他语言中以牺牲速度和内存为代价来解决。

“你是认真的吗?如果它存在,我们早就做了。” ——这就是我很好奇的地方。技术就在这里 - 胖指针(C 标准允许编译器将指针设为任意大小),每个指针都有完整的边界检查。但是我找不到关于它的概念证明、讨论和论文,而我想要的是一个完整的 C 编译器和一个用它构建的整个 Linux 发行版。没有人会很快用一种更安全的语言重写所有东西(Linux、Apache 等...)(遗憾的是他们一直在用 C 编写新东西),但我们可以使 C/C++ 更安全并重新编译所有东西。至少对于需要安全高于一切的用途而言。

最佳答案

这个问题有多种解决方案,基本上不用 C 语言。他们所做的主要是在一些运行时成本下跟踪“危险的”指针访问(静态分析无法证明是安全的)。

当然,您可能会争辩说,所有这些都是编译 C 的解决方案“已检查”,您似乎在问题中反对这一点。在最坏的情况下,我认为这些只是构建过程中的另一个步骤。

真正的问题是这些解决方案在时间和空间上都有可衡量的开销。在构建嵌入式系统时,这种额外成本表现为实际花费的美元,即购买更昂贵的处理器以在分配的时间内完成工作,和/或用于跟踪麻烦指针的额外内存。大多数制造商在发生不良程序的概率很低(或者更黑,“在我卖掉所有这些之前没人会注意到!”)和绝对实际的额外成本之间做出选择时,往往会优化成本,现在你是回到没有运行时检查的情况下编译原始 C 程序。 “便宜”妥协了“质量”或“进度”。我们在飞机座椅舒适度和软件安全方面看到了这一点。

关于c - 使 C 免受缓冲区溢出和其他错误影响的选项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26096166/

相关文章:

security - 在我的网站上使用 OpenID 作为身份验证方法是否存在任何安全风险?

c - 我如何绕过返回地址覆盖而不是重定向控制流?

c - sscanf 是否被认为可以安全使用?

c - 为什么我的 'reverse' 字符串 C 函数不起作用?

c - 在 LINUX 上的 C 中打开 O_NONBLOCKING

c - 如何在 C 中访问(动态分配的)Fortran 数组

c++ - 我如何理解我在 openMP 中的代码?

ios - 如何保护 NSUserDefaults 上的整数数据免遭黑客攻击?

php - CodeIgniter 授权安全模型

c - 缓冲区溢出错误和 Double 数据类型错误