linux sparse 内核代码静态检查

Sparse简介


Sparse诞生于2004年,是由Linux之父开发的,目的就是提供一个静态检查代码的工具,从而减少Linux内核的隐患。起始,在Sparse之前已经有了一个不错的代码静态检查工具(SWAT),只不过这个工具不是免费软件,使用上有一些限制。所以Linus自己开发了一个静态检查工具。

内核代码中有一个对Sparse的简略说明文档:Documentation/sparse.txt。

Sparse通过gcc的扩展属性__attribute__以及自己定义的__context__来对代码进行静态检查。

这些属性如下:

宏名称宏定义说明
__bitwise__attribute__((bitwise))确保变量是相同的位方式(比如 bit-endian, little-endiandeng)
__user__attribute__((noderef, address_space(1)))指针地址必须在用户地址空间
__kernel__attribute__((noderef, address_space(0)))指针地址必须在内核地址空间
__iomem__attribute__((noderef, address_space(2)))指针地址必须在设备地址空间
__safe__attribute__((safe))变量可以为空
__force__attribute__((force))变量可以进行强制转换
__nocast__attribute__((nocast))参数类型与实际参数类型必须一致
__acquires(x)__attribute__((context(x, 0, 1)))参数x 在执行前引用计数必须是0,执行后,引用计数必须为1
__releases__attribute__((context(x, 1, 0)))与__acquires(x)相反
__acquire__context__(x, 1)参数x的引用计数+1
__release__context__(x, 1)与__acquire(x)相反
__cond_lock(x,c)((c) ? ({ __acquire(x); 1; }) : 0)参数c 不为0时,引用计数 + 1, 并返回1

其中__acquires(x)和__releases,__acquire和__release必须配对使用,否则Sparse会发出警告

 

下载安装


可以在 https://www.kernel.org/pub/software/devel/sparse/dist/ 下载sparse的版本,

解压后,make make install

 

Sparse使用方法


__bitwise

主要作用就是确保内核使用的整数是在同样的位方式下。对于使用了这个宏的变量,Sparse会检查这个变量是否一直在同一种位方式(big-endian,little-endian或其他)下被使用。如果此变量在多个位方式下被使用了,Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:include/linux/types.h line:158 */
typedef unsigned __bitwise__ fmode_t;

__user

如果使用了__user宏的指针不在用户地址空间初始化,或者指向内核地址空间、设备地址空间等,Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:kernel/ldt.c line:153 */
static int read_ldt(void __user *ptr, unsigned long bytecount)

__kernel

如果使用了__kernel宏的指针不在内核地址空间初始化,或者指向用户地址空间、设备地址空间等,Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:drivers/s390/char/hmcdrv_ftp.h line:52 */
void __kernel *buf;

__iomem

如果使用了__iomem宏的指针不在设备地址空间初始化,或者指向用户地址空间、内核地址空间等,Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:kernel/apic/io_apic.c line:461 */
struct io_apic __iomem *io_apic;

__safe

如果使用了__safe宏修饰的变量在使用前没有判断它是否为空(NULL),Sparse会给出警告。
最新的gcc应该已经会对这种情况给出警告,所以没有必要用Sparse去检查。

__force

如果使用了__force修饰的变量可以进行强制类型转换,没有使用__force修饰的变量进行强制类型转换时,Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:include/asm/io.h line:213 */
memset((void __force *)addr, val, count);

__nocast

如果使用了__nocast修饰的参数必须和实际传入的参数类型一致才可以,否则Sparse会给出警告。

/* kernel version:4.6.2 */
/* file:include/asm-generic/cputime_nsecs.h line:21 */
typedef u64 __nocast cputime_t;

z__acquires __releases__acquire __release

这4个宏都是和锁有关的,__acquires和__releases、__acquire和__release必须成对使用,否则Sparse会警告。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值