SEI CERT C++ Coding Standard 学习及翻译计划
稍微说说
最近在网上浏览到卡内基梅隆大学 (CMU) 软件工程研究所 (SEI) 发布的安全编码规范。SEI CERT 的规则都是为了确保 C/C++ 编程开发软件系统的安全性、可靠性和稳固性,比如消除一些未定义行为或者可利用漏洞。大致浏览了一下,很多规则相对比较基础,有些规则相对比较隐晦,示例代码很丰富简洁明了,文后还有一些实际漏洞的案例介绍等。规范的内容组织得也非常清晰,一方面是学习一下安全编码,另一方面也作为平时积累和查漏补缺的过程。
在此,记录一下自己对这份规范的蹩脚翻译,保留了原文英文,以备后用。顺便也提升一下阅读英文技术手册的能力,为了打工恰饭。
更新目录
Rule 01. Declarations and Initialization (DCL) 声明和初始化 (DCL)
- DCL50-CPP. Do not define a C-style variadic function
 - DCL51-CPP. Do not declare or define a reserved identifier
 - DCL52-CPP. Never qualify a reference type with const or volatile
 - DCL53-CPP. Do not write syntactically ambiguous declarations
 - DCL54-CPP. Overload allocation and deallocation functions as a pair in the same scope
 - DCL55-CPP. Avoid information leakage when passing a class object across a trust boundary
 - DCL56-CPP. Avoid cycles during initialization of static objects
 - DCL57-CPP. Do not let exceptions escape from destructors or deallocation functions
 - DCL58-CPP. Do not modify the standard namespaces
 - DCL59-CPP. Do not define an unnamed namespace in a header file
 - DCL60-CPP. Obey the one-definition rule
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
Rule 02. Expressions (EXP) 表达式 (EXP)
- EXP50-CPP. Do not depend on the order of evaluation for side effects
 - EXP51-CPP. Do not delete an array through a pointer of the incorrect type
 - EXP52-CPP. Do not rely on side effects in unevaluated operands
 - EXP53-CPP. Do not read uninitialized memory
 - EXP54-CPP. Do not access an object outside of its lifetime
 - EXP55-CPP. Do not access a cv-qualified object through a cv-unqualified type
 - EXP56-CPP. Do not call a function with a mismatched language linkage
 - EXP57-CPP. Do not cast or delete pointers to incomplete classes
 - EXP58-CPP. Pass an object of the correct type to va_start
 - EXP59-CPP. Use offsetof() on valid types and members
 - EXP60-CPP. Do not pass a nonstandard-layout type object across execution boundaries
 - EXP61-CPP. A lambda object must not outlive any of its reference captured objects
 - EXP62-CPP. Do not access the bits of an object representation that are not part of the object’s value representation
 - EXP63-CPP. Do not rely on the value of a moved-from object
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
- EXP34-C. Do not dereference null pointers
 - EXP35-C. Do not modify objects with temporary lifetime
 - EXP36-C. Do not cast pointers into more strictly aligned pointer types
 - EXP37-C. Call functions with the correct number and type of arguments
 - EXP39-C. Do not access a variable through a pointer of an incompatible type
 - EXP42-C. Do not compare padding data
 - EXP45-C. Do not perform assignments in selection statements
 - EXP46-C. Do not use a bitwise operator with a Boolean-like operand
 - EXP47-C. Do not call va_arg with an argument of the incorrect type
 
Rule 03. Integers (INT) 整型 (INT)
The following rules from the SEI CERT C Coding Standard also apply in C++:
- INT30-C. Ensure that unsigned integer operations do not wrap
 - INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data
 - INT32-C. Ensure that operations on signed integers do not result in overflow
 - INT33-C. Ensure that division and remainder operations do not result in divide-by-zero errors
 - INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand
 - INT35-C. Use correct integer precisions
 - INT36-C. Converting a pointer to integer or integer to pointer
 
Rule 04. Containers (CTR) 容器 (CTR) —— 2020.06.24 完成
- CTR50-CPP. 保证容器索引和迭代器在有效范围内
 - CTR51-CPP. 使用有效的引用,指针,迭代器来引用容器的元素
 - CTR52-CPP. 确保库函数不要溢出
 - CTR53-CPP. 使用有效的迭代器范围
 - CTR54-CPP. 不要相减不是指向同一个容器的迭代器
 - CTR55-CPP. 不要使用对迭代器使用加法运算如果结果会溢出
 - CTR56-CPP. 不要在多态对象上使用指针运算
 - CTR57-CPP. 提供一个有效排序的谓词
 - CTR58-CPP. 谓词函数对象不应该是 mutable
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
Rule 05. Characters and Strings (STR) 字符和字符串 (STR) —— 2021.11.20 完成
- STR50-CPP. 确保有足够的空间来存储字符串的字符数据和空终终止符
 - STR51-CPP. 不用试图以空指针创建 str::string
 - STR52-CPP. 使用合法的引用, 指针和迭代器来引用 basic_string 的元素
 - STR53-CPP. 元素访问的范围检查
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
- STR30-C. Do not attempt to modify string literals
 - STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator
 - STR32-C. Do not pass a non-null-terminated character sequence to a library function that expects a string
 - STR34-C. Cast characters to unsigned char before converting to larger integer sizes
 - STR37-C. Arguments to character-handling functions must be representable as an unsigned char
 - STR38-C. Do not confuse narrow and wide character strings and functions
 
