From c6af0aa45342a609c884f27446496b750f10a38f Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 6 Oct 2017 01:33:00 +0100 Subject: [PATCH] Move check-security-hardening.sh into full_test_suite.py --- qa/zcash/check-security-hardening.sh | 46 ---------------------- qa/zcash/full_test_suite.py | 58 +++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 47 deletions(-) delete mode 100755 qa/zcash/check-security-hardening.sh diff --git a/qa/zcash/check-security-hardening.sh b/qa/zcash/check-security-hardening.sh deleted file mode 100755 index 94a87fea3..000000000 --- a/qa/zcash/check-security-hardening.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -set -e - -REPOROOT="$(readlink -f "$(dirname "$0")"/../../)" - -function test_rpath_runpath { - if "${REPOROOT}/qa/zcash/checksec.sh" --file "$1" | grep -q "No RPATH.*No RUNPATH"; then - echo PASS: "$1" has no RPATH or RUNPATH. - return 0 - else - echo FAIL: "$1" has an RPATH or a RUNPATH. - "${REPOROOT}/qa/zcash/checksec.sh" --file "$1" - return 1 - fi -} - -function test_fortify_source { - if { "${REPOROOT}/qa/zcash/checksec.sh" --fortify-file "$1" | grep -q "FORTIFY_SOURCE support available.*Yes"; } && - { "${REPOROOT}/qa/zcash/checksec.sh" --fortify-file "$1" | grep -q "Binary compiled with FORTIFY_SOURCE support.*Yes"; }; then - echo PASS: "$1" has FORTIFY_SOURCE. - return 0 - else - echo FAIL: "$1" is missing FORTIFY_SOURCE. - return 1 - fi -} - -# PIE, RELRO, Canary, and NX are tested by make check-security. -make -C "$REPOROOT/src" check-security - -test_rpath_runpath "${REPOROOT}/src/zcashd" -test_rpath_runpath "${REPOROOT}/src/zcash-cli" -test_rpath_runpath "${REPOROOT}/src/zcash-gtest" -test_rpath_runpath "${REPOROOT}/src/zcash-tx" -test_rpath_runpath "${REPOROOT}/src/test/test_bitcoin" -test_rpath_runpath "${REPOROOT}/src/zcash/GenerateParams" - -# NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE is -# enabled for the entire binary. See issue #915. -test_fortify_source "${REPOROOT}/src/zcashd" -test_fortify_source "${REPOROOT}/src/zcash-cli" -test_fortify_source "${REPOROOT}/src/zcash-gtest" -test_fortify_source "${REPOROOT}/src/zcash-tx" -test_fortify_source "${REPOROOT}/src/test/test_bitcoin" -test_fortify_source "${REPOROOT}/src/zcash/GenerateParams" diff --git a/qa/zcash/full_test_suite.py b/qa/zcash/full_test_suite.py index d2eca6a42..6e890c49a 100755 --- a/qa/zcash/full_test_suite.py +++ b/qa/zcash/full_test_suite.py @@ -5,6 +5,7 @@ import argparse import os +import re import subprocess import sys @@ -24,6 +25,61 @@ def repofile(filename): # Custom test runners # +RE_RPATH_RUNPATH = re.compile('No RPATH.*No RUNPATH') +RE_FORTIFY_AVAILABLE = re.compile('FORTIFY_SOURCE support available.*Yes') +RE_FORTIFY_USED = re.compile('Binary compiled with FORTIFY_SOURCE support.*Yes') + +def test_rpath_runpath(filename): + output = subprocess.check_output( + [repofile('qa/zcash/checksec.sh'), '--file', repofile(filename)] + ) + if RE_RPATH_RUNPATH.search(output): + print('PASS: %s has no RPATH or RUNPATH.' % filename) + return True + else: + print('FAIL: %s has an RPATH or a RUNPATH.' % filename) + print(output) + return False + +def test_fortify_source(filename): + proc = subprocess.Popen( + [repofile('qa/zcash/checksec.sh'), '--fortify-file', repofile(filename)], + stdout=subprocess.PIPE, + ) + line1 = proc.stdout.readline() + line2 = proc.stdout.readline() + proc.terminate() + if RE_FORTIFY_AVAILABLE.search(line1) and RE_FORTIFY_USED.search(line2): + print('PASS: %s has FORTIFY_SOURCE.' % filename) + return True + else: + print('FAIL: %s is missing FORTIFY_SOURCE.' % filename) + return False + +def check_security_hardening(): + ret = True + + # PIE, RELRO, Canary, and NX are tested by make check-security. + ret &= subprocess.call(['make', '-C', repofile('src'), 'check-security']) == 0 + + ret &= test_rpath_runpath('src/zcashd') + ret &= test_rpath_runpath('src/zcash-cli') + ret &= test_rpath_runpath('src/zcash-gtest') + ret &= test_rpath_runpath('src/zcash-tx') + ret &= test_rpath_runpath('src/test/test_bitcoin') + ret &= test_rpath_runpath('src/zcash/GenerateParams') + + # NOTE: checksec.sh does not reliably determine whether FORTIFY_SOURCE + # is enabled for the entire binary. See issue #915. + ret &= test_fortify_source('src/zcashd') + ret &= test_fortify_source('src/zcash-cli') + ret &= test_fortify_source('src/zcash-gtest') + ret &= test_fortify_source('src/zcash-tx') + ret &= test_fortify_source('src/test/test_bitcoin') + ret &= test_fortify_source('src/zcash/GenerateParams') + + return ret + def ensure_no_dot_so_in_depends(): arch_dir = os.path.join( REPOROOT, @@ -72,7 +128,7 @@ STAGES = [ STAGE_COMMANDS = { 'btest': [repofile('src/test/test_bitcoin'), '-p'], 'gtest': [repofile('src/zcash-gtest')], - 'sec-hard': [repofile('qa/zcash/check-security-hardening.sh')], + 'sec-hard': check_security_hardening, 'no-dot-so': ensure_no_dot_so_in_depends, 'secp256k1': ['make', '-C', repofile('src/secp256k1'), 'check'], 'univalue': ['make', '-C', repofile('src/univalue'), 'check'],