Files
spectre-meltdown-checker/scripts/intel-affected-processor-list/test_inteldb.py
T
Stéphane Lesimple de4109f93f feat: tooling to generate the inteldb from trusted sources
The old Intel HTML and XSLX files contain historical data from EOL
processors that are no longer present in their Github repo. We merge
these 3 sources to generate our db.
2026-09-13 11:23:51 +00:00

153 lines
6.5 KiB
Python

"""Regression cases for processor identity and historical database updates."""
import csv
import io
import unittest
from unittest.mock import patch
from build_inteldb import build_history, merge_snapshot, parse_db
from parse_inteldb_csv import format_db, parse_csv, parse_cpuid_values
HYBRID = 'CPUID Hybrid Identification'
RFDS = 'Register File Data Sampling - CVE-2023-28746'
REPTAR = 'Reptar - CVE-2023-23583'
def csv_text(headers, rows):
stream = io.StringIO(newline='')
writer = csv.writer(stream)
writer.writerow(headers)
writer.writerows(rows)
return stream.getvalue()
def parse(headers, rows):
return parse_csv(io.StringIO(csv_text(headers, rows)))
class ParserTests(unittest.TestCase):
def test_explicit_identity_overrides_codename(self):
# Deliberately misleading names prove the explicit field wins.
entries = parse(['Code Name(s)', HYBRID, RFDS, 'CPUID'], [
['Catlow', 'CPUID.0x7.EDX[15]=1', 'MCU+Software', '90675'],
['Alder Lake S', 'CPUID.0x7.EDX[15]=0 - CPUID.0x1A.EAX[31:24]=40',
'Not Affected', '90675'],
])
self.assertEqual(entries[('0x00090675', 'H=1')]['2023-28746'], 'MS')
self.assertEqual(entries[('0x00090675', 'H=0')]['2023-28746'], 'N')
self.assertNotIn(('0x00090675', ''), entries)
def test_arizona_beach_and_alder_lake_u(self):
entries = parse(['CPUID', HYBRID, REPTAR], [
['906A4', 'CPUID.0x7.EDX[15]=0', 'Not Affected'],
['906A4', 'CPUID.0x7.EDX[15]=1', 'MCU'],
])
self.assertEqual(entries[('0x000906A4', 'H=0')]['2023-23583'], 'N')
self.assertEqual(entries[('0x000906A4', 'H=1')]['2023-23583'], 'M')
def test_single_and_identical_explicit_profiles_keep_qualifiers(self):
entries = parse(['CPUID', HYBRID, RFDS], [
['90672', 'CPUID.0x7.EDX[15]=1', 'MCU+Software'],
['90675', 'CPUID.0x7.EDX[15]=1', 'Not Affected'],
['90675', 'CPUID.0x7.EDX[15]=0', 'Not Affected'],
])
self.assertEqual(set(entries), {
('0x00090672', 'H=1'), ('0x00090675', 'H=0'), ('0x00090675', 'H=1'),
})
def test_na_does_not_infer_hybrid(self):
for value in ('NA', 'N/A', ''):
with self.subTest(value=value):
entries = parse(['CPUID', 'Code Name(s)', HYBRID, RFDS], [
['90675', 'Alder Lake S', value, 'Not Affected'],
])
self.assertEqual(set(entries), {('0x00090675', '')})
def test_legacy_inference(self):
entries = parse(['CPUID', 'Code Name(s)', RFDS], [
['90675', 'Alder Lake S', 'MCU+Software'],
['90675', 'Catlow', 'Not Affected'],
['306F2', 'Haswell', 'Not Affected'],
])
self.assertEqual(set(entries), {
('0x00090675', 'H=0'), ('0x00090675', 'H=1'), ('0x000306F2', ''),
})
def test_unknown_identity_and_truncated_rows_fail(self):
with self.assertRaisesRegex(ValueError, 'Hybrid Identification'):
parse(['CPUID', HYBRID, RFDS], [['90675', 'unknown', 'Not Affected']])
with self.assertRaisesRegex(ValueError, 'expected 3 columns'):
parse(['CPUID', HYBRID, RFDS], [['90675', 'NA']])
def test_platform_masks_are_not_cpuids(self):
self.assertEqual(parse_cpuid_values('806F5 - 806F8 (PID 0x87)'),
['0x000806F5', '0x000806F8'])
self.assertEqual(parse_cpuid_values('A06D1 (PID 0x00000095)'), ['0x000A06D1'])
def test_combined_cves_and_duplicate_columns(self):
entries = parse([
'CPUID', 'L1TF - CVE-2018-3615 - CVE-2018-3620 - CVE-2018-3646',
'ITS (IBPB) - CVE-2024-28956', 'ITS (Guest-Host) - CVE-2024-28956',
'ITS cBPF - CVE-2024-28956',
], [['90675', 'Not Affected', 'MCU', 'Software', 'Not Affected']])
self.assertEqual(entries[('0x00090675', '')], {
'2018-3615': 'N', '2018-3620': 'N', '2018-3646': 'N',
'2024-28956_IBPB': 'M', '2024-28956_GH': 'S', '2024-28956_cBPF': 'N',
})
def test_segment_and_core_type_rows_merge_conservatively(self):
entries = parse(['CPUID', HYBRID, 'Segment', RFDS], [
['B06E0', 'CPUID.0x7.EDX[15]=0 - CPUID.0x1A.EAX[31:24]=20',
'Embedded', 'MCU_BIOS+Software'],
['B06E0', 'CPUID.0x7.EDX[15]=0 - CPUID.0x1A.EAX[31:24]=40',
'Mobile', 'Not Affected'],
])
self.assertEqual(entries[('0x000B06E0', 'H=0')]['2023-28746'], 'MBS')
self.assertEqual(parse_db(io.StringIO(format_db(entries))), entries)
class HistoryTests(unittest.TestCase):
def test_new_snapshot_replaces_profiles_and_preserves_absent_cpus(self):
merged = {
('0x00090675', ''): {'2023-28746': 'N'},
('0x000306F2', ''): {'2023-28746': 'N'},
}
snapshot = {
('0x00090675', 'H=1'): {'2023-28746': 'MS'},
('0x00090675', 'H=0'): {'2023-28746': 'N'},
}
merge_snapshot(merged, snapshot)
self.assertNotIn(('0x00090675', ''), merged)
self.assertIn(('0x000306F2', ''), merged)
merge_snapshot(merged, {('0x00090675', ''): {'2023-28746': 'M'}})
self.assertNotIn(('0x00090675', 'H=0'), merged)
self.assertNotIn(('0x00090675', 'H=1'), merged)
def test_build_uses_git_order_not_hash_order_and_tip_last(self):
old = csv_text(['CPUID', RFDS], [['90675', 'Not Affected'], ['306F2', 'Not Affected']])
new = csv_text(['CPUID', HYBRID, RFDS], [['90675', 'CPUID.0x7.EDX[15]=1', 'MCU']])
tip = csv_text(['CPUID', HYBRID, RFDS], [['90675', 'CPUID.0x7.EDX[15]=1', 'MCU+Software']])
with patch('build_inteldb.git', side_effect=[
'tip\n', 'false\n', 'ffff\naaaa\n', old, new, tip,
]) as run_git:
entries, revision = build_history('repo')
self.assertEqual(revision, 'tip')
self.assertEqual(entries[('0x00090675', 'H=1')]['2023-28746'], 'MS')
self.assertNotIn(('0x00090675', ''), entries)
self.assertIn(('0x000306F2', ''), entries)
self.assertEqual([call.args[2] for call in run_git.call_args_list[3:]], [
'ffff:Intel_affected_processor_list.csv',
'aaaa:Intel_affected_processor_list.csv',
'tip:Intel_affected_processor_list.csv',
])
def test_shallow_clone_rejected(self):
with patch('build_inteldb.git', side_effect=['tip\n', 'true\n']):
with self.assertRaisesRegex(ValueError, 'shallow'):
build_history('repo')
if __name__ == '__main__':
unittest.main()