Rule 06. Memory Management (MEM) 内存分配 (MEM) —— 2021.11.16 完成
- MEM50-CPP. 不要访问被释放的内存
 - MEM51-CPP. 正确地释放动态分配的资源
 - MEM52-CPP. 检测并处理内存分配错误
 - MEM53-CPP. 不要访问被释放的内存
 - MEM54-CPP. 为 placement new 提供足够内存容量的正确对齐的指针
 - MEM55-CPP. 遵守替换动态内存管理的要求
 - MEM56-CPP. 不要在不相关的智能指针中存放一个已有所属的指针值
 - MEM57-CPP. 避免对超出默认对齐的对象使用默认 new 操作符
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
Rule 07. Input Output (FIO) 输入输出 (FIO)
The following rules from the SEI CERT C Coding Standard also apply in C++:
- FIO30-C. Exclude user input from format strings
 - FIO32-C. Do not perform operations on devices that are only appropriate for files
 - FIO34-C. Distinguish between characters read from a file and EOF or WEOF
 - FIO37-C. Do not assume that fgets() or fgetws() returns a nonempty string when successful
 - FIO38-C. Do not copy a FILE object
 - FIO39-C. Do not alternately input and output from a stream without an intervening flush or positioning call
 - FIO40-C. Reset strings on fgets() or fgetws() failure
 - FIO41-C. Do not call getc(), putc(), getwc(), or putwc() with a stream argument that has side effects
 - FIO42-C. Close files when they are no longer needed
 - FIO44-C. Only use values for fsetpos() that are returned from fgetpos()
 - FIO45-C. Avoid TOCTOU race conditions while accessing files
 - FIO46-C. Do not access a closed file
 - FIO47-C. Use valid format strings
 
Rule 08. Exceptions and Error Handling (ERR) 异常及错误处理 (ERR)
- ERR50-CPP. Do not abruptly terminate the program
 - ERR51-CPP. Handle all exceptions
 - ERR52-CPP. Do not use setjmp() or longjmp()
 - ERR53-CPP. Do not reference base classes or class data members in a constructor or destructor function-try-block handler
 - ERR54-CPP. Catch handlers should order their parameter types from most derived to least derived
 - ERR55-CPP. Honor exception specifications
 - ERR56-CPP. Guarantee exception safety
 - ERR57-CPP. Do not leak resources when handling exceptions
 - ERR58-CPP. Handle all exceptions thrown before main() begins executing
 - ERR59-CPP. Do not throw an exception across execution boundaries
 - ERR60-CPP. Exception objects must be nothrow copy constructible
 - ERR61-CPP. Catch exceptions by lvalue reference
 - ERR62-CPP. Detect errors when converting a string to a number
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
- ERR30-C. Set errno to zero before calling a library function known to set errno, and check errno only after the function returns a value indicating failure
 - ERR32-C. Do not rely on indeterminate values of errno
 - ERR33-C. Detect and handle standard library errors
 - ERR34-C. Detect errors when converting a string to a number
 
Rule 09. Object Oriented Programming (OOP) 面向对象编程 (OOP)
- OOP50-CPP. Do not invoke virtual functions from constructors or destructors
 - OOP51-CPP. Do not slice derived objects
 - OOP52-CPP. Do not delete a polymorphic object without a virtual destructor
 - OOP53-CPP. Write constructor member initializers in the canonical order
 - OOP54-CPP. Gracefully handle self-copy assignment
 - OOP55-CPP. Do not use pointer-to-member operators to access nonexistent members
 - OOP56-CPP. Honor replacement handler requirements
 - OOP57-CPP. Prefer special member functions and overloaded operators to C Standard Library functions
 - OOP58-CPP. Copy operations must not mutate the source object
 
Rule 10. Concurrency (CON) 并发 (CON)
- CON50-CPP. Do not destroy a mutex while it is locked
 - CON51-CPP. Ensure actively held locks are released on exceptional conditions
 - CON52-CPP. Prevent data races when accessing bit-fields from multiple threads
 - CON53-CPP. Avoid deadlock by locking in a predefined order
 - CON54-CPP. Wrap functions that can spuriously wake up in a loop
 - CON55-CPP. Preserve thread safety and liveness when using condition variables
 - CON56-CPP. Do not speculatively lock a non-recursive mutex that is already owned by the calling thread
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
Rule 49. Miscellaneous (MSC) 杂项 (MSC)
- MSC50-CPP. Do not use std::rand() for generating pseudorandom numbers
 - MSC51-CPP. Ensure your random number generator is properly seeded
 - MSC52-CPP. Value-returning functions must return a value from all exit paths
 - [MSC53-CPP. Do not return from a function declared [noreturn]]
 - MSC54-CPP. A signal handler must be a plain old function
 
