Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
CAN CSA ISO/IEC TR 24731-1-12 (2016) 是加拿大标准委员会(SCC)采纳的国际标准化组织/国际电工委员会技术报告(ISO/IEC TR 24731-1)的加拿大国家版本。该技术报告正式名称为 Information technology — Programming languages, their environments and system software interfaces — Extensions to the C library — Part 1: Bounds-checking interfaces,旨在为C语言标准库提供一组具有运行时边界检查功能的函数接口,以显著降低缓冲区溢出、字符串截断等常见内存安全漏洞的发生概率。
作为一份技术报告(TR),它并非强制性的国际标准,但为后来的ISO/IEC 9899:2011(C11)的Annex K提供了主要技术基础。加拿大标准CSA版本于2016年重新确认发布,明确了在加拿大国内推荐采用此技术规范,特别适用于安全关键系统、嵌入式开发以及需要遵循严格编码标准(如MISRA C)的工业领域。
适用范围:
__STDC_WANT_LIB_EXT1__ 宏以启用边界检查接口。_s 后缀结尾(如 strcpy_s、sprintf_s),并在检测到约束违规时会调用统一的约束处理函数,默认行为是触发运行时异常或调用用户安装的处理器,从而避免未定义行为的发生。 TR 24731-1 引入了 运行时约束违规(runtime-constraint violation)的概念。当安全函数检测到如下条件时将触发约束违规:
NULL);RSIZE_MAX;每个安全函数在执行其正常功能之前,必须首先检查这些约束。若违规发生,函数将:
set_constraint_handler_s 设置,默认由 abort_handler_s 或 ignore_handler_s 提供);errno_t 错误码。| 名称 | 类型/宏 | 说明 |
|---|---|---|
errno_t | int 类型 | 用于表示错误状态,成功返回0,失败返回非0。 |
rsize_t | size_t 等价类型 | 用于表示缓冲区大小的特殊类型,用于区分合法的size_t值。 |
RSIZE_MAX | 宏定义的常量 | 由实现定义的该类型最大值,任何大于此值的大小参数均被视为溢出。 |
constraint_handler_t | 函数指针类型 | 指向约束处理函数的指针,原型为 void (*)(const char *restrict msg, void *restrict ptr, errno_t error)。 |
| 传统函数 | 边界检查版本 | 附加参数 | 主要增强 |
|---|---|---|---|
strcpy | strcpy_s | 目标最大长度 (rsize_t) | 确保不超过目标大小,失败时将目标置空并返回错误码 |
strcat | strcat_s | 目标最大长度 (rsize_t) | 防止拼接后的结果超过目标缓冲区 |
sprintf | sprintf_s | 缓冲区长度 (rsize_t) | 自动截断并确保结尾空字符,返回-1表示错误 |
gets | gets_s | 缓冲区长度 (rsize_t) | 读取不超过指定长度的行,防止缓冲区溢出 |
memcpy | memcpy_s | 目标最大长度 (rsize_t) | 拷贝时检查目标空间是否足够 |
_s 函数与 C11 Annex K 中的同名函数在行为上存在细微差别(例如约束违规时是否清空目标缓冲区)。开发者不可假设所有平台行为完全一致,尤其在跨平台移植时必须查阅实现文档。 要使用这些安全函数,必须在任何包含标准头文件之前定义宏 __STDC_WANT_LIB_EXT1__ 为 1。例如:
#define __STDC_WANT_LIB_EXT1__ 1 #include <string.h> #include <stdio.h> 并非所有编译器都完全支持此TR。GCC/Clang 在严格模式(例如 -std=c11)下需要配合特定的 C 运行库(如 glibc 或 musl)的可选实现,而 MSVC 在 /std:c11 或 /std:c17 模式下已提供部分 Annex K 函数。建议先确认目标平台的支持程度。
默认约束处理函数(abort_handler_s)在违规时会导致程序终止,适合安全关键场景;对于非关键场景,可以安装 ignore_handler_s 或自定义处理函数(如记录日志后继续执行)。使用 set_constraint_handler_s 设置全局处理器:
set_constraint_handler_s(your_handler);
_s 函数时,绝对禁止 将约束处理函数设置为 ignore_handler_s 而不进行任何替代性错误处理。忽略约束违规将直接破坏函数的安全保证,等于放弃了机制本身。 RSIZE_MAX 可能不同,不可硬编码。CAN CSA ISO/IEC TR 24731-1-12 (2016) 与多项国际标准和技术文献密切相关:
_s 函数替代传统不安全函数,并结合静态分析工具实施。gets_s 的具体行为。编写跨平台兼容代码时,应同时考虑两者规定的子集,并充分测试。 __STDC_LIB_EXT1__ 宏,若未定义则准备回退方案。 本文撰写于2026年,内容基于CAN CSA ISO/IEC TR 24731-1-12 (2016) 官方文本及公开资料。实际实施时请以最新版本的合规文档为准。