1

我已阅读grep 中的以下漏洞报告以及相关的提交,其中所有integerunsigned integer都替换为size_t.

我有一个简单的问题:是unsigned integer通过size_t避免数字溢出来替换(或其他类型的攻击?如果是为什么?(实际上我没有看到它发生了什么变化,因为我相信size_twas的定义typedef unsigned int size_t;)。

4

4 回答 4

4

size_t 可能在您的系统上被类型定义为 unsigned int,但在其他系统上可能不是这样,特别是嵌入式(非 X86)系统。根据 ANSI 标准,unsigned int 可以小到 16 位。

size_t 在每个系统上定义,以保证足够大以提供该系统上任何可能对象的大小。

在这个漏洞的情况下,我猜 (unsigned int) -> (size_t) 实际上并不是修复的一部分,至少在 X86 系统上,而是相关清理的一部分,以确保没有问题仍然存在。

这也是一种很好的编程习惯。

于 2013-02-27T19:31:22.683 回答
1

unsigned integer永不溢出。它不能。无符号类型的算术是使用模算术完成的。所以不,替换unsigned integer不会size_t不会避免任何溢出,因为首先没有任何溢出可以避免unsigned int

作为对一些评论的回应,我的意思是标准在将“整数溢出”描述为未定义行为时使用“溢出”的方式中的“溢出”。例如,当标准声明“未定义行为的一个例子是整数溢出行为”时。这并不是说当值不能适合数据类型时,无符号整数会导致未定义的行为。此外,该标准还说:

涉及无符号操作数的计算永远不会溢出,因为无法由结果无符号整数类型表示的结果会以比结果类型可以表示的最大值大一的数字为模减少

(第 6.2.5 节,第 9 段)

于 2013-02-27T19:26:21.370 回答
1

size_t 是一种能够以字节表示任何对象大小的类型: size_t 是 sizeof 运算符返回的类型,在标准库中广泛用于表示大小和计数。

因此, size_t ia 总是能够正确地表示大小,并且在这个意义上永远不会溢出。

此外, size_t 可能比 unsigned int 更大、相等甚至更小,并且您的编译器可能会出于优化目的对其进行假设。因此, size_t 和 unsigned int 是不同的。

于 2013-02-27T19:30:34.207 回答
1

size_t 可以比 int 更大(并且在大多数 64 位机器上),并且 size_t 是表示大小/长度的正确类型。

该补丁将 unsigned int 更改为 size_t 以避免可能出现的问题,即可用内存多于 unsigned int 和 int 中可存储的内存。如果有足够的内存可用,两者都会换行/溢出。尽管包装 int 可能会给您带来负面结果,但比包装未签名的结果更致命(容易崩溃)。

所以似乎真正的问题是包装一个 int ,给你负面的结果,使得可以在应该可能的范围之外索引内存 - 修复它只使用一个 unsigned int - 你也可以将它全部更改为使用更多正确的 size_t。

于 2013-02-27T19:42:35.550 回答