hardening: Introducing hardenconfig tool

Basic tool to help checking Kconfig options against a list of
hardening preferences.

This tool is available as a kconfig target, so to run it:

make/ninja hardenconfig

[Flavio Ceolin: Simplify logic and fix python lint issues]

Signed-off-by: Lauren Murphy <lauren.murphy@intel.com>
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
This commit is contained in:
Lauren Murphy 2019-10-28 11:28:40 -05:00 committed by Anas Nashif
commit e0b2fb75db
3 changed files with 165 additions and 0 deletions

View file

@ -65,9 +65,14 @@ set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_guiconfig
${ZEPHYR_BASE}/scripts/kconfig/guiconfig.py
)
set(EXTRA_KCONFIG_TARGET_COMMAND_FOR_hardenconfig
${ZEPHYR_BASE}/scripts/kconfig/hardenconfig.py
)
foreach(kconfig_target
menuconfig
guiconfig
hardenconfig
${EXTRA_KCONFIG_TARGETS}
)
add_custom_target(

79
scripts/kconfig/hardenconfig.py Executable file
View file

@ -0,0 +1,79 @@
#!/usr/bin/env python3
# Copyright (c) 2019 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import csv
import os
from kconfiglib import standard_kconfig
def hardenconfig(kconf):
kconf.load_config()
hardened_kconf_filename = os.path.join(os.environ['ZEPHYR_BASE'],
'scripts', 'kconfig', 'hardened.csv')
options = compare_with_hardened_conf(kconf, hardened_kconf_filename)
display_results(options)
class Option:
def __init__(self, name, recommended, current=None, symbol=None):
self.name = name
self.recommended = recommended
self.current = current
self.symbol = symbol
if current is None:
self.result = 'NA'
elif recommended == current:
self.result = 'PASS'
else:
self.result = 'FAIL'
def compare_with_hardened_conf(kconf, hardened_kconf_filename):
options = []
with open(hardened_kconf_filename) as csvfile:
csvreader = csv.reader(csvfile)
for row in csvreader:
name = row[0]
recommended = row[1]
try:
symbol = kconf.syms[name]
current = symbol.str_value
except KeyError:
symbol = None
current = None
options.append(Option(name=name, current=current,
recommended=recommended, symbol=symbol))
return options
def display_results(options):
# header
print('{:^50}|{:^13}|{:^20}'.format('name', 'current', 'recommended'), end='')
print('||{:^28}\n'.format('check result'), end='')
print('=' * 116)
# results, only printing options that have failed for now. It simplify the readability.
# TODO: add command line option to show all results
for opt in options:
if opt.result == 'FAIL' and opt.symbol.visibility != 0:
print('CONFIG_{:<43}|{:^13}|{:^20}'.format(
opt.name, opt.current, opt.recommended), end='')
print('||{:^28}\n'.format(opt.result), end='')
print()
def main():
hardenconfig(standard_kconfig())
if __name__ == '__main__':
main()

View file

@ -0,0 +1,81 @@
HW_STACK_PROTECTION,y
INIT_STACKS,n
KERNEL_DEBUG,n
BOOT_BANNER,n
BOOT_DELAY,0
EXECUTION_BENCHMARKING,n
THREAD_MONITOR,n
THREAD_NAME,n
STACK_CANARIES,y
EXECUTE_XOR_WRITE,y
STACK_POINTER_RANDOM,100
BOUNDS_CHECK_BYPASS_MITIGATION,y
PERFORMANCE_METRICS,n
STATS,n
DEBUG,n
TRACING,n
STACK_USAGE,n
PRINTK,n
EARLY_CONSOLE,n
ASSERT,n
OBJECT_TRACING,n
OVERRIDE_FRAME_POINTER_DEFAULT,y
DEBUG_INFO,n
OPENOCD_SUPPORT,n
TRACING_CPU_STATS,n
TRACING_CTF,n
USE_SEGGER_RTT,n
LOG,n
SHELL,n
TEST_RANDOM_GENERATOR,n
ZTEST,n
TEST,n
TEST_SHELL,n
TEST_EXTRA_STACKSIZE,0
TEST_USERSPACE,n
CUSTOM_RODATA_LD,n
CUSTOM_RWDATA_LD,n
CUSTOM_SECTIONS_LD,n
BUILD_OUTPUT_STRIPPED,y
SOC_ATMEL_SAME70_DISABLE_ERASE_PIN,y
SOC_ATMEL_SAME70_WAIT_MODE,n
FAULT_DUMP,0
EXCEPTION_DEBUG,n
X86_MMU,y
BUILTIN_STACK_GUARD,y
MPU_STACK_GUARD,y
STACK_SENTINEL,y
BOOT_TIME_MEASUREMENT,n,experimental
BT_A2DP,n,experimental
BT_AVDTP,n,experimental
BT_BREDR,n,experimental
BT_H5,n,experimental,
BT_HFP_HF,n,experimental
BT_RFCOMM,n,experimental
CAN_NET,n,experimental
CONSOLE_SUBSYS,n,experimental
CRYPTO,n,experimental
CRYPTO_MBEDTLS_SHIM,n,experimental
CRYPTO_TINYCRYPT_SHIM,n,experimental
MODEM_CONTEXT,n,experimental
NET_BUF_VARIABLE_DATA_SIZE,n,experimental
NET_CONNECTION_MANAGER,n,experimental
NET_GPTP,n,experimental
NET_IPV4_AUTO,n,experimental
NET_L2_CANBUS,n,experimental
NET_L2_IEEE802154_SECURITY,n,experimental
NET_L2_PPP,n,experimental
NET_OFFLOAD,n,experimental
NET_PROMISCUOUS_MODE,n,experimental
NET_SOCKETS_CAN,n,experimental
NET_SOCKETS_ENABLE_DTLS,n,experimental
NET_SOCKETS_NET_MGMT,n,experimental
NET_SOCKETS_OFFLOAD,n,experimental
NET_SOCKETS_SOCKOPT_TLS,n,experimental
OPENOCD_SUPPORT,n,experimental
PERFORMANCE_METRICS,n,experimental
SHELL_TELNET_SUPPORT_COMMAND,n,experimental
SPI_SLAVE,n,experimental
THREAD_MONITOR,n,experimental
THREAD_NAME,n,experimental
UART_ASYNC_API,n,experimental
Can't render this file because it has a wrong number of fields in line 48.