aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/spectre-meltdown-checker-externalize-fwdb.patch
blob: cce70b880f553b0591d0714f23949366f8ac9980 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
From 340b08737e552c3c186863d76d123808d853a159 Mon Sep 17 00:00:00 2001
From: Hilton Chain <hako@ultrarare.space>
Date: Sat, 12 Nov 2022 22:45:24 +0800
Subject: [PATCH] Replace fwdb downloader with a local file option.

Also warn about non-free software.
---
 spectre-meltdown-checker.sh | 180 +++---------------------------------
 1 file changed, 15 insertions(+), 165 deletions(-)

diff --git a/spectre-meltdown-checker.sh b/spectre-meltdown-checker.sh
index 30f760c..ce46970 100755
--- a/spectre-meltdown-checker.sh
+++ b/spectre-meltdown-checker.sh
@@ -22,8 +22,6 @@ exit_cleanup()
 	[ -n "${dumped_config:-}" ] && [ -f "$dumped_config" ] && rm -f "$dumped_config"
 	[ -n "${kerneltmp:-}"     ] && [ -f "$kerneltmp"     ] && rm -f "$kerneltmp"
 	[ -n "${kerneltmp2:-}"    ] && [ -f "$kerneltmp2"    ] && rm -f "$kerneltmp2"
-	[ -n "${mcedb_tmp:-}"     ] && [ -f "$mcedb_tmp"     ] && rm -f "$mcedb_tmp"
-	[ -n "${intel_tmp:-}"     ] && [ -d "$intel_tmp"     ] && rm -rf "$intel_tmp"
 	[ "${mounted_debugfs:-}" = 1 ] && umount /sys/kernel/debug 2>/dev/null
 	[ "${mounted_procfs:-}"  = 1 ] && umount "$procfs" 2>/dev/null
 	[ "${insmod_cpuid:-}"    = 1 ] && rmmod cpuid 2>/dev/null
@@ -93,9 +91,9 @@ show_usage()
 		--vmm [auto,yes,no]	override the detection of the presence of a hypervisor, default: auto
 		--allow-msr-write	allow probing for write-only MSRs, this might produce kernel logs or be blocked by your system
 		--cpu [#,all]		interact with CPUID and MSR of CPU core number #, or all (default: CPU core 0)
-		--update-fwdb		update our local copy of the CPU microcodes versions database (using the awesome
-					MCExtractor project and the Intel firmwares GitHub repository)
-		--update-builtin-fwdb	same as --update-fwdb but update builtin DB inside the script itself
+		--with-fwdb FILE	read CPU microcode version information from FILE
+		                        Note that most CPU microcode is distributed as binaries without source -- relying on
+		                        such non-free firmware as sole protection against security vulnerabilities is ill-advised.
 		--dump-mock-data	used to mimick a CPU on an other system, mainly used to help debugging this script
 
 	Return codes:
@@ -837,147 +833,6 @@ show_header()
 	_info
 }
 
