qidao123.com技术社区-IT企服评测·应用市场

标题: 《C和C++安全编码》课程条记——第五章 整数安全 [打印本页]

作者: 雁过留声    时间: 2025-5-15 00:10
标题: 《C和C++安全编码》课程条记——第五章 整数安全
一、整数安全导论

整数安全的核心抵牾在于:

典型问题场景:
隐式转换陷阱:
  1. int a = -1;
  2. unsigned b = a; // 转为4294967295(32位系统)
复制代码
未定义行为:
  1. int a = INT_MAX;
  2. int b = a + 1;
复制代码

 
二、整数数据类型

类型体系对比

类型范围(32位)风险点int-2³¹ ~ 2³¹-1溢出为UBunsigned0 ~ 2³²-1回绕(0-1=UINT_MAX)char实现定义符号性需显式声明signed/unsigned 特性有符号类型无符号类型表树模围-2^(n-1) ~ 2^(n-1)-10 ~ 2^n-1溢出行为未定义行为(UB)明白定义的回绕典型用途通用计算、错误码位操作、数组索引零值扩展符号位扩展零扩展 关键特性


  1. size_t len = sizeof(arr);
  2. ptrdiff_t diff = p2 - p1;
复制代码


 
三、整数转换 

转换规则(转换优先级)

  1. int a = -5;   
  2. unsigned b = 10;   
  3. long c = a + b; // a转为UINT_MAX-4,结果可能非预期
复制代码
 
隐式转换风险矩阵

转换方向潜在风险示例有符号→无符号负值变极大正值int(-1) → unsigned(4294967295)宽类型→窄类型高位截断long(0x12345678) → short(0x5678)浮点→整数未定义行为(UB)int x = 1e30;
  1. unsigned char a = 0xFF;   // 255   
  2. unsigned char b = 0x01;   // 1
  3.    
  4. // 情况1:直接比较(无提升)   
  5. if (a < b) {              // 比较的是 255 < 1 → false
  6.     // 不会执行   
  7. }
  8.    
  9. // 情况2:提升为 int 后比较   
  10. if ((int)a < (int)b) {    // 比较的是 255 < 1 → false(和情况1一样)
  11.     // 不会执行   
  12. }
  13.    
  14. // 情况3:危险的情况(涉及有符号和无符号混合运算)   
  15. signed char c = -1;       // -1(有符号)   
  16. if (a < c) {              // 提升为 int 后比较:255 < -1 → false(但可能不符合预期)
  17.     // 不会执行   
  18. }
复制代码
  1. unsigned char a = 0xFF;   // 255   
  2. signed char b = -1;       // -1
  3.    
  4. // 开发者可能误以为比较的是 (unsigned char)-1 == 255   
  5. if (a < b) {  
  6.     printf("a < b\n");    // 不会执行,因为实际比较的是 255 < -1(false)   
  7. } else {
  8.     printf("a >= b\n");   // 会执行   
  9. }
  10.    
  11. // 如果确实想比较回绕后的值,应该显式转换:   
  12. if (a < (unsigned char)b) {  // 比较 255 < 255 → false
  13.     printf("a < (unsigned char)b\n");
  14. }
复制代码
 

 
四、整数操作 

安全范式

  1. _Bool safe_add(int a, int b, int *res) {
  2.     if ((b > 0 && a > INT_MAX - b) ||
  3.         (b < 0 && a < INT_MIN - b)) {
  4.         return 0;
  5.     }
  6.     *res = a + b;
  7.     return 1;
  8. }
复制代码
操作安全检测方法伤害案例加法if (a > INT_MAX - b) /*溢出*/INT_MAX + 1(UB)乘法if (a > INT_MAX / b) /*溢出*/INT_MIN * -1(UB)移位右操作数必须∈[0,类型宽度-1]1 << 32(UB)除法检查除零和INT_MIN/-1INT_MIN / -1(UB)  
汇编级检测



 
五、整数毛病 

毛病模式

 
真实案例


六、缓解策略

防御技能栈

层级措施代码层面使用安全库(如<stdckdint.h>)编译层面-ftrapv(有符号溢出陷阱)运行时ASLR、边界检查器硬件MPU内存保护单位
 
安全编码清单

  1. int a = -5;   
  2. unsigned b = 10;   
  3. long c = a + b; // a转为UINT_MAX-4,结果可能非预期
复制代码
回绕检测:
  1. if (UINT_MAX - a < b) { }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4