#!/bin/bash
# Version: 1.0

# Warning! Be sure to download latest version of this script from its primary source:
# https://access.redhat.com/security/vulnerabilities/2934281
# DO NOT blindly trust any internet sources and NEVER do `curl something | bash`!

RED="\033[1;31m"
YELLOW="\033[1;33m"
GREEN="\033[1;32m"
BOLD="\033[1m"
RESET="\033[0m"

# Checking against the list is of vulnerable kernels is necessary because of the way how features 
# are backported to older kernel versions in various channels.

VULNERABLE_VERSIONS=(
    # .el5
    '2.6.18-8.1.1.el5'
    '2.6.18-8.1.3.el5'
    '2.6.18-8.1.4.el5'
    '2.6.18-8.1.6.el5'
    '2.6.18-8.1.8.el5'
    '2.6.18-8.1.10.el5'
    '2.6.18-8.1.14.el5'
    '2.6.18-8.1.15.el5'
    '2.6.18-53.el5'
    '2.6.18-53.1.4.el5'
    '2.6.18-53.1.6.el5'
    '2.6.18-53.1.13.el5'
    '2.6.18-53.1.14.el5'
    '2.6.18-53.1.19.el5'
    '2.6.18-53.1.21.el5'
    '2.6.18-92.el5'
    '2.6.18-92.1.1.el5'
    '2.6.18-92.1.6.el5'
    '2.6.18-92.1.10.el5'
    '2.6.18-92.1.13.el5'
    '2.6.18-92.1.18.el5'
    '2.6.18-92.1.22.el5'
    '2.6.18-92.1.24.el5'
    '2.6.18-92.1.26.el5'
    '2.6.18-92.1.27.el5'
    '2.6.18-92.1.28.el5'
    '2.6.18-92.1.29.el5'
    '2.6.18-92.1.32.el5'
    '2.6.18-92.1.35.el5'
    '2.6.18-92.1.38.el5'
    '2.6.18-128.el5'
    '2.6.18-128.1.1.el5'
    '2.6.18-128.1.6.el5'
    '2.6.18-128.1.10.el5'
    '2.6.18-128.1.14.el5'
    '2.6.18-128.1.16.el5'
    '2.6.18-128.2.1.el5'
    '2.6.18-128.4.1.el5'
    '2.6.18-128.4.1.el5'
    '2.6.18-128.7.1.el5'
    '2.6.18-128.8.1.el5'
    '2.6.18-128.11.1.el5'
    '2.6.18-128.12.1.el5'
    '2.6.18-128.14.1.el5'
    '2.6.18-128.16.1.el5'
    '2.6.18-128.17.1.el5'
    '2.6.18-128.18.1.el5'
    '2.6.18-128.23.1.el5'
    '2.6.18-128.23.2.el5'
    '2.6.18-128.25.1.el5'
    '2.6.18-128.26.1.el5'
    '2.6.18-128.27.1.el5'
    '2.6.18-128.29.1.el5'
    '2.6.18-128.30.1.el5'
    '2.6.18-128.31.1.el5'
    '2.6.18-128.32.1.el5'
    '2.6.18-128.35.1.el5'
    '2.6.18-128.36.1.el5'
    '2.6.18-128.37.1.el5'
    '2.6.18-128.38.1.el5'
    '2.6.18-128.39.1.el5'
    '2.6.18-128.40.1.el5'
    '2.6.18-128.41.1.el5'
    '2.6.18-164.el5'
    '2.6.18-164.2.1.el5'
    '2.6.18-164.6.1.el5'
    '2.6.18-164.9.1.el5'
    '2.6.18-164.10.1.el5'
    '2.6.18-164.11.1.el5'
    '2.6.18-164.15.1.el5'
    '2.6.18-164.17.1.el5'
    '2.6.18-164.19.1.el5'
    '2.6.18-164.21.1.el5'
    '2.6.18-164.25.1.el5'
    '2.6.18-164.25.2.el5'
    '2.6.18-164.28.1.el5'
    '2.6.18-164.30.1.el5'
    '2.6.18-164.32.1.el5'
    '2.6.18-164.34.1.el5'
    '2.6.18-164.36.1.el5'
    '2.6.18-164.37.1.el5'
    '2.6.18-164.38.1.el5'
    '2.6.18-194.el5'
    '2.6.18-194.3.1.el5'
    '2.6.18-194.8.1.el5'
    '2.6.18-194.11.1.el5'
    '2.6.18-194.11.3.el5'
    '2.6.18-194.11.4.el5'
    '2.6.18-194.17.1.el5'
    '2.6.18-194.17.4.el5'
    '2.6.18-194.26.1.el5'
    '2.6.18-194.32.1.el5'
    '2.6.18-238.el5'
    '2.6.18-238.1.1.el5'
    '2.6.18-238.5.1.el5'
    '2.6.18-238.9.1.el5'
    '2.6.18-238.12.1.el5'
    '2.6.18-238.19.1.el5'
    '2.6.18-238.21.1.el5'
    '2.6.18-238.27.1.el5'
    '2.6.18-238.28.1.el5'
    '2.6.18-238.31.1.el5'
    '2.6.18-238.33.1.el5'
    '2.6.18-238.35.1.el5'
    '2.6.18-238.37.1.el5'
    '2.6.18-238.39.1.el5'
    '2.6.18-238.40.1.el5'
    '2.6.18-238.44.1.el5'
    '2.6.18-238.45.1.el5'
    '2.6.18-238.47.1.el5'
    '2.6.18-238.48.1.el5'
    '2.6.18-238.49.1.el5'
    '2.6.18-238.50.1.el5'
    '2.6.18-238.51.1.el5'
    '2.6.18-238.52.1.el5'
    '2.6.18-238.53.1.el5'
    '2.6.18-238.54.1.el5'
    '2.6.18-238.55.1.el5'
    '2.6.18-238.56.1.el5'
    '2.6.18-238.57.1.el5'
    '2.6.18-274.el5'
    '2.6.18-274.3.1.el5'
    '2.6.18-274.7.1.el5'
    '2.6.18-274.12.1.el5'
    '2.6.18-274.17.1.el5'
    '2.6.18-274.18.1.el5'
    '2.6.18-308.el5'
    '2.6.18-308.1.1.el5'
    '2.6.18-308.4.1.el5'
    '2.6.18-308.8.1.el5'
    '2.6.18-308.8.2.el5'
    '2.6.18-308.11.1.el5'
    '2.6.18-308.13.1.el5'
    '2.6.18-308.16.1.el5'
    '2.6.18-308.20.1.el5'
    '2.6.18-308.24.1.el5'
    '2.6.18-348.el5'
    '2.6.18-348.1.1.el5'
    '2.6.18-348.2.1.el5'
    '2.6.18-348.3.1.el5'
    '2.6.18-348.4.1.el5'
    '2.6.18-348.6.1.el5'
    '2.6.18-348.12.1.el5'
    '2.6.18-348.16.1.el5'
    '2.6.18-348.18.1.el5'
    '2.6.18-348.19.1.el5'
    '2.6.18-348.21.1.el5'
    '2.6.18-348.22.1.el5'
    '2.6.18-348.23.1.el5'
    '2.6.18-348.25.1.el5'
    '2.6.18-348.27.1.el5'
    '2.6.18-348.28.1.el5'
    '2.6.18-348.29.1.el5'
    '2.6.18-348.30.1.el5'
    '2.6.18-348.31.2.el5'
    '2.6.18-348.32.1.el5'
    '2.6.18-371.el5'
    '2.6.18-371.1.2.el5'
    '2.6.18-371.3.1.el5'
    '2.6.18-371.4.1.el5'
    '2.6.18-371.6.1.el5'
    '2.6.18-371.8.1.el5'
    '2.6.18-371.9.1.el5'
    '2.6.18-371.11.1.el5'
    '2.6.18-371.12.1.el5'
    '2.6.18-398.el5'
    '2.6.18-400.el5'
    '2.6.18-400.1.1.el5'
    '2.6.18-402.el5'
    '2.6.18-404.el5'
    '2.6.18-406.el5'
    '2.6.18-407.el5'
    '2.6.18-408.el5'
    '2.6.18-409.el5'
    '2.6.18-410.el5'
    '2.6.18-411.el5'
    '2.6.18-412.el5'
    '2.6.18-416.el5'
    '2.6.18-417.el5'
    '2.6.18-418.el5'

    # .el6
    '2.6.32-71.7.1.el6'
    '2.6.32-71.14.1.el6'
    '2.6.32-71.18.1.el6'
    '2.6.32-71.18.2.el6'
    '2.6.32-71.24.1.el6'
    '2.6.32-71.29.1.el6'
    '2.6.32-71.31.1.el6'
    '2.6.32-71.34.1.el6'
    '2.6.32-71.35.1.el6'
    '2.6.32-71.36.1.el6'
    '2.6.32-71.37.1.el6'
    '2.6.32-71.38.1.el6'
    '2.6.32-71.39.1.el6'
    '2.6.32-71.40.1.el6'
    '2.6.32-131.0.15.el6'
    '2.6.32-131.2.1.el6'
    '2.6.32-131.4.1.el6'
    '2.6.32-131.6.1.el6'
    '2.6.32-131.12.1.el6'
    '2.6.32-131.17.1.el6'
    '2.6.32-131.21.1.el6'
    '2.6.32-131.22.1.el6'
    '2.6.32-131.25.1.el6'
    '2.6.32-131.26.1.el6'
    '2.6.32-131.28.1.el6'
    '2.6.32-131.29.1.el6'
    '2.6.32-131.30.1.el6'
    '2.6.32-131.30.2.el6'
    '2.6.32-131.33.1.el6'
    '2.6.32-131.35.1.el6'
    '2.6.32-131.36.1.el6'
    '2.6.32-131.37.1.el6'
    '2.6.32-131.38.1.el6'
    '2.6.32-131.39.1.el6'
    '2.6.32-220.el6'
    '2.6.32-220.2.1.el6'
    '2.6.32-220.4.1.el6'
    '2.6.32-220.4.2.el6'
    '2.6.32-220.4.7.bgq.el6'
    '2.6.32-220.7.1.el6'
    '2.6.32-220.7.3.p7ih.el6'
    '2.6.32-220.7.4.p7ih.el6'
    '2.6.32-220.7.6.p7ih.el6'
    '2.6.32-220.7.7.p7ih.el6'
    '2.6.32-220.13.1.el6'
    '2.6.32-220.17.1.el6'
    '2.6.32-220.23.1.el6'
    '2.6.32-220.24.1.el6'
    '2.6.32-220.25.1.el6'
    '2.6.32-220.26.1.el6'
    '2.6.32-220.28.1.el6'
    '2.6.32-220.30.1.el6'
    '2.6.32-220.31.1.el6'
    '2.6.32-220.32.1.el6'
    '2.6.32-220.34.1.el6'
    '2.6.32-220.34.2.el6'
    '2.6.32-220.38.1.el6'
    '2.6.32-220.39.1.el6'
    '2.6.32-220.41.1.el6'
    '2.6.32-220.42.1.el6'
    '2.6.32-220.45.1.el6'
    '2.6.32-220.46.1.el6'
    '2.6.32-220.48.1.el6'
    '2.6.32-220.51.1.el6'
    '2.6.32-220.52.1.el6'
    '2.6.32-220.53.1.el6'
    '2.6.32-220.54.1.el6'
    '2.6.32-220.55.1.el6'
    '2.6.32-220.56.1.el6'
    '2.6.32-220.57.1.el6'
    '2.6.32-220.58.1.el6'
    '2.6.32-220.60.2.el6'
    '2.6.32-220.62.1.el6'
    '2.6.32-220.63.2.el6'
    '2.6.32-220.64.1.el6'
    '2.6.32-220.65.1.el6'
    '2.6.32-220.66.1.el6'
    '2.6.32-220.67.1.el6'
    '2.6.32-220.68.1.el6'
    '2.6.32-220.69.1.el6'
    '2.6.32-279.el6'
    '2.6.32-279.1.1.el6'
    '2.6.32-279.2.1.el6'
    '2.6.32-279.5.1.el6'
    '2.6.32-279.5.2.el6'
    '2.6.32-279.9.1.el6'
    '2.6.32-279.11.1.el6'
    '2.6.32-279.14.1.bgq.el6'
    '2.6.32-279.14.1.el6'
    '2.6.32-279.19.1.el6'
    '2.6.32-279.22.1.el6'
    '2.6.32-279.23.1.el6'
    '2.6.32-279.25.1.el6'
    '2.6.32-279.25.2.el6'
    '2.6.32-279.31.1.el6'
    '2.6.32-279.33.1.el6'
    '2.6.32-279.34.1.el6'
    '2.6.32-279.37.2.el6'
    '2.6.32-279.39.1.el6'
    '2.6.32-279.41.1.el6'
    '2.6.32-279.42.1.el6'
    '2.6.32-279.43.1.el6'
    '2.6.32-279.43.2.el6'
    '2.6.32-279.46.1.el6'
    '2.6.32-358.el6'
    '2.6.32-358.0.1.el6'
    '2.6.32-358.2.1.el6'
    '2.6.32-358.6.1.el6'
    '2.6.32-358.6.2.el6'
    '2.6.32-358.6.3.p7ih.el6'
    '2.6.32-358.11.1.bgq.el6'
    '2.6.32-358.11.1.el6'
    '2.6.32-358.14.1.el6'
    '2.6.32-358.18.1.el6'
    '2.6.32-358.23.2.el6'
    '2.6.32-358.28.1.el6'
    '2.6.32-358.32.3.el6'
    '2.6.32-358.37.1.el6'
    '2.6.32-358.41.1.el6'
    '2.6.32-358.44.1.el6'
    '2.6.32-358.46.1.el6'
    '2.6.32-358.46.2.el6'
    '2.6.32-358.48.1.el6'
    '2.6.32-358.49.1.el6'
    '2.6.32-358.51.1.el6'
    '2.6.32-358.51.2.el6'
    '2.6.32-358.55.1.el6'
    '2.6.32-358.56.1.el6'
    '2.6.32-358.59.1.el6'
    '2.6.32-358.61.1.el6'
    '2.6.32-358.62.1.el6'
    '2.6.32-358.65.1.el6'
    '2.6.32-358.67.1.el6'
    '2.6.32-358.68.1.el6'
    '2.6.32-358.69.1.el6'
    '2.6.32-358.70.1.el6'
    '2.6.32-358.71.1.el6'
    '2.6.32-358.72.1.el6'
    '2.6.32-358.73.1.el6'
    '2.6.32-358.75.1.el6'
    '2.6.32-358.76.1.el6'
    '2.6.32-358.111.1.openstack.el6'
    '2.6.32-358.114.1.openstack.el6'
    '2.6.32-358.118.1.openstack.el6'
    '2.6.32-358.123.4.openstack.el6'
    '2.6.32-431.el6'
    '2.6.32-431.1.1.bgq.el6'
    '2.6.32-431.1.2.el6'
    '2.6.32-431.3.1.el6'
    '2.6.32-431.5.1.el6'
    '2.6.32-431.11.2.el6'
    '2.6.32-431.17.1.el6'
    '2.6.32-431.20.3.el6'
    '2.6.32-431.20.5.el6'
    '2.6.32-431.23.3.el6'
    '2.6.32-431.29.2.el6'
    '2.6.32-431.37.1.el6'
    '2.6.32-431.40.1.el6'
    '2.6.32-431.40.2.el6'
    '2.6.32-431.46.2.el6'
    '2.6.32-431.50.1.el6'
    '2.6.32-431.53.2.el6'
    '2.6.32-431.56.1.el6'
    '2.6.32-431.59.1.el6'
    '2.6.32-431.61.2.el6'
    '2.6.32-431.64.1.el6'
    '2.6.32-431.66.1.el6'
    '2.6.32-431.68.1.el6'
    '2.6.32-431.69.1.el6'
    '2.6.32-431.70.1.el6'
    '2.6.32-431.71.1.el6'
    '2.6.32-431.72.1.el6'
    '2.6.32-431.73.2.el6'
    '2.6.32-431.74.1.el6'
    '2.6.32-431.75.1.el6'
    '2.6.32-431.75.1.el6'
    '2.6.32-431.76.1.el6'
    '2.6.32-431.77.1.el6'
    '2.6.32-431.77.1.el6'
    '2.6.32-504.el6'
    '2.6.32-504.1.3.el6'
    '2.6.32-504.3.3.el6'
    '2.6.32-504.8.1.el6'
    '2.6.32-504.8.2.bgq.el6'
    '2.6.32-504.12.2.el6'
    '2.6.32-504.16.2.el6'
    '2.6.32-504.23.4.el6'
    '2.6.32-504.30.3.el6'
    '2.6.32-504.30.5.p7ih.el6'
    '2.6.32-504.30.6.p7ih.el6'
    '2.6.32-504.33.2.el6'
    '2.6.32-504.36.1.el6'
    '2.6.32-504.38.1.el6'
    '2.6.32-504.40.1.el6'
    '2.6.32-504.43.1.el6'
    '2.6.32-504.46.1.el6'
    '2.6.32-504.49.1.el6'
    '2.6.32-504.50.1.el6'
    '2.6.32-504.51.1.el6'
    '2.6.32-504.52.1.el6'
    '2.6.32-504.54.1.el6'
    '2.6.32-504.55.1.el6'
    '2.6.32-504.56.1.el6'
    '2.6.32-504.56.1.el6'
    '2.6.32-573.el6'
    '2.6.32-573.1.1.el6'
    '2.6.32-573.3.1.el6'
    '2.6.32-573.4.2.bgq.el6'
    '2.6.32-573.7.1.el6'
    '2.6.32-573.8.1.el6'
    '2.6.32-573.12.1.el6'
    '2.6.32-573.18.1.el6'
    '2.6.32-573.22.1.el6'
    '2.6.32-573.26.1.el6'
    '2.6.32-573.30.1.el6'
    '2.6.32-573.32.1.el6'
    '2.6.32-573.34.1.el6'
    '2.6.32-573.35.1.el6'
    '2.6.32-573.35.2.el6'
    '2.6.32-573.37.1.el6'
    '2.6.32-573.38.1.el6'
    '2.6.32-642.el6'
    '2.6.32-642.1.1.el6'
    '2.6.32-642.3.1.el6'
    '2.6.32-642.4.2.el6'
    '2.6.32-642.6.1.el6'
    '2.6.32-642.6.2.el6'
    '2.6.32-642.11.1.el6'
    '2.6.32-642.13.1.el6'
    '2.6.32-694.el6'

    # .el7
    '3.10.0-123.el7'
    '3.10.0-123.1.2.el7'
    '3.10.0-123.4.2.el7'
    '3.10.0-123.4.4.el7'
    '3.10.0-123.6.3.el7'
    '3.10.0-123.8.1.el7'
    '3.10.0-123.9.2.el7'
    '3.10.0-123.9.3.el7'
    '3.10.0-123.13.1.el7'
    '3.10.0-123.13.2.el7'
    '3.10.0-123.20.1.el7'
    '3.10.0-229.el7'
    '3.10.0-229.1.2.el7'
    '3.10.0-229.4.2.el7'
    '3.10.0-229.7.2.el7'
    '3.10.0-229.11.1.el7'
    '3.10.0-229.14.1.el7'
    '3.10.0-229.20.1.el7'
    '3.10.0-229.24.2.el7'
    '3.10.0-229.26.2.el7'
    '3.10.0-229.28.1.el7'
    '3.10.0-229.30.1.el7'
    '3.10.0-229.34.1.el7'
    '3.10.0-229.38.1.el7'
    '3.10.0-229.40.1.el7'
    '3.10.0-229.42.1.el7'
    '3.10.0-229.42.2.el7'
    '3.10.0-229.44.1.el7'
    '3.10.0-229.46.1.el7'
    '3.10.0-229.48.1.el7'
    '3.10.0-327.el7'
    '3.10.0-327.3.1.el7'
    '3.10.0-327.4.4.el7'
    '3.10.0-327.4.5.el7'
    '3.10.0-327.10.1.el7'
    '3.10.0-327.13.1.el7'
    '3.10.0-327.18.2.el7'
    '3.10.0-327.22.2.el7'
    '3.10.0-327.28.2.el7'
    '3.10.0-327.28.3.el7'
    '3.10.0-327.36.1.el7'
    '3.10.0-327.36.2.el7'
    '3.10.0-327.36.3.el7'
    '3.10.0-327.41.3.el7'
    '3.10.0-327.41.4.el7'
    '3.10.0-327.44.2.el7'
    '3.10.0-327.46.1.el7'
    '3.10.0-514.el7'
    '3.10.0-514.2.2.el7'
    '3.10.0-514.6.1.el7'

    # .ael7
    '3.10.0-229.1.2.ael7b'
    '3.10.0-229.4.2.ael7b'
    '3.10.0-229.7.2.ael7b'
    '3.10.0-229.11.1.ael7b'
    '3.10.0-229.14.1.ael7b'
    '3.10.0-229.20.1.ael7b'
    '3.10.0-229.24.2.ael7b'
    '3.10.0-229.26.2.ael7b'
    '3.10.0-229.28.1.ael7b'
    '3.10.0-229.30.1.ael7b'
    '3.10.0-229.34.1.ael7b'
    '3.10.0-229.38.1.ael7b'
    '3.10.0-229.40.1.ael7b'
    '3.10.0-229.42.1.ael7b'
    '3.10.0-229.42.2.ael7b'
    '3.10.0-229.44.1.ael7b'
    '3.10.0-229.46.1.ael7b'
    '3.10.0-229.48.1.ael7b'


    # .el5
    '2.6.24.7-74.el5rt'
    '2.6.24.7-81.el5rt'
    '2.6.24.7-93.el5rt'
    '2.6.24.7-101.el5rt'
    '2.6.24.7-108.el5rt'
    '2.6.24.7-111.el5rt'
    '2.6.24.7-117.el5rt'
    '2.6.24.7-126.el5rt'
    '2.6.24.7-132.el5rt'
    '2.6.24.7-137.el5rt'
    '2.6.24.7-139.el5rt'
    '2.6.24.7-146.el5rt'
    '2.6.24.7-149.el5rt'
    '2.6.24.7-161.el5rt'
    '2.6.24.7-169.el5rt'
    '2.6.33.7-rt29.45.el5rt'
    '2.6.33.7-rt29.47.el5rt'
    '2.6.33.7-rt29.55.el5rt'
    '2.6.33.9-rt31.64.el5rt'
    '2.6.33.9-rt31.67.el5rt'
    '2.6.33.9-rt31.86.el5rt'

    # .el6
    '2.6.33.9-rt31.66.el6rt'
    '2.6.33.9-rt31.74.el6rt'
    '2.6.33.9-rt31.75.el6rt'
    '2.6.33.9-rt31.79.el6rt'
    '3.0.9-rt26.45.el6rt'
    '3.0.9-rt26.46.el6rt'
    '3.0.18-rt34.53.el6rt'
    '3.0.25-rt44.57.el6rt'
    '3.0.30-rt50.62.el6rt'
    '3.0.36-rt57.66.el6rt'
    '3.2.23-rt37.56.el6rt'
    '3.2.33-rt50.66.el6rt'
    '3.6.11-rt28.20.el6rt'
    '3.6.11-rt30.25.el6rt'
    '3.6.11.2-rt33.39.el6rt'
    '3.6.11.5-rt37.55.el6rt'
    '3.8.13-rt14.20.el6rt'
    '3.8.13-rt14.25.el6rt'
    '3.8.13-rt27.33.el6rt'
    '3.8.13-rt27.34.el6rt'
    '3.8.13-rt27.40.el6rt'
    '3.10.0-229.rt56.144.el6rt'
    '3.10.0-229.rt56.147.el6rt'
    '3.10.0-229.rt56.149.el6rt'
    '3.10.0-229.rt56.151.el6rt'
    '3.10.0-229.rt56.153.el6rt'
    '3.10.0-229.rt56.158.el6rt'
    '3.10.0-229.rt56.161.el6rt'
    '3.10.0-229.rt56.162.el6rt'
    '3.10.0-327.rt56.170.el6rt'
    '3.10.0-327.rt56.171.el6rt'
    '3.10.0-327.rt56.176.el6rt'
    '3.10.0-327.rt56.183.el6rt'
    '3.10.0-327.rt56.190.el6rt'
    '3.10.0-327.rt56.194.el6rt'
    '3.10.0-327.rt56.195.el6rt'
    '3.10.0-327.rt56.197.el6rt'
    '3.10.0-327.rt56.198.el6rt'
    '3.10.0-327.rt56.199.el6rt'
    '3.10.0-514.rt56.210.el6rt'
    '3.10.33-rt32.33.el6rt'
    '3.10.33-rt32.34.el6rt'
    '3.10.33-rt32.43.el6rt'
    '3.10.33-rt32.45.el6rt'
    '3.10.33-rt32.51.el6rt'
    '3.10.33-rt32.52.el6rt'
    '3.10.58-rt62.58.el6rt'
    '3.10.58-rt62.60.el6rt'

    # .el7
    '3.10.0-229.rt56.141.el7'
    '3.10.0-229.1.2.rt56.141.2.el7_1'
    '3.10.0-229.4.2.rt56.141.6.el7_1'
    '3.10.0-229.7.2.rt56.141.6.el7_1'
    '3.10.0-229.11.1.rt56.141.11.el7_1'
    '3.10.0-229.14.1.rt56.141.13.el7_1'
    '3.10.0-229.20.1.rt56.141.14.el7_1'
    '3.10.0-327.rt56.204.el7'
    '3.10.0-327.4.5.rt56.206.el7_2'
    '3.10.0-327.10.1.rt56.211.el7_2'
    '3.10.0-327.13.1.rt56.216.el7_2'
    '3.10.0-327.18.2.rt56.223.el7_2'
    '3.10.0-327.22.2.rt56.230.el7_2'
    '3.10.0-327.28.2.rt56.234.el7_2'
    '3.10.0-327.28.3.rt56.235.el7'
    '3.10.0-327.36.1.rt56.237.el7'
    '3.10.0-327.36.3.rt56.238.el7'
    '3.10.0-514.rt56.420.el7'
    '3.10.0-514.2.2.rt56.424.el7'
    '3.10.0-514.6.1.rt56.429.el7'
)

