Skip to content

C 安全函数与安全编程

C 提供的部分传统库函数存在缓冲区溢出等风险。本章总结常见不安全用法、改进方式与通用安全实践。

1. 避免的函数与替代

  • gets:已被移除,使用 fgets
  • strcpy/strcat:可能溢出,考虑 strncpy/strncatsnprintf 组合(注意 strncpy 不保证结尾 \0)。
  • sprintf:可能溢出,使用 snprintf
  • scanf 读取字符串时使用宽度限制:%31s

示例:

c
char buf[32];
snprintf(buf, sizeof buf, "%s-%d", "id", 42);

2. 输入校验与边界检查

  • 对外部输入做范围与格式校验(strtolstrtod)。
  • 文件与网络 I/O 检查返回值,处理部分读写。

3. 格式化字符串安全

  • printf(fmt, ...)fmt 不可由不可信输入直接提供,防止格式化字符串漏洞。
  • 使用 "%s" 明确输出字符串:printf("%s", user_input);

4. 内存安全

  • 分配前检查大小是否溢出;分配后检查返回值。
  • 使用 memmove 处理可能重叠的内存区域。
  • 释放后指针置 NULL,避免悬空。

5. 其他建议

  • 使用最小权限原则与最小暴露接口。
  • 编译时开启更多告警,进行静态/动态分析。
  • 对敏感数据内存进行显式清理(注意编译器优化,可用 volatile 或专用清理 API)。

6. 小结

通过选择更安全的函数变体、系统的输入校验与内存管理习惯,可以显著降低 C 程序的安全风险。

本站内容仅供学习和研究使用。