前から存在だけ知っていたyoctoのcve-checkを実際に動かしてみる。
作業概要
yoctoのレイヤmeta-raspberrypiの最小構成でcve-checkを実施し、どのような結果が得られるか確認する。以下のページの「3.34 Checking for Vulnerabilities」 を参考に作業する。
https://docs.yoctoproject.org/dev-manual/common-tasks.html#checking-for-vulnerabilities
yoctoバージョンはkirkstoneで、ビルド環境はあらかじめ用意してあるものを使用する。
作業日は、2023/1/28。
作業手順
meta-raspberrypi用ソフトをダウンロードする。
$ mkdir yocto-cve-check-raspi $ cd yocto-cve-check-raspi $ git clone git://git.yoctoproject.org/poky -b kirkstone $ git clone https://github.com/agherzan/meta-raspberrypi.git -b kirkstone
環境設定を行う
以下のコマンドで環境を初期化する。
$ . poky/oe-init-build-env rpi-build
rpi-build/conf/bblayers.confを編集してmeta-raspberrypiを追加する。
BBLAYERS ?= " \ /home/user/yocto-cve-check-raspi/poky/meta \ /home/user/yocto-cve-check-raspi/poky/meta-poky \ /home/user/yocto-cve-check-raspi/poky/meta-yocto-bsp \ /home/user/yocto-cve-check-raspi/meta-raspberrypi \ "
rpi-build/conf/local.confを編集する。ターゲットとするボードを指定と、cve-checkの指定を行う。今回はラズパイ4の64bitを対象にする。
MACHINE = "raspberrypi4-64" INHERIT += "cve-check"
ビルド
ビルドを実行する。
$ bitbake core-image-minimal
結果確認
結果はrpi-build/tmp/deploy/cve/に格納されている。 参考にしたページと同様にflex-nativeの結果を見ると以下のようになっている。
LAYER: meta PACKAGE NAME: flex-native PACKAGE VERSION: 2.6.4 CVE: CVE-2016-6354 CVE STATUS: Patched CVE SUMMARY: Heap-based buffer overflow in the yy_get_next_buffer function in Flex before 2.6.1 might allow context-dependent attackers to cause a denial of service or possibly execute arbitrary code via vectors involving num_to_read. CVSS v2 BASE SCORE: 7.5 CVSS v3 BASE SCORE: 9.8 VECTOR: NETWORK MORE INFORMATION: https://nvd.nist.gov/vuln/detail/CVE-2016-6354 LAYER: meta PACKAGE NAME: flex-native PACKAGE VERSION: 2.6.4 CVE: CVE-2019-6293 CVE STATUS: Ignored CVE SUMMARY: An issue was discovered in the function mark_beginning_as_normal in nfa.c in flex 2.6.4. There is a stack exhaustion problem caused by the mark_beginning_as_normal function making recursive calls to itself in certain scenarios involving lots of '*' characters. Remote attackers could leverage this vulnerability to cause a denial-of-service. CVSS v2 BASE SCORE: 4.3 CVSS v3 BASE SCORE: 5.5 VECTOR: NETWORK MORE INFORMATION: https://nvd.nist.gov/vuln/detail/CVE-2019-6293
statusは以下を意味するようだ。
- Patched
セキュリティ問題を修正するパッチが適用されている。
- Unpatched
パッチが当たっておらず、調査が必要。
- Ignored
分析の結果、この問題を無視すると判断したもの。
また、ビルドしたイメージ全体に含まれるcve情報はrpi-build/tmp/deploy/images/raspberrypi-64/core-image-minimal-raspberrypi4-64.cveとして格納されている。
cve-checkの情報元は?
ではこのcve情報はどこから来ているのか?もちろん自動でアップデートはされるだろうが出所くらいは知っておきたい。
そこでcve-check.bbclassファイルを調べてみる。
cve-check.bbclass
ファイル内を見たところ以下でcheck_cves関数でデータベースを読んでいる。
import sqlite3 db_file = d.expand("file:${CVE_CHECK_DB_FILE}?mode=ro") conn = sqlite3.connect(db_file, uri=True)
ここで使用されている CVE_CHECK_DB_FILE は同ファイル内で以下のように定義されている。
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_1.1.db"
nvccve_1.1.dbがcve情報を格納したデータベースとなっていそうだ。 続けてこのファイルを取得する処理を探すと、cve-update-db-native.bbという、いかにもな名前のbbファイルを発見した。
cve-update-db-native.bb
このファイル内で以下の記述の通りデータベースのもととなるファイルを取得しているようだ。
NVDCVE_URL ?= "https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-" # CVE database update interval, in seconds. By default: once a day (24*60*60). # Use 0 to force the update # Use a negative value to skip the update CVE_DB_UPDATE_INTERVAL ?= "86400"
このNVDCVE_URLから以下のようにurlを組み立てデータをダウンロードしている。
year_url = (d.getVar('NVDCVE_URL')) + str(year) meta_url = year_url + ".meta" json_url = year_url + ".json.gz"
試しに、 https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2020.meta と https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-2020.json.gz をダウンロードしてみた。
nvcve-1.1-2022.metaはメタデータで以下の内容だった。
lastModifiedDate:2023-01-28T03:00:17-05:00 size:97658996 zipSize:5301183 gzSize:5301047 sha256:2D59A166D4C1A9E80AFB8F9B24A23AC0C9332195922115B65C3A27FC5F853A1C
nvdcve-1.1-2020.json.gzはcve情報を含む巨大なjsonファイルだった。
cve-update-db-native.bbではこのjsonファイルからデータを取得して内部のデータベースをアップデートしているようだ。
まとめ
yoctoのcve-checkを試し、cveの一覧を取得できた。
情報元のnvdcveは1日1回の更新らしいので、脆弱性情報は毎日確認して使用してるパッケージについての情報は見落とさないように通知する仕組みが必要そうだ。