使用潜在危险函数¶
ID: cpp/potentially-dangerous-function
Kind: problem
Security severity: 10.0
Severity: warning
Precision: medium
Tags:
- reliability
- security
- external/cwe/cwe-676
Query suites:
- cpp-security-extended.qls
- cpp-security-and-quality.qls
此规则查找对使用危险的函数的调用。目前,它会检查对 gmtime
、localtime
、ctime
和 asctime
的调用。
诸如 gmtime
之类的与时间相关的函数会将数据填充到共享内存中的 tm
结构或 char
数组中,然后返回指向该内存的指针。如果从同一程序中的多个位置调用该函数,尤其是从同一程序中的多个线程调用该函数,则这些调用会覆盖彼此的数据。
建议¶
将对 gmtime
的调用替换为 gmtime_r
。使用 gmtime_r
,应用程序代码管理 tm
结构的分配。这样,对该函数的单独调用可以使用其自己的存储。
类似地,将对 localtime
的调用替换为 localtime_r
,将对 ctime
的调用替换为 ctime_r
,并将对 asctime
的调用替换为 asctime_r
(如果您的平台上存在这些函数)。
示例¶
以下示例以两种方式检查本地时间
// BAD: using gmtime
int is_morning_bad() {
const time_t now_seconds = time(NULL);
struct tm *now = gmtime(&now_seconds);
return (now->tm_hour < 12);
}
// GOOD: using gmtime_r
int is_morning_good() {
const time_t now_seconds = time(NULL);
struct tm now;
gmtime_r(&now_seconds, &now);
return (now.tm_hour < 12);
}
第一个版本使用 gmtime
,因此它容易受到其他线程覆盖其数据的影响。即使此代码现在不在多线程上下文中使用,将来的更改也可能使程序变为多线程。代码的第二个版本使用 gmtime_r
。因为它在每次调用时都会分配一个新的 tm
结构,所以它不会受到对 gmtime
或 gmtime_r
的其他调用的影响。
参考文献¶
SEI CERT C 编码标准:CON33-C. 避免在使用库函数时出现竞争条件。
常见弱点枚举:CWE-676。