0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux內(nèi)核代碼的靜態(tài)檢查

冬至子 ? 來(lái)源:linux與soc ? 作者:linux與soc ? 2023-06-05 14:50 ? 次閱讀

1.Sparse介紹

Linus在2004年開(kāi)發(fā)了kernel代碼靜態(tài)檢查工具,可以檢查出kernel中潛在的風(fēng)險(xiǎn)代碼,Sparse通過(guò) gcc 的擴(kuò)展屬性__attribute__ 以及自己定義的 __context__來(lái)對(duì)代碼進(jìn)行靜態(tài)檢查,重點(diǎn)檢查kernel代碼中的變量類(lèi)型和各類(lèi)鎖。

那么如何指定代碼可以被Sparse檢查的到呢?以__iomem為例,可以對(duì)需要檢查的變量類(lèi)型放到特定文件中,以__CHECKER__進(jìn)行限定即可。

#ifdef __CHECKER__
# define __user  __attribute__((noderef, address_space(1)))
# define __kernel __attribute__((address_space(0)))
# define __safe  __attribute__((safe))
# define __force __attribute__((force))
# define __nocast __attribute__((nocast))
# define __iomem __attribute__((noderef, address_space(2)))
# define __must_hold(x) __attribute__((context(x,1,1)))
# define __acquires(x) __attribute__((context(x,0,1)))
# define __releases(x) __attribute__((context(x,1,0)))
# define __acquire(x) __context__(x,1)
# define __release(x) __context__(x,-1)
# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
# define __percpu __attribute__((noderef, address_space(3)))
# define __rcu  __attribute__((noderef, address_space(4)))
# define __private __attribute__((noderef))
extern void __chk_user_ptr(const volatile void __user *);
extern void __chk_io_ptr(const volatile void __iomem *);
# define ACCESS_PRIVATE(p, member) (*((typeof((p)- >member) __force *) &(p)- >member))
#else /* __CHECKER__ */
# ifdef STRUCTLEAK_PLUGIN
#  define __user __attribute__((user))
# else
#  define __user
# endif
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
# define __builtin_warning(x, y...) (1)
# define __must_hold(x)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x,c) (c)
# define __percpu
# define __rcu
# define __private
# define ACCESS_PRIVATE(p, member) ((p)- >member)
#endif /* __CHECKER__ */

2. 安裝Sparse工具

通常來(lái)說(shuō),開(kāi)發(fā)環(huán)境中沒(méi)有Sparse工具,需要手動(dòng)安裝,否則報(bào)如下錯(cuò)誤:

ubuntu16@ubuntu16:linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 C=2
  CHECK   scripts/mod/empty.c
/bin/sh: 1: sparse: not found
scripts/Makefile.build:261: recipe for target 'scripts/mod/empty.o' failed
  1. 獲取Sparse代碼
ubuntu16@ubuntu16:~$ git clone git://git.kernel.org/pub/scm/devel/sparse/sparse.git
Cloning into 'sparse'...
remote: Enumerating objects: 17, done.
remote: Counting objects: 100% (17/17), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 20026 (delta 6), reused 0 (delta 0), pack-reused 20009
Receiving objects: 100% (20026/20026), 4.29 MiB | 924.00 KiB/s, done.
Resolving deltas: 100% (14035/14035), done.
Checking connectivity... done.
  1. 編譯Sparse
ubuntu16@ubuntu16:~$ cd sparse/
ubuntu16@ubuntu16:sparse$ make
Makefile:152: Your system does not have libxml, disabling c2xml
Makefile:170: Your system does not have sqlite3, disabling semind
Makefile:192: Your system does not have gtk3/gtk2, disabling test-inspect
Makefile:226: Your system does not have llvm, disabling sparse-llvm
  1. 安裝Sparse
ubuntu16@ubuntu16:sparse$ make install
Makefile:152: Your system does not have libxml, disabling c2xml
Makefile:170: Your system does not have sqlite3, disabling semind
Makefile:192: Your system does not have gtk3/gtk2, disabling test-inspect
Makefile:226: Your system does not have llvm, disabling sparse-llvm
INSTALL /home/ubuntu16/bin/sparse
INSTALL /home/ubuntu16/bin/cgcc
INSTALL /home/ubuntu16/share/man/man1/sparse.1
INSTALL /home/ubuntu16/share/man/man1/cgcc.1
ubuntu16@ubuntu16:sparse$