KPATCH_MODULE_NAMES=(
    # Example: "kpatch_3_10_0_327_36_1_1_1"
)

POLICY_PATTERN='^selinux-policy-([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+-[[:digit:]]+).*$'
MITIGATING_RHEL7_POLICY="3.13.1-81"
MITIGATION_PATTERN='install[[:space:]]+dccp[[:space:]]+/bin/true'

compare4() {
    local left=( $( tr ".-" "  " <<< "$1" ) )
    local right=( $( tr ".-" "  " <<< "$3" ) )
    local expression="$2"

    if [[ "$expression" == *"="* ]]; then
        if (( left[0] == right[0] && 
              left[1] == right[1] && 
              left[2] == right[2] && 
              left[3] == right[3] )); then
            return 0
        fi
    fi

    if [[ "$expression" == *">"* ]]; then
        if (( left[0] > right[0] ||
              left[0] == right[0] && left[1] > right[1] ||
              left[0] == right[0] && left[1] == right[1] && left[2] > right[2] ||
              left[0] == right[0] && left[1] == right[1] && left[2] == right[2] && left[3] > right[3] )); then
            return 0
        fi
    fi
    
    if [[ "$expression" == *"<"* ]]; then
        if (( left[0] < right[0] ||
              left[0] == right[0] && left[1] < right[1] ||
              left[0] == right[0] && left[1] == right[1] && left[2] < right[2] ||
              left[0] == right[0] && left[1] == right[1] && left[2] == right[2] && left[3] < right[3] )); then
            return 0
        fi
    fi
    
    return 1
}


