#!/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/stackguard
# DO NOT blindly trust any internet sources and NEVER do `curl something | bash`!

# Checking against the list of vulnerable packages is necessary because of the way how features
# are back-ported to older versions of packages in various channels.

VULNERABLE_VERSIONS=(
    'glibc-2.17-79.ael7b_1'
    'glibc-2.17-79.ael7b_1.4'
    'glibc-2.5-18.el5_1.1'
    'glibc-2.5-24.el5_2.2'
    'glibc-2.5-24.el5_2.3'
    'glibc-2.5-34.el5_3.1'
    'glibc-2.5-34.el5_3.2'
    'glibc-2.5-34.el5_3.3'
    'glibc-2.5-34.el5_3.4'
    'glibc-2.5-42.el5_4.2'
    'glibc-2.5-42.el5_4.3'
    'glibc-2.5-42.el5_4.4'
    'glibc-2.5-42.el5_4.5'
    'glibc-2.5-49.el5_5.2'
    'glibc-2.5-49.el5_5.4'
    'glibc-2.5-49.el5_5.5'
    'glibc-2.5-49.el5_5.6'
    'glibc-2.5-49.el5_5.7'
    'glibc-2.5-58.el5_6.2'
    'glibc-2.5-58.el5_6.3'
    'glibc-2.5-58.el5_6.4'
    'glibc-2.5-58.el5_6.5'
    'glibc-2.5-58.el5_6.6'
    'glibc-2.5-65.el5_7.1'
    'glibc-2.5-65.el5_7.3'
    'glibc-2.5-81.el5_8.1'
    'glibc-2.5-81.el5_8.2'
    'glibc-2.5-81.el5_8.4'
    'glibc-2.5-81.el5_8.7'
    'glibc-2.5-107.el5_9.1'
    'glibc-2.5-107.el5_9.4'
    'glibc-2.5-107.el5_9.5'
    'glibc-2.5-107.el5_9.6'
    'glibc-2.5-107.el5_9.7'
    'glibc-2.5-107.el5_9.8'
    'glibc-2.5-118.el5_10.2'
    'glibc-2.5-118.el5_10.3'
    'glibc-2.5-123.el5_11.1'
    'glibc-2.5-123.el5_11.3'
    'glibc-2.12-1.7.el6_0.3'
    'glibc-2.12-1.7.el6_0.4'
    'glibc-2.12-1.7.el6_0.5'
    'glibc-2.12-1.7.el6_0.8'
    'glibc-2.12-1.25.el6'
    'glibc-2.12-1.25.el6_1.3'
    'glibc-2.12-1.47.el6'
    'glibc-2.12-1.47.el6_2.5'
    'glibc-2.12-1.47.el6_2.9'
    'glibc-2.12-1.47.el6_2.12'
    'glibc-2.12-1.47.el6_2.13'
    'glibc-2.12-1.47.el6_2.15'
    'glibc-2.12-1.47.el6_2.17'
    'glibc-2.12-1.80.el6'
    'glibc-2.12-1.80.el6_3.3'
    'glibc-2.12-1.80.el6_3.4'
    'glibc-2.12-1.80.el6_3.5'
    'glibc-2.12-1.80.el6_3.6'
    'glibc-2.12-1.80.el6_3.7'
    'glibc-2.12-1.107.el6'
    'glibc-2.12-1.107.el6_4.2'
    'glibc-2.12-1.107.el6_4.4'
    'glibc-2.12-1.107.el6_4.5'
    'glibc-2.12-1.107.el6_4.6'
    'glibc-2.12-1.107.el6_4.7'
    'glibc-2.12-1.107.el6_4.9'
    'glibc-2.12-1.132.el6'
    'glibc-2.12-1.132.el6_5.1'
    'glibc-2.12-1.132.el6_5.2'
    'glibc-2.12-1.132.el6_5.3'
    'glibc-2.12-1.132.el6_5.4'
    'glibc-2.12-1.132.el6_5.5'
    'glibc-2.12-1.132.el6_5.7'
    'glibc-2.12-1.132.el6_5.8'
    'glibc-2.12-1.149.el6'
    'glibc-2.12-1.149.el6_6.4'
    'glibc-2.12-1.149.el6_6.5'
    'glibc-2.12-1.149.el6_6.7'
    'glibc-2.12-1.149.el6_6.9'
    'glibc-2.12-1.149.el6_6.11'
    'glibc-2.12-1.166.el6'
    'glibc-2.12-1.166.el6_7.1'
    'glibc-2.12-1.166.el6_7.3'
    'glibc-2.12-1.166.el6_7.7'
    'glibc-2.12-1.192.el6'
    'glibc-2.12-1.209.el6'
    'glibc-2.12-1.209.el6_9.1'
    'glibc-2.17-55.el7'
    'glibc-2.17-55.el7_0.1'
    'glibc-2.17-55.el7_0.3'
    'glibc-2.17-55.el7_0.5'
    'glibc-2.17-78.el7'
    'glibc-2.17-79.el7_1'
    'glibc-2.17-79.el7_1.4'
    'glibc-2.17-105.el7'
    'glibc-2.17-106.el7_2.1'
    'glibc-2.17-106.el7_2.4'
    'glibc-2.17-106.el7_2.6'
    'glibc-2.17-106.el7_2.8'
    'glibc-2.17-157.el7'
    'glibc-2.17-157.el7_3.1'
    'glibc-2.17-157.el7_3.1'
    'glibc-2.17-157.el7_3.2'
)