3.執(zhí)行Sparse靜態(tài)檢查

從kernel頂層Makefile中可以看出,當(dāng)編譯kernel時(shí)通過(guò)指定C=1C=2,可以調(diào)用到Sparse進(jìn)行代碼靜態(tài)檢查。

192 # Call a source code checker (by default, "sparse") as part of the
193 # C compilation.
194 #
195 # Use 'make C=1' to enable checking of only re-compiled files.
196 # Use 'make C=2' to enable checking of *all* source files, regardless
197 # of whether they are re-compiled or not.
198 #
199 # See the file "Documentation/dev-tools/sparse.rst" for more details,
200 # including where to get the "sparse" utility.

執(zhí)行結(jié)果:

ubuntu16@ubuntu16:linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 C=2
  CHECK   scripts/mod/empty.c
  CALL    scripts/atomic/check-atomics.sh
  CALL    scripts/checksyscalls.sh
  CHECK   arch/arm/vfp/vfpmodule.c
  CHECK   init/main.c
arch/arm/vfp/vfpmodule.c:38:17: warning: symbol 'vfp_vector' was not declared. Should it be static?
arch/arm/vfp/vfpmodule.c:56:17: warning: symbol 'vfp_current_hw_state' was not declared. Should it be static?
arch/arm/vfp/vfpmodule.c:323:6: warning: symbol 'VFP_bounce' was not declared. Should it be static?
arch/arm/vfp/vfpmodule.c:714:6: warning: symbol 'kernel_neon_begin' was not declared. Should it be static?
arch/arm/vfp/vfpmodule.c:745:6: warning: symbol 'kernel_neon_end' was not declared. Should it be static?
...
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    8966

    瀏覽量

    365007
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    315

    瀏覽量

    21556
  • gcc編譯器
    +關(guān)注

    關(guān)注

    0

    文章

    78

    瀏覽量

    3297
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux內(nèi)核代碼

    Linux內(nèi)核代碼本章講述在L i n u x內(nèi)核源碼中,應(yīng)該從何處開(kāi)始查找特定的內(nèi)核函數(shù)。本書(shū)并不要求讀者具有C語(yǔ)言編程能力,也不要求讀
    發(fā)表于 02-09 15:24 ?36次下載

    Linux內(nèi)核代碼漫游

    Linux內(nèi)核代碼漫游 本章試圖以順序的方式來(lái)解釋Linux代碼,以幫助讀者對(duì)源代碼的體系
    發(fā)表于 02-09 15:27 ?26次下載

    Linux 內(nèi)核代碼

    Linux 內(nèi)核代碼 實(shí)模式setup階段setup用于體系結(jié)構(gòu)相關(guān)的硬件初始化工作,在arch目錄中的各個(gè)系統(tǒng)結(jié)構(gòu)的平臺(tái)相關(guān)都有類(lèi)似功能的代碼。在32位的x86平臺(tái)中,s
    發(fā)表于 02-10 13:45 ?28次下載

    嵌入式LINUX內(nèi)核網(wǎng)絡(luò)棧(源代碼)

    本文選擇 LINUX-1.2.13 內(nèi)核所包含的網(wǎng)絡(luò)部分代碼分析(注意網(wǎng)絡(luò)部分代碼內(nèi)核代碼的演
    發(fā)表于 05-12 10:39 ?57次下載
    嵌入式<b class='flag-5'>LINUX</b><b class='flag-5'>內(nèi)核</b>網(wǎng)絡(luò)棧(源<b class='flag-5'>代碼</b>)

    Linux內(nèi)核代碼感悟

    直接訪問(wèn)校內(nèi)外的 lxr 網(wǎng)站)的。如果在 windows 下也可以用 source insight。以下的當(dāng)前路徑為內(nèi)核代碼路徑,通常為/usr/src/linux。內(nèi)核版本為 2
    發(fā)表于 09-11 17:01 ?18次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>代碼</b>感悟

    怎樣去讀Linux內(nèi)核代碼

    怎樣去讀Linux內(nèi)核代碼
    發(fā)表于 10-25 10:15 ?13次下載
    怎樣去讀<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>源<b class='flag-5'>代碼</b>

    Linux內(nèi)核配置系統(tǒng)詳解

    隨著 Linux 操作系統(tǒng)的廣泛應(yīng)用,特別是 Linux 在嵌入式領(lǐng)域的發(fā)展,越來(lái)越多的人開(kāi)始投身到 Linux 內(nèi)核級(jí)的開(kāi)發(fā)中。面對(duì)日益龐大的 L
    發(fā)表于 11-01 15:45 ?4次下載

    最硬核的Linux內(nèi)核文章

    內(nèi)核。 擁有超過(guò)1300萬(wàn)行的代碼,Linux內(nèi)核是世界上最大的開(kāi)源項(xiàng)目之一,但是內(nèi)核是什么,它用于什么? 02 什么是
    的頭像 發(fā)表于 10-19 17:46 ?2020次閱讀
    最硬核的<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>文章

    快速理解什么是Linux內(nèi)核以及Linux內(nèi)核的內(nèi)容

    01 前言 本文主要講解什么是Linux內(nèi)核,以及通過(guò)多張圖片展示Linux內(nèi)核的作用與功能,以便于讀者能快速理解什么是Linux
    的頭像 發(fā)表于 10-21 12:02 ?4143次閱讀
    快速理解什么是<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>以及<b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的內(nèi)容

    Linux內(nèi)核的源代碼漫游詳細(xì)資料說(shuō)明

    本章試圖以順序的方式來(lái)解釋 Linux代碼,以幫助讀者對(duì)源代碼的體系結(jié)構(gòu)以及很多相關(guān)的unix特性的實(shí)現(xiàn)有一個(gè)很好的理解。目標(biāo)是幫助對(duì) Linux不甚了解的有經(jīng)驗(yàn)的C程序員對(duì)整個(gè)
    發(fā)表于 01-15 17:40 ?15次下載

    關(guān)于Linux內(nèi)核代碼風(fēng)格

    從而導(dǎo)致的問(wèn)題。因?yàn)楫?dāng)時(shí)代碼量不大,所以解決問(wèn)題的時(shí)間相對(duì)較少。在代碼量增大的情況下可以借助工具進(jìn)行自動(dòng)修改。 快速修改編碼風(fēng)格的工具 scripts/checkpatch.pl 這是一個(gè)檢查patch是否符合
    的頭像 發(fā)表于 04-25 14:50 ?1691次閱讀

    Linux內(nèi)核代碼修改將為性能測(cè)試獲8450%提升

    Jason Donenfeld 是 WireGuard 的主要開(kāi)發(fā)者,同時(shí)他也是 Linux 內(nèi)核隨機(jī)數(shù)相關(guān)代碼的維護(hù)者,近日在他的領(lǐng)導(dǎo)下,Linux
    的頭像 發(fā)表于 03-09 14:16 ?1117次閱讀

    Linux內(nèi)核的編譯和運(yùn)行

    想讓Linux內(nèi)核代碼跑起來(lái),得先搭建編譯和運(yùn)行代碼的環(huán)境。
    發(fā)表于 06-23 11:56 ?1000次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>的編譯和運(yùn)行

    Linux內(nèi)核代碼60%都是驅(qū)動(dòng)?

    為什么Linux內(nèi)核代碼60%都是驅(qū)動(dòng)? 如果每支持新的設(shè)備就加入驅(qū)動(dòng),內(nèi)核會(huì)不會(huì)變得越來(lái)越臃腫?
    的頭像 發(fā)表于 07-11 11:48 ?727次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>代碼</b>60%都是驅(qū)動(dòng)?

    linux內(nèi)核代碼詳解

     在安裝好的Linux系統(tǒng)中,內(nèi)核的源代碼位于/ust/src/linux.如果是從GNU網(wǎng)站下載的Linux
    發(fā)表于 09-06 17:01 ?4次下載