# Help and parameters
for parameter in "$@"; do
    if [[ "$parameter" == "-h" || "$parameter" == "--help" ]]; then
      echo "Usage: $( basename "$0" ) [--no-colors] [-d | --debug]"
      exit 1
    fi
    if [[ "$parameter" == "--no-colors" ]]; then
        RED=""
        YELLOW=""
        GREEN=""
        BOLD=""
        RESET=""
    fi
    if [[ "$parameter" == "-d" || "$parameter" == "--debug" ]]; then
        debug=true
    fi
done

# Disclaimer
echo
echo -e "${BOLD}This script is primarily designed to detect CVE-2017-6074 on supported"
echo -e "RHEL systems and kernel packages."
echo -e "Result may be inaccurate for other RPM based systems.${RESET}"
echo

# RPM is required
if ! command -v rpm >/dev/null 2>&1; then
    echo "'rpm' command is required, but not installed. Exiting."
    exit 1
fi

# Get kernel info
running_kernel=$( uname -r )

# Check supported platform
if [[ "$running_kernel" != *".el"[5-7]* ]]; then
    echo -e "${RED}This script is only meant to detect vulnerable kernels on Red Hat Enterprise Linux 5, 6 and 7.${RESET}"
    exit 1
fi

# Get RHEL number
rhel=$( sed -r -n 's/^.*el([[:digit:]]).*$/\1/p' <<< "$running_kernel" )