VULNERABLE_KERNELS=(
    '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'
    '3.10.0-229.49.1.ael7b'
    '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-238.58.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-348.33.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'
    '2.6.18-419.el5'
    '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-220.70.1.el6'
    '2.6.32-220.71.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.77.1.el6'
    '2.6.32-358.78.1.el6'
    '2.6.32-358.79.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-431.78.1.el6'
    '2.6.32-431.78.1.el6'
    '2.6.32-431.79.1.el6'
    '2.6.32-431.79.1.el6'
    '2.6.32-431.80.1.el6'
    '2.6.32-431.80.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-504.57.1.el6'
    '2.6.32-504.57.1.el6'
    '2.6.32-504.58.1.el6'
    '2.6.32-504.58.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-573.40.1.el6'
    '2.6.32-573.41.1.el6'
    '2.6.32-573.42.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-642.13.2.el6'
    '2.6.32-642.15.1.el6'
    '2.6.32-696.el6'
    '2.6.32-696.1.1.el6'
    '2.6.32-696.3.1.el6'
    '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-229.49.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-327.49.2.el7'
    '3.10.0-327.53.1.el7'
    '3.10.0-327.55.1.el7'
    '3.10.0-514.el7'
    '3.10.0-514.2.2.el7'
    '3.10.0-514.6.1.el7'
    '3.10.0-514.6.2.el7'
    '3.10.0-514.10.2.el7'
    '3.10.0-514.16.1.el7'
    '3.10.0-514.16.2.p7ih.el7'
    '3.10.0-514.21.1.el7'
    '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'
    '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.0-514.rt56.215.el6rt'
    '3.10.0-514.rt56.219.el6rt'
    '3.10.0-514.rt56.221.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'
    '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'
    '3.10.0-514.6.1.rt56.430.el7'
    '3.10.0-514.10.2.rt56.435.el7'
    '3.10.0-514.16.1.rt56.437.el7'
    '3.10.0-514.21.1.rt56.438.el7'
)

KPATCH_MODULE_NAMES=(
    'kpatch_3_10_0_514_21_1_1_2'
    'kpatch_3_10_0_327_36_3_1_2'
)


basic_args() {
    # Parses basic commandline arguments and sets basic environment.
    #
    # Args:
    #     parameters - an array of commandline arguments
    #
    # Side effects:
    #     Exits if --help parameters is used
    #     Sets COLOR constants and debug variable

    parameters=( "$@" )

    RED="\033[1;31m"
    YELLOW="\033[1;33m"
    GREEN="\033[1;32m"
    BOLD="\033[1m"
    RESET="\033[0m"
    for parameter in "${parameters[@]}"; do
        if [[ "$parameter" == "-h" || "$parameter" == "--help" ]]; then
            echo "Usage: $( basename "$0" ) [-n | --no-colors] [-d | --debug]"
            exit 1
        elif [[ "$parameter" == "-n" || "$parameter" == "--no-colors" ]]; then
            RED=""
            YELLOW=""
            GREEN=""
            BOLD=""
            RESET=""
        elif [[ "$parameter" == "-d" || "$parameter" == "--debug" ]]; then
            debug=true
        fi
    done
}


basic_reqs() {
    # Prints common disclaimer and checks basic requirements.
    #
    # Args:
    #     CVE - string printed in the disclaimer
    #
    # Side effects:
    #     Exits when 'rpm' command is not available

    CVE="$1"

    # Disclaimer
    echo
    echo -e "${BOLD}This script is primarily designed to detect $CVE on supported"
    echo -e "Red Hat Enterprise Linux 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; then
        echo "'rpm' command is required, but not installed. Exiting."
        exit 1
    fi
}


