From 3bc3e81b2cdc2fa9d9c72ab9620a62ef1566d35b Mon Sep 17 00:00:00 2001 From: HoussemNasri Date: Sun, 17 Sep 2023 20:26:16 +0100 Subject: [PATCH] Distinguish between zero-day vulnerabilities and vulnerabilities without a patch in synced channels --- .../rhn/manager/audit/CVEAuditManagerOVAL.java | 11 ++++++----- .../com/redhat/rhn/manager/audit/PatchStatus.java | 15 ++++++++------- web/html/src/manager/audit/cveaudit/cveaudit.tsx | 10 ++++++++-- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManagerOVAL.java b/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManagerOVAL.java index 505c565c3358..1ca723d725e4 100644 --- a/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManagerOVAL.java +++ b/java/code/src/com/redhat/rhn/manager/audit/CVEAuditManagerOVAL.java @@ -177,7 +177,9 @@ public static CVEAuditSystemBuilder doAuditSystem(String cveIdentifier, .filter(vulnerablePackage -> vulnerablePackage.getFixVersion().isEmpty()).collect( Collectors.toSet()); - if (patchedVulnerablePackages.isEmpty() && !unpatchedVulnerablePackages.isEmpty()) { + boolean allPackagesUnpatched = unpatchedVulnerablePackages.size() == clientProductVulnerablePackages.size(); + + if (allPackagesUnpatched) { cveAuditServerBuilder.setPatchStatus(PatchStatus.AFFECTED_PATCH_UNAVAILABLE); } else { @@ -187,8 +189,7 @@ public static CVEAuditSystemBuilder doAuditSystem(String cveIdentifier, Objects.equals(installedPackage.getName(), patchedPackage.getName())) .anyMatch(installedPackage -> installedPackage.getPackageEVR() - .compareTo(PackageEvr.parseRpm( - patchedPackage.getFixVersion().get())) >= 0)); + .compareTo(PackageEvr.parseRpm(patchedPackage.getFixVersion().get())) >= 0)); if (allPackagesPatched) { cveAuditServerBuilder.setPatchStatus(PatchStatus.PATCHED); @@ -250,10 +251,10 @@ else if (somePackagesHavePatchInAssignedChannels) { } else if (somePackagesHavePatchInUnassignedChannels) { //TODO: Not sure how to handle... - cveAuditServerBuilder.setPatchStatus(PatchStatus.AFFECTED_PATCH_UNAVAILABLE); + cveAuditServerBuilder.setPatchStatus(PatchStatus.AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI); } else { - cveAuditServerBuilder.setPatchStatus(PatchStatus.AFFECTED_PATCH_UNAVAILABLE); + cveAuditServerBuilder.setPatchStatus(PatchStatus.AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI); } } } diff --git a/java/code/src/com/redhat/rhn/manager/audit/PatchStatus.java b/java/code/src/com/redhat/rhn/manager/audit/PatchStatus.java index 586495b1e601..c3d07ae33d4b 100644 --- a/java/code/src/com/redhat/rhn/manager/audit/PatchStatus.java +++ b/java/code/src/com/redhat/rhn/manager/audit/PatchStatus.java @@ -21,13 +21,14 @@ public enum PatchStatus { // Values sorted by seriousness - AFFECTED_PATCH_UNAVAILABLE("Affected, patch is unavailable", 0), - AFFECTED_PATCH_INAPPLICABLE("Affected, patch available in unassigned channel", 1), - AFFECTED_PARTIAL_PATCH_APPLICABLE("Affected, partial patch available in assigned channel", 2), - AFFECTED_FULL_PATCH_APPLICABLE("Affected, full patch available in assigned channel", 3), - NOT_AFFECTED("Not affected", 4), - PATCHED("Patched", 5), - AFFECTED_PATCH_INAPPLICABLE_SUCCESSOR_PRODUCT("Affected, patch available in a Product Migration target", 6); + AFFECTED_PATCH_UNAVAILABLE("Affected, patch is unavailable anywhere", 0), + AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI("Affected, patch is unavailable in any of the synced channels", 1), + AFFECTED_PATCH_INAPPLICABLE("Affected, patch available in unassigned channel", 2), + AFFECTED_PARTIAL_PATCH_APPLICABLE("Affected, partial patch available in assigned channel", 3), + AFFECTED_FULL_PATCH_APPLICABLE("Affected, full patch available in assigned channel", 4), + NOT_AFFECTED("Not affected", 5), + PATCHED("Patched", 6), + AFFECTED_PATCH_INAPPLICABLE_SUCCESSOR_PRODUCT("Affected, patch available in a Product Migration target", 7); /** * The lower the more severe diff --git a/web/html/src/manager/audit/cveaudit/cveaudit.tsx b/web/html/src/manager/audit/cveaudit/cveaudit.tsx index e32f1c17ea3b..280f6b814d5e 100644 --- a/web/html/src/manager/audit/cveaudit/cveaudit.tsx +++ b/web/html/src/manager/audit/cveaudit/cveaudit.tsx @@ -22,10 +22,12 @@ const AFFECTED_FULL_PATCH_APPLICABLE = "AFFECTED_FULL_PATCH_APPLICABLE"; const NOT_AFFECTED = "NOT_AFFECTED"; const PATCHED = "PATCHED"; const AFFECTED_PATCH_UNAVAILABLE = "AFFECTED_PATCH_UNAVAILABLE"; +const AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI = "AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI"; const AFFECTED_PARTIAL_PATCH_APPLICABLE = "AFFECTED_PARTIAL_PATCH_APPLICABLE"; const ALL = [ AFFECTED_PATCH_UNAVAILABLE, + AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI, AFFECTED_PARTIAL_PATCH_APPLICABLE, AFFECTED_PATCH_INAPPLICABLE, AFFECTED_PATCH_INAPPLICABLE_SUCCESSOR_PRODUCT, @@ -56,7 +58,11 @@ const PATCH_STATUS_LABEL = { }, AFFECTED_PATCH_UNAVAILABLE: { className: "fa-exclamation-circle text-danger", - label: t("Affected, patch is unavailable") + label: t("Affected, patch is unavailable anywhere (possibly a zero-day vulnerability or a \"Won't fix\" )") + }, + AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI: { + className: "fa-exclamation-circle text-danger", + label: t("Affected, patch is unavailable in any of the synced channels") }, AFFECTED_PARTIAL_PATCH_APPLICABLE: { className: "fa-shield text-danger", @@ -348,7 +354,7 @@ class CVEAudit extends React.Component { cell={(row, criteria) => { if (this.state.resultType === TARGET_SERVER) { if (row.patchStatus === NOT_AFFECTED || row.patchStatus === PATCHED || - row.patchStatus === AFFECTED_PATCH_UNAVAILABLE) { + row.patchStatus === AFFECTED_PATCH_UNAVAILABLE || row.patchStatus === AFFECTED_PATCH_UNAVAILABLE_IN_UYUNI) { return t("No action required"); } else if (row.patchStatus === AFFECTED_FULL_PATCH_APPLICABLE) { return (