Skip to content

Commit 361b7e8

Browse files
lubaihua33LiliDeng
authored andcommitted
Add test case verify_omi_version
1 parent 81fe31b commit 361b7e8

File tree

1 file changed

+101
-4
lines changed

1 file changed

+101
-4
lines changed

microsoft/testsuites/core/azure_image_standard.py

Lines changed: 101 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,13 @@ class AzureImageStandard(TestSuite):
296296
# 1.1
297297
_openssl_version_pattern = re.compile(r"(?:Python\s*)?(\d+\.\d+(?:\.\d+)?)")
298298

299+
# OMI-1.9.1-0 - Wed Aug 28 23:16:27 PDT 2024
300+
# ii omi 1.9.1.0 amd64 Open Management Infrastructure
301+
# omi-1.9.1-0.x86_64
302+
_omi_version_pattern = re.compile(
303+
r"(?:OMI-|omi\s+|omi-)(\d+\.\d+\.\d+(?:\.\d+|-\d+)?)"
304+
)
305+
299306
@TestCaseMetadata(
300307
description="""
301308
This test will verify that `Defaults targetpw` is not enabled in the
@@ -1330,7 +1337,7 @@ def verify_waagent_version(self, node: Node) -> None:
13301337
def verify_python_version(self, node: Node) -> None:
13311338
minimum_version = Version("3.8.0")
13321339
python_command = ["python3 --version", "python --version"]
1333-
self._check_version_by_pattern_value(
1340+
self._verify_version_by_pattern_value(
13341341
node=node,
13351342
commands=python_command,
13361343
version_pattern=self._python_version_pattern,
@@ -1357,7 +1364,7 @@ def verify_openssl_version(self, node: Node) -> None:
13571364
minimum_version = Version("3.0.0")
13581365
openssl_command = ["openssl version"]
13591366
extended_support_versions = [Version("1.1.1"), Version("1.0.2")]
1360-
self._check_version_by_pattern_value(
1367+
self._verify_version_by_pattern_value(
13611368
node=node,
13621369
commands=openssl_command,
13631370
version_pattern=self._openssl_version_pattern,
@@ -1388,7 +1395,72 @@ def verify_azure_64bit_os(self, node: Node) -> None:
13881395
f"64-bit architectures: {', '.join(str(a.value) for a in arch_64bit)}."
13891396
)
13901397

1391-
def _check_version_by_pattern_value(
1398+
@TestCaseMetadata(
1399+
description="""
1400+
This test verifies the version of the Open Management Infrastructure (OMI)
1401+
version installed on the system is not vulnerable to the "OMIGOD"
1402+
vulnerabilities.
1403+
1404+
The "OMIGOD" vulnerabilities (CVE-2021-38647, CVE-2021-38648,
1405+
CVE-2021-38645, CVE-2021-38649) were fixed in OMI version 1.6.8.1.
1406+
1407+
OMI github: https://github.com/microsoft/omi
1408+
1409+
Steps:
1410+
1. Check if OMI is installed on the system.
1411+
a. If OMI is installed, the version can be got by using
1412+
""/opt/omi/bin/omiserver --version"" command.
1413+
b. If omiserver command fails, use ""dpkg -l omi | grep omi"" and
1414+
""rpm -q omi"" to double-check whether the OMI package is installed.
1415+
c. If all the commands fail, it means OMI is not installed.
1416+
2. Verify that the version is 1.6.8.1 or later.
1417+
3. Pass if OMI is not installed or the version is secure.
1418+
""",
1419+
priority=1,
1420+
requirement=simple_requirement(supported_platform_type=[AZURE]),
1421+
)
1422+
def verify_omi_version(self, node: Node) -> None:
1423+
minimum_secure_version = Version("1.6.8.1")
1424+
# LISA has node.os.package_exists to check if a package is installed. However,
1425+
# since this test case is for Azure image certification, we prefer to use
1426+
# simpler and more generic commands to support a wider range of distributions.
1427+
# OMI supports most modern Linux platforms, including Ubuntu, Debian, CentOS,
1428+
# Oracle, Red Hat, SUSE, Rocky, and Alma. All of these distributions include
1429+
# either the dpkg command (for Debian-based systems like Ubuntu and Debian)
1430+
# or the rpm command (for RPM-based systems like CentOS and SUSE).
1431+
commands = [
1432+
"/opt/omi/bin/omiserver --version",
1433+
"dpkg -l omi | grep omi",
1434+
"rpm -q omi",
1435+
]
1436+
1437+
try:
1438+
self._verify_version_by_pattern_value(
1439+
node=node,
1440+
commands=commands,
1441+
version_pattern=self._omi_version_pattern,
1442+
minimum_version=minimum_secure_version,
1443+
library_name="OMI",
1444+
)
1445+
except LisaException as e:
1446+
if "lower than the required version" in str(e):
1447+
raise LisaException(
1448+
f"Vulnerable OMI version detected. You have an OMI framework "
1449+
f"version less than {minimum_secure_version}. "
1450+
f"Please update OMI to the version {minimum_secure_version} or "
1451+
"later. For more information, please see the OMI update guidance at"
1452+
" https://aka.ms/omi-updation."
1453+
) from e
1454+
elif "Failed to retrieve" in str(e):
1455+
node.log.info("OMI is not installed on the system. Pass the case.")
1456+
elif "Failed to parse" in str(e):
1457+
raise LisaException(
1458+
"OMI is installed but could not determine version. Please verify "
1459+
"manually that the OMI version is at least "
1460+
f"{minimum_secure_version} to prevent OMIGOD vulnerabilities."
1461+
) from e
1462+
1463+
def _verify_version_by_pattern_value(
13921464
self,
13931465
node: Node,
13941466
commands: List[str],
@@ -1398,6 +1470,21 @@ def _check_version_by_pattern_value(
13981470
library_name: str = "library",
13991471
group_index: int = 1,
14001472
) -> None:
1473+
"""
1474+
Verifies the version of a library or tool against a minimum required version.
1475+
Args:
1476+
node: The node to execute commands on
1477+
commands: List of commands to try to get version information
1478+
version_pattern: Regex pattern to extract version string from command
1479+
output
1480+
minimum_version: Minimum required version. Please use dots (.) to separate
1481+
version numbers for proper version comparison, e.g. "1.2.3" or
1482+
"1.2.3.4"
1483+
extended_support_versions: Optional list of versions that are still
1484+
supported despite being lower than minimum_version
1485+
library_name: Name of the library/tool being checked (for messages)
1486+
group_index: Index of the regex group that contains the version string
1487+
"""
14011488
version_output = None
14021489

14031490
for command in commands:
@@ -1417,7 +1504,17 @@ def _check_version_by_pattern_value(
14171504
f"Failed to parse {library_name} version from output: {version_output}"
14181505
)
14191506

1420-
current_version = Version(match.group(group_index))
1507+
# The reason we don't use 'parse_version' and 'LisaVersionInfo' here is because
1508+
# they don't support the four-part version like "1.2.3.4". Some versions of
1509+
# waagent have this format. So we use 'Version' class from 'packaging'.
1510+
#
1511+
# Version class supports multiple formats but is unable comparing versions with
1512+
# hyphens like "1.2.3-4" and "1.2.3-5". So we replace "-" with "." for proper
1513+
# version comparison.
1514+
#
1515+
# e.g. the version of OMI has the format of "1.9.0-1". Changing it to "1.9.0.1"
1516+
# allows proper comparison with the minimum version.
1517+
current_version = Version(match.group(group_index).replace("-", "."))
14211518
if current_version < minimum_version:
14221519
message = (
14231520
f"The {library_name} version {current_version} is lower than the "

0 commit comments

Comments
 (0)