# pti=on
# spec_store_bypass_disable=on
# l1tf=full,force
+# l1d_flush=on (a part of the l1tf option)
# mds=full,nosmt
# tsx=off
-# l1d_flush=on
# ARM64:
# kpti=on
# ssbd=force-on
def type(self):
return 'kconfig'
+ def json_dump(self, with_results):
+ dump = [self.name, self.type, self.expected, self.decision, self.reason]
+ if with_results:
+ dump.append(self.result)
+ return dump
+
class VersionCheck:
def __init__(self, ver_expected):
if with_results:
print('| {}'.format(self.result), end='')
+ def json_dump(self, with_results):
+ dump = self.opts[0].json_dump(False)
+ if with_results:
+ dump.append(self.result)
+ return dump
+
class OR(ComplexOptCheck):
# self.opts[0] is the option that this OR-check is about.
# 'cut_attack_surface', 'my'
l += [OR(KconfigCheck('cut_attack_surface', 'my', 'TRIM_UNUSED_KSYMS', 'y'),
modules_not_set)]
+ l += [KconfigCheck('cut_attack_surface', 'my', 'BPF_UNPRIV_DEFAULT_OFF', 'y')] # see kernel.unprivileged_bpf_disabled
l += [KconfigCheck('cut_attack_surface', 'my', 'MMIOTRACE', 'is not set')] # refers to LOCKDOWN (permissive)
l += [KconfigCheck('cut_attack_surface', 'my', 'LIVEPATCH', 'is not set')]
l += [KconfigCheck('cut_attack_surface', 'my', 'IP_DCCP', 'is not set')]
known_options = []
for o1 in checklist:
- if not hasattr(o1, 'opts'):
+ if o1.type != 'complex':
known_options.append(o1.name)
continue
for o2 in o1.opts:
- if not hasattr(o2, 'opts'):
+ if o2.type != 'complex':
if hasattr(o2, 'name'):
known_options.append(o2.name)
continue
for o3 in o2.opts:
- if hasattr(o3, 'opts'):
+ if o3.type == 'complex':
sys.exit('[!] ERROR: unexpected ComplexOptCheck inside {}'.format(o2.name))
if hasattr(o3, 'name'):
known_options.append(o3.name)
def print_checklist(mode, checklist, with_results):
if mode == 'json':
- opts = []
+ output = []
for o in checklist:
- opt = [o.name, o.type, o.expected, o.decision, o.reason]
- if with_results:
- opt.append(o.result)
- opts.append(opt)
- print(json.dumps(opts))
+ output.append(o.json_dump(with_results))
+ print(json.dumps(output))
return
# table header
def populate_simple_opt_with_data(opt, data, data_type):
- if hasattr(opt, 'opts'):
+ if opt.type == 'complex':
sys.exit('[!] ERROR: unexpected ComplexOptCheck {}: {}'.format(opt.name, vars(opt)))
if data_type not in TYPES_OF_CHECKS:
sys.exit('[!] ERROR: invalid data type "{}"'.format(data_type))
+
if data_type != opt.type:
return
+
if data_type == 'kconfig':
opt.state = data.get(opt.name, None)
elif data_type == 'version':
def populate_opt_with_data(opt, data, data_type):
- if hasattr(opt, 'opts'):
+ if opt.type == 'complex':
for o in opt.opts:
- if hasattr(o, 'opts'):
+ if o.type == 'complex':
# Recursion for nested ComplexOptCheck objects
populate_opt_with_data(o, data, data_type)
else:
populate_simple_opt_with_data(o, data, data_type)
else:
- # The 'state' is mandatory for simple checks
- if not hasattr(opt, 'state'):
- sys.exit('[!] ERROR: bad simple check {}'.format(vars(opt)))
+ if opt.type != 'kconfig':
+ sys.exit('[!] ERROR: bad type "{}" for a simple check {}'.format(opt.type, opt.name))
populate_simple_opt_with_data(opt, data, data_type)