如何更改此代码以使其不易受到算术溢出的影响?

问题描述

计算机系统:程序员的观点说:

1 /* Illustration of code vulnerability similar to that found in
2 * Sun’s XDR library.
3 */
4 void* copy_elements(void *ele_src[],int ele_cnt,size_t ele_size) {
5 /*
6 * Allocate buffer for ele_cnt objects,each of ele_size bytes
7 * and copy from locations designated by ele_src
8 */
9 void *result = malloc(ele_cnt * ele_size);
10 if (result == NULL)
11 /* malloc failed */
12 return NULL;
13 void *next = result;
14 int i;
15 for (i = 0; i < ele_cnt; i++) {
16 /* Copy object i to destination */
17 memcpy(next,ele_src[i],ele_size);
18 /* Move pointer to next memory region */
19 next += ele_size;
20 }
21 return result;
22 }

copy_elements函数旨在复制ele_cnt数据 结构,每个结构由ele_ size个字节组成,并分配给缓冲区 通过第9行上的函数。所需的字节数计算为 ele_cnt * ele_size。

但是,想象一下,一个恶意的程序员使用 ele_cnt是1,048,577(2 ^ 20 +1)和ele_size是4,096(2 ^ 12) 程序编译为32位。 然后在线进行乘法 9将溢出,导致仅分配4,096字节,而不是 保持这么多数据所需的4,294,971,392字节。循环 从第15行开始,将尝试复制所有这些字节, 超出分配的缓冲区的末尾,因此损坏 其他数据结构。这可能导致程序崩溃或 否则行为不正常。

我想知道如何将代码更改为由于算术溢出而没有漏洞?

谢谢。

解决方法

从数学角度来看,您要检查((?:\d\s*){5,11}\d?)。但是由于溢出,您无法在代码中执行此操作。您可以改用一些代数来避免溢出。您还想先检查两个值都为正:

(size_t)-1 < ele_cnt * ele_size

关于强制转换if ((ele_size == 0) || (ele_cnt <= 0) || ((size_t)-1 / ele_size < ele_cnt)) { return NULL; } ,因为(size_t)-1是无符号类型,所以转换定义得很好,并求值可以存储在size_t中的最大值。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...