深入分析图形渲染库精度问题引发的安全漏洞(上篇)
字数 1257 2025-08-20 18:17:42
图形渲染库精度问题引发的安全漏洞深入分析
1. 精度问题漏洞概述
精度问题漏洞是一种罕见但危险的漏洞类型,主要影响图形渲染库,偶尔也会出现在其他软件中。这类漏洞的根本原因是精度误差导致应用程序的安全假设失效,转而使用有限精度算法。
1.1 与整数溢出的对比
- 整数溢出:运算结果太大而无法以给定精度准确表示
- 精度问题漏洞:运算结果或结果的一部分太小而无法以给定精度准确表示
1.2 典型示例
float a = 100000000;
float b = 1;
float c = a + b; // 实际结果为100000000而非100000001
2. SwiftShader中的精度问题
2.1 背景介绍
SwiftShader是OpenGL ES和Direct3D 9图形API的CPU实现,Chrome浏览器将其作为备选渲染库。
2.2 漏洞代码分析
// 纹理复制循环中的问题代码
float w = sRect.width() / dRect.width();
float h = sRect.height() / dRect.height();
const float xStart = sRect.x0 + 0.5f * w;
float y = sRect.y0 + 0.5f * h;
float x = xStart;
for(int j = dRect.y0; j < dRect.y1; j++) {
x = xStart;
for(int i = dRect.x0; i < dRect.x1; i++) {
dest->copyInternal(source, i, j, x, y, options.filter);
x += w; // 迭代加法导致误差累积
}
y += h;
}
2.3 问题本质
- 迭代加法导致误差累积传播,像滚雪球一样越来越大
- 乘法实现误差更小且稳定,与操作数大小成正比
2.4 具体数值示例
当源宽度与目标宽度比为5828:8132时:
- 前2046次迭代结果相同
- 从2047次开始出现误差
- 最终导致越界索引(8131次迭代时差值足够大)
3. Skia中的精度问题
3.1 背景介绍
Skia是Chrome、Firefox和Android使用的图形库,用于绘制canvas元素和SVG图像。
3.2 剪辑检查机制
Skia采用三级剪辑检查策略:
- 完全在绘图区域外:不绘制,立即返回
- 部分在绘图区域内:绘制并进行逐像素剪辑检查
- 完全在绘图区域内:直接绘制,不进行逐像素检查
3.3 主要精度问题
3.3.1 浮点到整数转换误差
// 问题函数1
static inline int round_down_to_int(SkScalar x) {
double xx = x;
xx -= 0.5;
return (int)ceil(xx);
}
// 问题函数2
inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0) {
// 使用magic number进行转换
double magic = (1LL << (52 - (fractionalBits))) * 1.5;
tmp.fDouble = SkScalarToDouble(x) + magic;
return tmp.fBits[0];
}
对于-0.499:
round_down_to_int返回0(通过检查)SkScalarRoundToFDot6返回-32(对应-0.5)
3.3.2 分数相乘误差
static inline SkFixed(SkFixed a, SkFixed b) {
return (SkFixed)((int64_t)a * b >> 16); // 右移导致负数相乘问题
}
示例:
- 预期:0xFFFFFFFE × 0xFFFFFFFE = 0xFFFFFFFC00000004 → 0xFFFFFFFC
- 实际:0xFFFFFFFF(更大的结果)
3.4 组合利用
结合两个问题可以:
- 使x坐标足够小(<-0.5)
- 通过舍入操作变为整数时,尝试在x=-1处绘制
- 导致越界写入漏洞
4. 防御建议
4.1 通用防御措施
- 避免迭代累积误差:使用乘法而非迭代加法
- 增加安全余量:在边界检查中使用更大的安全余量
- 统一精度处理:确保所有转换使用相同算法
4.2 SwiftShader特定建议
- 重构纹理复制循环,使用乘法计算坐标
- 对关键计算进行最大误差分析
- 限制纹理大小以减小误差影响范围
4.3 Skia特定建议
- 在所有路径上启用逐像素剪辑检查
- 统一浮点到整数转换算法
- 修复SkFixedMul中的负数处理问题
5. 总结
图形渲染库中的精度问题可能导致严重的安全漏洞,特别是越界读写问题。这些问题通常源于:
- 迭代计算导致的误差累积
- 不同精度转换算法的不一致性
- 边界检查中的安全余量不足
开发者需要特别注意图形计算中的精度处理,特别是在安全敏感的上下文中。通过采用更精确的算法、统一转换方法和适当的边界检查,可以显著降低这类漏洞的风险。