-[ -z "$HOME" ] && HOME="$(getent passwd "$(whoami)" | cut -d: -f6)"
-mcedb_cache="$HOME/.mcedb"
-update_fwdb()
-{
-	show_header
-
-	set -e
-
-	if [ -r "$mcedb_cache" ]; then
-		previous_dbversion=$(awk '/^# %%% MCEDB / { print $4 }' "$mcedb_cache")
-	fi
-
-	# first, download the MCE.db from the excellent platomav's MCExtractor project
-	mcedb_tmp="$(mktemp -t smc-mcedb-XXXXXX)"
-	mcedb_url='https://github.com/platomav/MCExtractor/raw/master/MCE.db'
-	_info_nol "Fetching MCE.db from the MCExtractor project... "
-	if command -v wget >/dev/null 2>&1; then
-		wget -q "$mcedb_url" -O "$mcedb_tmp"; ret=$?
-	elif command -v curl >/dev/null 2>&1; then
-		curl -sL "$mcedb_url" -o "$mcedb_tmp"; ret=$?
-	elif command -v fetch >/dev/null 2>&1; then
-		fetch -q "$mcedb_url" -o "$mcedb_tmp"; ret=$?
-	else
-		echo ERROR "please install one of \`wget\`, \`curl\` of \`fetch\` programs"
-		return 1
-	fi
-	if [ "$ret" != 0 ]; then
-		echo ERROR "error $ret while downloading MCE.db"
-		return $ret
-	fi
-	echo DONE
-
-	# second, get the Intel firmwares from GitHub
-	intel_tmp="$(mktemp -d -t smc-intelfw-XXXXXX)"
-	intel_url="https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/archive/main.zip"
-	_info_nol "Fetching Intel firmwares... "
-	## https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git
-	if command -v wget >/dev/null 2>&1; then
-		wget -q "$intel_url" -O "$intel_tmp/fw.zip"; ret=$?
-	elif command -v curl >/dev/null 2>&1; then
-		curl -sL "$intel_url" -o "$intel_tmp/fw.zip"; ret=$?
-	elif command -v fetch >/dev/null 2>&1; then
-		fetch -q "$intel_url" -o "$intel_tmp/fw.zip"; ret=$?
-	else
-		echo ERROR "please install one of \`wget\`, \`curl\` of \`fetch\` programs"
-		return 1
-	fi
-	if [ "$ret" != 0 ]; then
-		echo ERROR "error $ret while downloading Intel firmwares"
-		return $ret
-	fi
-	echo DONE
-
-	# now extract MCEdb contents using sqlite
-	_info_nol "Extracting MCEdb data... "
-	if ! command -v sqlite3 >/dev/null 2>&1; then
-		echo ERROR "please install the \`sqlite3\` program"
-		return 1
-	fi
-	mcedb_revision=$(sqlite3 "$mcedb_tmp" "select revision from MCE")
-	if [ -z "$mcedb_revision" ]; then
-		echo ERROR "downloaded file seems invalid"
-		return 1
-	fi
-	sqlite3 "$mcedb_tmp" "alter table Intel add column origin text"
-	sqlite3 "$mcedb_tmp" "update Intel set origin='mce'"
-
-	echo OK "MCExtractor database revision $mcedb_revision"
-
-	# parse Intel firmwares to get their versions
-	_info_nol "Integrating Intel firmwares data to db... "
-	if ! command -v unzip >/dev/null 2>&1; then
-		echo ERROR "please install the \`unzip\` program"
-		return 1
-	fi
-	( cd "$intel_tmp" && unzip fw.zip >/dev/null; )
-	if ! [ -d "$intel_tmp/Intel-Linux-Processor-Microcode-Data-Files-main/intel-ucode" ]; then
-		echo ERROR "expected the 'intel-ucode' folder in the downloaded zip file"
-		return 1
-	fi
-
-	if ! command -v iucode_tool >/dev/null 2>&1; then
-		if ! command -v iucode-tool >/dev/null 2>&1; then
-			echo ERROR "please install the \`iucode-tool\` program"
-			return 1
-		else
-			iucode_tool="iucode-tool"
-		fi
-	else
-		iucode_tool="iucode_tool"
-	fi
-	#  079/001: sig 0x000106c2, pf_mask 0x01, 2009-04-10, rev 0x0217, size 5120
-	#  078/004: sig 0x000106ca, pf_mask 0x10, 2009-08-25, rev 0x0107, size 5120
-	$iucode_tool -l "$intel_tmp/Intel-Linux-Processor-Microcode-Data-Files-main/intel-ucode" | grep -wF sig | while read -r _line
-	do
-		_line=$(   echo "$_line" | tr -d ',')
-		_cpuid=$(  echo "$_line" | awk '{print $3}')
-		_cpuid=$(( _cpuid ))
-		_cpuid=$(printf "0x%08X" "$_cpuid")
-		_date=$(   echo "$_line" | awk '{print $6}' | tr -d '-')
-		_version=$(echo "$_line" | awk '{print $8}')
-		_version=$(( _version ))
-		_version=$(printf "0x%08X" "$_version")
-		_sqlstm="$(printf "INSERT INTO Intel (origin,cpuid,version,yyyymmdd) VALUES (\"%s\",\"%s\",\"%s\",\"%s\");" "intel" "$(printf "%08X" "$_cpuid")" "$(printf "%08X" "$_version")" "$_date")"
-		sqlite3 "$mcedb_tmp" "$_sqlstm"
-	done
-	_intel_timestamp=$(stat -c %Y "$intel_tmp/Intel-Linux-Processor-Microcode-Data-Files-main/license" 2>/dev/null)
-	if [ -n "$_intel_timestamp" ]; then
-		# use this date, it matches the last commit date
-		_intel_latest_date=$(date +%Y%m%d -d @"$_intel_timestamp")
-	else
-		echo "Falling back to the latest microcode date"
-		_intel_latest_date=$(sqlite3 "$mcedb_tmp" "SELECT yyyymmdd from Intel WHERE origin = 'intel' ORDER BY yyyymmdd DESC LIMIT 1;")
-	fi
-	echo DONE "(version $_intel_latest_date)"
-
-	dbversion="$mcedb_revision+i$_intel_latest_date"
-
-	if [ "$1" != builtin ] && [ -n "$previous_dbversion" ] && [ "$previous_dbversion" = "v$dbversion" ]; then
-		echo "We already have this version locally, no update needed"
-		return 0
-	fi
-
-	_info_nol "Building local database... "
-	{
-		echo "# Spectre & Meltdown Checker";
-		echo "# %%% MCEDB v$dbversion";
-		sqlite3 "$mcedb_tmp" "SELECT '# I,0x'||t1.cpuid||',0x'||MAX(t1.version)||','||t1.yyyymmdd FROM Intel AS t1 LEFT OUTER JOIN Intel AS t2 ON t2.cpuid=t1.cpuid AND t2.yyyymmdd > t1.yyyymmdd WHERE t2.yyyymmdd IS NULL GROUP BY t1.cpuid ORDER BY t1.cpuid ASC;" | grep -v '^# .,0x00000000,';
-		sqlite3 "$mcedb_tmp" "SELECT '# A,0x'||t1.cpuid||',0x'||MAX(t1.version)||','||t1.yyyymmdd FROM AMD   AS t1 LEFT OUTER JOIN AMD   AS t2 ON t2.cpuid=t1.cpuid AND t2.yyyymmdd > t1.yyyymmdd WHERE t2.yyyymmdd IS NULL GROUP BY t1.cpuid ORDER BY t1.cpuid ASC;" | grep -v '^# .,0x00000000,';
-	} > "$mcedb_cache"
-	echo DONE "(version $dbversion)"
-
-	if [ "$1" = builtin ]; then
-		newfile=$(mktemp -t smc-builtin-XXXXXX)
-		awk '/^# %%% MCEDB / { exit }; { print }' "$0" > "$newfile"
-		awk '{ if (NR>1) { print } }' "$mcedb_cache" >> "$newfile"
-		cat "$newfile" > "$0"
-		rm -f "$newfile"
-	fi
-}
-
 parse_opt_file()
 {
 	# parse_opt_file option_name option_value
@@ -1067,12 +922,15 @@ while [ -n "${1:-}" ]; do
 		# deprecated, kept for compatibility
 		opt_explain=0
 		shift
-	elif [ "$1" = "--update-fwdb" ] || [ "$1" = "--update-mcedb" ]; then
-		update_fwdb
-		exit $?
-	elif [ "$1" = "--update-builtin-fwdb" ] || [ "$1" = "--update-builtin-mcedb" ]; then
-		update_fwdb builtin
-		exit $?
+	elif [ "$1" = "--with-fwdb" ] || [ "$1" = "--with-mcedb" ]; then
+	        opt_fwdb=$2
+		if [ -f "$opt_fwdb" ]; then
+		        mcedb_cache=$2
+		else
+		        echo "$0: error: --with-fwdb should be a file, got '$opt_fwdb'" >&2
+		        exit 255
+		fi
+		shift 2
 	elif [ "$1" = "--dump-mock-data" ]; then
 		opt_mock=1
 		shift
@@ -2033,21 +1891,11 @@ is_xen_domU()
 	fi
 }
 