The following rules from the SEI CERT C Coding Standard also apply in C++:
- MSC30-C. Do not use the rand() function for generating pseudorandom numbers
 - MSC32-C. Properly seed pseudorandom number generators
 - MSC33-C. Do not pass invalid data to the asctime() function
 - MSC37-C. Ensure that control never reaches the end of a non-void function
 - MSC38-C. Do not treat a predefined identifier as an object if it might only be implemented as a macro
 - MSC39-C. Do not call va_arg() on a va_list that has an indeterminate value
 - MSC40-C. Do not violate constraints
 - MSC41-C. Never hard code sensitive information
 - FLP30-C. Do not use floating-point variables as loop counters
 - FLP32-C. Prevent or detect domain and range errors in math functions
 - FLP34-C. Ensure that floating-point conversions are within range of the new type
 - FLP36-C. Preserve precision when converting integral values to floating-point type
 - FLP37-C. Do not use object representations to compare floating-point values
 - ENV30-C. Do not modify the object referenced by the return value of certain functions
 - ENV31-C. Do not rely on an environment pointer following an operation that may invalidate it
 - ENV32-C. All exit handlers must return normally
 - ENV33-C. Do not call system()
 - ENV34-C. Do not store pointers returned by certain functions
 - SIG31-C. Do not access shared objects in signal handlers
 - SIG34-C. Do not call signal() from within interruptible signal handlers
 - SIG35-C. Do not return from a computational exception signal handler
 - PRE30-C. Do not create a universal character name through concatenation
 - PRE31-C. Avoid side effects in arguments to unsafe macros
 - PRE32-C. Do not use preprocessor directives in invocations of function-like macros
 
关于 SEI CERT 规范
SEI CERT 的规则都是为了确保 C/C++ 编程开发软件系统的安全性、可靠性和稳固性,比如消除一些未定义行为或者可利用漏洞。
C 和 C++ 各一份。他们同时还有其他语言的,比如 Java 、Android、Perl 的代码规范。这里主要自己写 C/C++,所以只关注这两份。相关信息可以移步到研究所维护的公开 wiki 主页。他们也会定期发布出版物,C/C++ 就是下面这两本,最新的都是 2016 v1 版本,官方主页有有下载通道。
SEI CERT C Coding Standard: Rules for Developing Safe, Reliable, and Secure SystemsSEI CERT C++ Coding Standard: Rules for Developing Safe, Reliable, and Secure Systems
关于安全编码规范,目前全球比较受认可的还有汽车工业软件可靠性协会的 MISRA C 和 MISRA C++,前者最新为 2012 版,后者最新为 2008 版。相对来说 SEI CERT C 和 SEI CERT C++ 主页维护还很活跃,一直在更新。
SEI CERT C++ Coding Standard 中总共有 11 条规则,每条规则分别由标题、描述、不合规代码示例、合规方案、风险评估及其他一些实际案例、参考文献等组成。这 11 条规则分别是:
- Rule 01. Declarations and Initialization (DCL) 声明和初始化 (DCL)
 - Rule 02. Expressions (EXP) 表达式 (EXP)
 - Rule 03. Integers (INT) 整型 (INT)
 - Rule 04. Containers (CTR) 容器 (CTR)
 - Rule 05. Characters and Strings (STR) 字符和字符串 (STR)
 - Rule 06. Memory Management (MEM) 内存分配 (MEM)
 - Rule 07. Input Output (FIO) 输入输出 (FIO)
 - Rule 08. Exceptions and Error Handling (ERR) 异常及错误处理 (ERR)
 - Rule 09. Object Oriented Programming (OOP) 面向对象编程 (OOP)
 - Rule 10. Concurrency (CON) 并发 (CON)
 - Rule 49. Miscellaneous (MSC) 杂项 (MSC)
 
关于这份规范的其他信息在主页也都已列出,其中How this Coding Standard Is Organized的需要看一下,能够知道编码标准如何组织的,有助于阅读。
- Usage
 - Tool Selection and Validation
 - System Qualities
 - Scope
 - Rules Versus Recommendations
 - Relation to the CERT C Coding Standard
 - Introduction
 - How this Coding Standard Is Organized
 - Government Regulations
 - Development Process
 - Conformance Testing
 - Automatically Generated Code
 - Automated Detection
 - Audience
 - Acknowledgments
 
本文标题:SEI CERT C++ Coding Standard 学习及翻译计划
文章作者:xwnb
发布时间:2020-06-24
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/3114312552/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享