# Get SELinux status and policy
selinux=0
if command -v getenforce >/dev/null 2>&1; then
    if [[ $( getenforce ) == "Enforcing" ]]; then
        selinux=1
    fi   
    # Parse selinux-policy version
    for package in $( rpm -qa | grep selinux-policy ); do
        if [[ "$package" =~ $POLICY_PATTERN ]]; then
            policy_version=$( sed -r -n 's/^'"$POLICY_PATTERN"'/\1/p' <<< "$package" )
        fi   
    done
    if [[ "$rhel" == 7 ]]; then
        if compare4 "$policy_version" ">=" "$MITIGATING_RHEL7_POLICY"; then
            enough_policy=true
        fi
    else
        enough_policy=true
    fi
fi

# Check kernel if it is vulnerable
for tested_kernel in "${VULNERABLE_VERSIONS[@]}"; do
	if [[ "$running_kernel" == *"$tested_kernel"* ]]; then
	    vulnerable_kernel="$running_kernel"
	    break
	fi
done

# Get loaded kernel modules
modules=$( lsmod )

# Check if kpatch is installed
for tested_kpatch in "${KPATCH_MODULE_NAMES[@]}"; do
    if [[ "$modules" == *"$tested_kpatch"* ]]; then
	    applied_kpatch="$tested_kpatch"
	    break
	fi