check_supported_kernel() {
    # Checks if running kernel is supported.
    #
    # Args:
    #     running_kernel - kernel string as returned by 'uname -r'
    #
    # Side effects:
    #     Exits when running kernel is obviously not supported

    running_kernel="$1"

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


check_kernel() {
    # Checks kernel if it is in list of vulnerable kernels.
    #
    # Args:
    #     running_kernel - kernel string as returned by 'uname -r'
    #     vulnerable_versions - an array of vulnerable versions
    #
    # Prints:
    #     Vulnerable kernel string as returned by 'uname -r', or nothing

    running_kernel="$1"
    shift
    vulnerable_versions=( "$@" )

    for tested_kernel in "${vulnerable_versions[@]}"; do
        if [[ "$running_kernel" == *"$tested_kernel"* ]]; then
            echo "$running_kernel"
            break
        fi
    done
}


check_kpatch() {
    # Checks if specific kpatch listed in a kpatch list is applied.
    #
    # Args:
    #     kpatch_module_names - an array of kpatches
    #
    # Prints:
    #     Found kpatch, or nothing

    kpatch_module_names=( "$@" )

    # Get loaded kernel modules
    modules=$( lsmod )

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


check_package() {
    # Checks if installed package is in list of vulnerable packages.
    #
    # Args:
    #     installed_packages - installed packages string as returned by 'rpm -qa package'
    #                          (may be multiline)
    #     vulnerable_versions - an array of vulnerable versions
    #
    # Prints:
    #     First vulnerable package string as returned by 'rpm -qa package', or nothing

    installed_packages=( $1 )  # Convert to array, use word splitting
    shift
    vulnerable_versions=( "$@" )

    for tested_package in "${vulnerable_versions[@]}"; do
        for installed_package in "${installed_packages[@]}"; do
            installed_package_without_arch="${installed_package%.*}"
            if [[ "$installed_package_without_arch" == "$tested_package" ]]; then
                echo "$installed_package"
                return 0
            fi
        done
    done
}


if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
    basic_args "$@"
    basic_reqs "CVE-1000366"
    running_kernel=$( uname -r )
    check_supported_kernel "$running_kernel"

    # Get installed glibc packages
    installed_packages=$( rpm -qa "glibc" )

    # Basic checks
    vulnerable_package=$( check_package "$installed_packages" "${VULNERABLE_VERSIONS[@]}" )

    # Kernel checks
    vulnerable_kernel=$( check_kernel "$running_kernel" "${VULNERABLE_KERNELS[@]}" )
    applied_kpatch=$( check_kpatch "${KPATCH_MODULE_NAMES[@]}" )

    if [[ "$vulnerable_kernel" && ! "$applied_kpatch" ]]; then
        kernel_exploitable="true"
    fi

    # Debug prints
    if [[ "$debug" ]]; then
        echo "running_kernel = *$running_kernel*"
        echo "vulnerable_kernel = *$vulnerable_kernel*"
        echo "applied_kpatch = *$applied_kpatch*"
        echo "installed_packages = *$installed_packages*"
        echo "vulnerable_package = *$vulnerable_package*"
        echo "kernel_exploitable = *$kernel_exploitable*"
        echo
    fi

    # Results
    echo -e "Detected 'glibc' package is '${BOLD}$installed_package${RESET}'."
    echo -e "Detected 'kernel' package is '${BOLD}$running_kernel${RESET}'."

    if [[ "$vulnerable_package" ]]; then
        echo -e "${RED}This 'glibc' version is vulnerable.${RESET}"
        echo -e "Update 'glibc' package and ${YELLOW}restart the system${RESET}."
        echo -e "Follow https://access.redhat.com/security/vulnerabilities/stackguard for advice."
    else
        echo -e "${GREEN}This 'glibc' version is not vulnerable.${RESET}"
    fi

    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 the kernel vulnerability"
            echo -e "is not exploitable."
        else
            echo -e "${RED}This 'kernel' version is vulnerable.${RESET}"
            echo -e "Update 'kernel' package and ${YELLOW}restart the system${RESET}."
            echo -e "Follow https://access.redhat.com/security/vulnerabilities/stackguard for advice."
        fi
    else
        echo -e "${GREEN}This 'kernel' version is not vulnerable.${RESET}"
    fi

    if [[ "$kernel_exploitable" && "$vulnerable_package" ]]; then
        exit 2  # Both exploitable
    elif [[ "$kernel_exploitable" ]]; then
        exit 3  # Only kernel exploitable
    elif [[ "$vulnerable_package" ]]; then
        exit 4  # Only glibc exploitable
    else
        exit 0
    fi
fi
