Robert C. Seacord在卡内基梅隆大学的软件工程研究所(SEI)的CERT小组倡导安全编码活动,在分析过去10年近18000份漏洞报告后,发现少量的根本原因产生了多数安全漏洞。根据这些原因,Robert C. Seacord制定了CERT C和CERT C++的标准。CERT C和CERT C++分别是用于C语言和C++语言软件开发的安全编码指南,它们都是由CERT社区开发,由卡内基梅隆大学负责运营,这些标准是对过去20多年记录的软件漏洞案例研究的结果,与CWE有很大的重叠。为了使用静态分析的方式对代码进行自动检测,2009年成立的WG14研究小组(从2006年开始促进CERT C的进展),在ISO/IEC C语言标准的C11版本基础上,研究出一套为C语言制定的可静态分析的安全编码指南,发布了ISO/IEC TS 17961:信息技术 编程语言及其环境和系统软件接口-C安全编码规则技术规范(2013)。标准中规定了45条在工业软件编程中要遵守的C语言安全编码规则,主要规则有:错误的内存使用、数组越界、污染数据未净化使用等比较严重的问题,这些问题的出现会引起嵌入式软件的崩溃。标准中还说明了如何使用静态分析技术保证规则的实现,同时强调了降低静态分析误漏报的重要性,并提供了一些简单的静态分析思路,它是CERT C的一套子集。

ISO17961共支持45条,库博静态代码分析工具可以完全支持所有的条目检测,帮助您极大提升编码安全规范检测的效率。

ISO17961具体括如下条目:

CERT-5.01 通过一个指向不兼容类型的指针来访问对象

CERT-5.02 访问已释放内存

CERT-5.03 在信号量处理方法中访问共享对象,需加锁访问

CERT-5.04 条件表达式中不能有赋值语句

CERT-5.05 在信号量处理函数中调用了除abort、_Exit、signal以外的库函数

CERT-5.06 带有不正确参数的函数调用

CERT-5.07 通过可能被中断的信号处理函数来调用signal方法

CERT-5.08 调用system方法

CERT-5.09 对填充数据进行比较

CERT-5.10 整型和指针之间的相互转换

CERT-5.11 将指针变量转换为更加严格对齐的指针类型

CERT-5.12 复制文件对象

CERT-5.13 通过不兼容的方式声明了同一方法或对象

CERT-5.14 空指针解引用

CERT-5.15 返回自动存储对象的地址,延长了对象的生命周期

CERT-5.16 将signed char转换成更大范围的整型类型时,需要先检查EOF

CERT-5.17 在switch语句中使用了隐式的缺省语句

CERT-5.18 当不再需要的时候,未能关闭文件或释放动态内存

CERT-5.19 未能检测和处理标准库的错误

CERT-5.20 通过库函数形成了无效的指针

CERT-5.21 数组越界

CERT-5.22 多次释放内存

CERT-5.23 污染数据或外部输入用于格式化字符串

CERT-5.24 不正确地设置和使用errno

CERT-5.25 除零错误

CERT-5.26 输出流和输入流之间没有fflush或者函数调用

CERT-5.27 修改字符串常量

CERT-5.28 修改函数getenv,localeconv,setlocale,strerror调用返回的字符串

CERT-5.29 signed溢出

CERT-5.30 没有结束符的字符串传递给库函数

CERT-5.31 传递到字符处理功能函数的参数不是unsigned char的兼容类型

CERT-5.32 将同一对象的指针传递到应该有不同参数的函数中

CERT-5.33 再次分配或者释放不是动态分配的内存

CERT-5.34 未初始化的内存被使用

CERT-5.35 对不指向同一个数组的指针进行减法或比较

CERT-5.36 污染数据传递给字符串拷贝函数

CERT-5.37 采用指针的大小来确定所指向的输入[sizeofptr]的大小

CERT-5.38 污染数据传递不合适的函数指针

CERT-5.39 污染数据传递给格式化输入输出

CERT-5.40 fsetpos的变量不是从fgetpos中获得的

CERT-5.41 重写getenv,localeconv,setlocale,strerror返回对象

CERT-5.42 使用从EOF区分字符值

CERT-5.43 使用保留的关键字

CERT-5.44 使用无效的格式字符串

CERT-5.45 污染数据,残缺数据,外部输入用于有限制的数据源

重点条目举例:

如在ISO17961中,条目“CERT-5.16 将signed char转换成更大范围的整型类型时,需要先检查EOF”其缺陷详解为:将signed char转换成更大范围的整型类型时,容易造成混淆,应该使用 int 变量进行比较或者需要先检查EOF。

错误例子:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int yy_string_get(char *c_str)

{

    int c = EOF;

    if (c_str && *c_str)

    {

        c = *c_str++;   // if char is signed, a 0xFF char can be confused with EOF

    }

    return c;

}

/*...*/

int main(void)

{

    char string[BUFSIZ];

    scanf("%s\n", string);

    if (yy_string_get(string) == EOF)   // diagnostic required

    {

        /*...*/

    }

    return 0;

}

错误例子解释:在第(19)行声明了[char [512]]类型数组[string]。在第(11)行将有符号[char]类型字符[*c_str]赋值给[int]类型变量[c],出现有符号字符转换为更大范围的整型类型,没有先检查EOF。

正确例子:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

int yy_string_get(int *c_str)

{

    int c = EOF;

    if (c_str && *c_str)

    {

        c = *c_str++;   // if char is signed, a 0xFF char can be confused with EOF

    }

    return c;

}

/*...*/

int main(void)

{

    int string[BUFSIZ];

    scanf("%d\n", string);

    if (yy_string_get(string) == EOF)   // diagnostic required

    {

        /*...*/

    }

    return 0;

}

正确例子解释:在第(19)行将数组[string]改为[int]类型。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