done

# Check DCCP module loaded
if [[ "$modules" == *"dccp"* ]]; then
    dccp_loaded=true
fi

# Check recommended mitigation
for file in /etc/modprobe.d/*; do
    if grep -E --quiet "$MITIGATION_PATTERN" "$file" 2>/dev/null; then
        dccp_loading_disabled=true
    fi
done

# Debug
if [[ "$debug" ]]; then
    echo "enough_policy = *$enough_policy*"
    echo "running_kernel = *$running_kernel*"
    echo "rhel = *$rhel*"
    echo "selinux = *$selinux*"
    echo "policy_version = *$policy_version*"
    echo "vulnerable_kernel = *$vulnerable_kernel*"
    echo "applied_kpatch = *$applied_kpatch*"
    echo "dccp_loaded = *$dccp_loaded*"
    echo "dccp_loading_disabled = *$dccp_loading_disabled*"
    echo
fi

# Result representation
echo -e "Detected kernel package is '$BOLD$running_kernel$RESET'."

if [[ "$vulnerable_kernel" ]]; then
    if [[ "$applied_kpatch" ]]; then
        echo -e "${YELLOW}This kernel version is vulnerable.${RESET}"
        echo -e "${GREEN}You have correct kpatch installed${RESET} and vulnerability is not exploitable."
        exit 0
    fi

    if [[ "$rhel" != 5 ]]; then
        if (( selinux )); then
            if [[ "$enough_policy" ]]; then
                echo -e "${YELLOW}This kernel version is vulnerable.${RESET}"
                echo -e "${GREEN}SELinux mitigates the issue.${RESET}"
                exit 0
            else
                echo -e "${RED}This kernel version is vulnerable.${RESET}"
                echo -e "You have '$policy_version' version of selinux-policy installed."
                echo -e "Minimal needed version of selinux-policy is '$MITIGATING_RHEL7_POLICY$'."
                exit 4
            fi
        fi
    fi

    if [[ "$dccp_loading_disabled" && ! "$dccp_loaded" ]]; then
        echo -e "${YELLOW}This kernel version is vulnerable.${RESET}"
        echo -e "${GREEN}You have proper mitigation installed${RESET} and vulnerability is not exploitable."
        exit 0
    elif [[ "$dccp_loading_disabled" && "$dccp_loaded" ]]; then
        echo -e "${RED}This kernel version is vulnerable.${RESET}"
        echo -e "You have proper mitigation installed, but ${RED}DCCP kernel module is still loaded.${RESET}"
        echo -e "You need to reboot the system."
        echo -e "Follow https://access.redhat.com/security/vulnerabilities/2934281 for advice."
        exit 2
    fi
    
    echo -e "${RED}This kernel version is vulnerable.${RESET}"
    echo -e "Either update kernel package or apply mitigation (SELinux on RHEL6 and RHEL7 or disable DCCP loading)."
    echo -e "Follow https://access.redhat.com/security/vulnerabilities/2934281 for advice."
    exit 3
else
    echo -e "${GREEN}This kernel version is not vulnerable.${RESET}"
    exit 0
fi