-builtin_dbversion=$(awk '/^# %%% MCEDB / { print $4 }' "$0")
 if [ -r "$mcedb_cache" ]; then
 	# we have a local cache file, but it might be older than the builtin version we have
 	local_dbversion=$(  awk '/^# %%% MCEDB / { print $4 }' "$mcedb_cache")
-	# sort -V sorts by version number
-	older_dbversion=$(printf "%b\n%b" "$local_dbversion" "$builtin_dbversion" | sort -V | head -n1)
-	if [ "$older_dbversion" = "$builtin_dbversion" ]; then
-		mcedb_source="$mcedb_cache"
-		mcedb_info="local firmwares DB $local_dbversion"
-	fi
-fi
-# if mcedb_source is not set, either we don't have a local cached db, or it is older than the builtin db
-if [ -z "${mcedb_source:-}" ]; then
-	mcedb_source="$0"
-	mcedb_info="builtin firmwares DB $builtin_dbversion"
+	mcedb_source="$mcedb_cache"
+	mcedb_info="local firmwares DB $local_dbversion"
 fi
 read_mcedb()
 {
@@ -2063,7 +1911,9 @@ is_latest_known_ucode()
 		return 2
 	fi
 	ucode_latest="latest microcode version for your CPU model is unknown"
-	if is_intel; then
+	if [ -z "$mcedb_source" ]; then
+	        return 2
+	elif is_intel; then
 		cpu_brand_prefix=I
 	elif is_amd; then
 		cpu_brand_prefix=A
-- 
2.38.1