Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(oracle-oval): Support multiple ELSAs per CVE #221

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

bpfoster
Copy link

@bpfoster bpfoster commented Jun 6, 2022

This is notably important for when there are additional FIPS and ksplice package patches available.

Adjust persisted advisory details object to be more like the RedHat object - each CVE key contains an array of Entries - each entry contains the fix version and associated ELSAs for different package flavors.
We keep the FixedVersion field at the top of the object to preserve backwards compatibility with older clients.

Since ELSA title and description can be different between the two, do not specify those in the vulnerability details, failing back to the defaults.

Inspecting the database for something like Oracle Linux 8 / gnutls, you can see it now changes from:

CVE-2019-3829 - {
  "FixedVersion":"3.6.8-8.el8"
}
CVE-2019-3836 - {
  "FixedVersion":"3.6.8-8.el8"
}
CVE-2020-11501 - {
  "FixedVersion":"3.6.8-10.el8_2"
}
CVE-2020-13777 - {
  "FixedVersion":"3.6.8-11.el8_2"
}
CVE-2020-24659 - {
  "FixedVersion":"3.6.14-7.el8_3"
}
CVE-2021-20231 - {
  "FixedVersion":"10:3.6.16-4.0.1.el8_fips"     // incorrect - this results in reported vulnerabilities on a patched normal package
}
CVE-2021-20232 - {
  "FixedVersion":"10:3.6.16-4.0.1.el8_fips"     // incorrect - this results in reported vulnerabilities on a patched normal package
}
CVE-2021-20305 - {
  "FixedVersion":"3.6.14-8.el8_3"
}
CVE-2021-3580 - {
  "FixedVersion":"10:3.6.16-4.0.1.el8_fips"     // incorrect - this results in reported vulnerabilities on a patched normal package
}

to:

CVE-2019-3829 - {
  "FixedVersion":"3.6.8-8.el8",
  "Entries": [
    {
      "FixedVersion": "3.6.8-8.el8",
      "VendorIDs": [
        "ELSA-2019-3600"
      ]
    }
  ]
}
CVE-2019-3836 - {
  "FixedVersion":"3.6.8-8.el8",
  "Entries": [
    {
      "FixedVersion": "3.6.8-8.el8",
      "VendorIDs": [
        "ELSA-2019-3600"
      ]
    }
  ]
}
CVE-2020-11501 - {
  "FixedVersion":"3.6.8-10.el8_2",
  "Entries": [
    {
      "FixedVersion": "3.6.8-10.el8_2",
      "VendorIDs": [
        "ELSA-2020-1998"
      ]
    }
  ]
}
CVE-2020-13777 - {
  "FixedVersion":"3.6.8-11.el8_2",
  "Entries": [
    {
      "FixedVersion": "3.6.8-11.el8_2",
      "VendorIDs": [
        "ELSA-2020-2637"
      ]
    }
  ]
}
CVE-2020-24659 - {
  "FixedVersion":"3.6.14-7.el8_3",
  "Entries": [
    {
      "FixedVersion": "3.6.14-7.el8_3",
      "VendorIDs": [
        "ELSA-2020-5483"
      ]
    }
  ]
}
CVE-2021-20231 - {
  "FixedVersion":"3.6.16-4.el8",
  "Entries": [
    {
      "FixedVersion": "3.6.16-4.el8",
      "VendorIDs": [
        "ELSA-2021-4451"
      ]
    },
    {
      "FixedVersion": "10:3.6.16-4.0.1.el8_fips",
      "VendorIDs": [
        "ELSA-2022-9221"
      ]
    }
  ]
}
CVE-2021-20232 - {
  "FixedVersion":"3.6.16-4.el8",
  "Entries": [
    {
      "FixedVersion": "3.6.16-4.el8",
      "VendorIDs": [
        "ELSA-2021-4451"
      ]
    },
    {
      "FixedVersion": "10:3.6.16-4.0.1.el8_fips",
      "VendorIDs": [
        "ELSA-2022-9221"
      ]
    }
  ]
}
CVE-2021-20305 - {
  "FixedVersion":"3.6.14-8.el8_3",
  "Entries": [
    {
      "FixedVersion": "3.6.14-8.el8_3",
      "VendorIDs": [
        "ELSA-2021-1206"
      ]
    }
  ]
}
CVE-2021-3580 - {
  "FixedVersion":"3.6.16-4.el8",
  "Entries": [
    {
      "FixedVersion": "3.6.16-4.el8",
      "VendorIDs": [
        "ELSA-2021-4451"
      ]
    },
    {
      "FixedVersion": "10:3.6.16-4.0.1.el8_fips",
      "VendorIDs": [
        "ELSA-2022-9221"
      ]
    }
  ]
}

See that previously, CVEs CVE-2021-20231, CVE-2021-20232 and CVE-2021-3580 only had fix versions for the FIPS package. We now have fix version for both the FIPS package and the normal one.

This also now supports multiple ELSAs per CVE, rolling up to the latest fixed version. For example:

Oracle Linux 8 / kernel-uek
CVE-2020-28374 - {
  "FixedVersion": "5.4.17-2102.202.5.el8uek",
  "Entries": [
    {
      "FixedVersion": "5.4.17-2102.202.5.el8uek",
      "VendorIDs": [
        "ELSA-2021-9006",
        "ELSA-2021-9037",
        "ELSA-2021-9306"
      ]
    }
  ]
}

Much like FIPS, Ksplice handling is also improved and accounted for:

Oracle Linux 8 / glibc
CVE-2021-3326 - {
  "FixedVersion": "2.28-151.0.1.el8"
  "Entries": [
    {
      "FixedVersion": "2.28-151.0.1.el8",
      "VendorIDs": [
        "ELSA-2021-1585"
      ]
    },
    {
      "FixedVersion": "2:2.28-151.0.1.ksplice2.el8",
      "VendorIDs": [
        "ELSA-2021-9280",
        "ELSA-2021-9344"
      ]
    }
  ]
}

fixes #220

This is notably important for when there are additional FIPS and ksplice
package patches available
@DmitriyLewen
Copy link
Contributor

DmitriyLewen commented Jun 7, 2022

Hello @bpfoster
I am working with this problem, too.

What do you think about ELSAs with different fixed versions(non fips or ksplice) for one CVE?
e.g.:
CVE-2021-23133:

Oracle Linux version 8 (kernel-uek)  ELSA-2021-9306  2021-06-15
Oracle Linux version 8 (kernel-uek)  ELSA-2021-9362  2021-07-16

from ELSA-2021-9306:

Oracle Linux 8 (aarch64)kernel-uek-5.4.17-2102.202.5.el8uek.src.rpm

from ELSA-2021-9362:

Oracle Linux 8 (aarch64)kernel-uek-5.4.17-2102.203.5.el8uek.src.rpm

@bpfoster
Copy link
Author

bpfoster commented Jun 7, 2022

@DmitriyLewen Ah yes, that is a good point.

What if we revert the change to the advisory-details key back to CVE ID, and instead change the structure of the value?

For example, the two cases we're talking about would then be:

Path: Oracle Linux 8 → gnutls → CVE-2021-20232
Key: CVE-2021-20232
Value:
{
  "Entries": [
    {
      "FixedVersion": "3.6.16-4.el8",
      "VendorIDs": [
        "ELSA-2021-4451"
      ]
    },
    {
      "FixedVersion": "10:3.6.16-4.0.1.el8_fips",
      "VendorIDs": [
        "ELSA-2022-9221"
      ]
    }
  ]
}

and

Path: Oracle Linux 8 → kernel-uek → CVE-2021-23133
Key: CVE-2021-23133
Value:
{
  "Entries": [
    {
      "FixedVersion": "5.4.17-2102.203.5.el8uek",
      "VendorIDs": [
        "ELSA-2021-9306",
        "ELSA-2021-9362"
      ]
    }
  ]
}

Collapsing CVE-2021-23133 into a single fixed version would require scanning and merging all the advisories ahead of saving them to the database, and could use version.NewVersion().Compare() to determine the latest one to use?

While we're here, we may also want to add architecture support as the ELSAs can contain information for multiple architectures? I'm not sure if the versions ever actually differ between the archs.

Pushed up another commit with changes as described above. Think this should work for these cases.

pkg/vulnsrc/oracle-oval/oracle-oval.go Outdated Show resolved Hide resolved
pkg/vulnsrc/oracle-oval/oracle-oval.go Outdated Show resolved Hide resolved
pkg/vulnsrc/oracle-oval/oracle-oval.go Outdated Show resolved Hide resolved
pkg/vulnsrc/oracle-oval/oracle-oval.go Outdated Show resolved Hide resolved
- Simplify data structures
- Reduce loops
- Refactor out functions
- Cleanup syntax
ksplice1 and ksplice2 are not different flavors.
ksplice2 is a second revision to the userspace ksplice support code.

X.ksplice2 > X.ksplice1
@knqyf263
Copy link
Collaborator

I'm so sorry to be late.

I was hopeful trivy/trivy-db had run into schema changes before and had a solution in hand already 🙃

We have it as Trivy DB is now version 2.

Rev the database version and maintain the 2 schemas/versions for some time. Not sure the infrastructure is in place to support this already.

As you said, we have to maintain multiple versions. We already maintain Trivy DB v1 and v2 and it is already hard. Adding v3 makes it harder. We should avoid it as much as possible.

What if we use ELSA-ID as a key? Did you already discuss it? I'm sorry if I missed it.

ELSA-2019-3600 - {
  "FixedVersion":"3.6.8-8.el8",
}
ELSA-2020-1998 - {
  "FixedVersion":"3.6.8-10.el8_2",
}

It increases the database size since we cannot reuse the CVE-ID detail in vulnerability-detail. We may want to have CveIDs.

ELSA-2019-3600 - {
  "FixedVersion":"3.6.8-8.el8",
  "CveIDs": []string{"CVE-2019-3829", "CVE-2019-3836"}.
}

But it doesn't work if there are several fixed versions in the same ELSA-ID.

@bpfoster
Copy link
Author

bpfoster commented Jun 28, 2022

What if we use ELSA-ID as a key? Did you already discuss it? I'm sorry if I missed it.

I did initially take that approach. There were some complications with it and I switched back to using CVE as the key. It is most likely feasible to use ELSA ID as the key, but I think we have come to a solution with CVE ID as the key that works for all identified cases and still preserves pretty good backwards compatibility. Is there something I have missed there that ELSA ID as the key solves?

I see a couple concerns with the schema you've proposed:

  1. Unless I'm overlooking something, backwards compatibility is diminished - because ELSA ID is used as the key and not the CVE ID, older clients utilizing the database will not be able to resolve the CVE and will report results like the following:
┌────────────────────────┬────────────────┬──────────┬─────────────────────┬──────────────────────────┬─────────────────────────────────────────────────────┐
│        Library         │ Vulnerability  │ Severity │  Installed Version  │      Fixed Version       │                        Title                        │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤
│ cyrus-sasl-lib         │ ELSA-2022-0658 │ HIGH     │ 2.1.27-5.el8        │ 2.1.27-6.el8_5           │ https://linux.oracle.com/errata/ELSA-2022-0658.html │
├────────────────────────┼────────────────┤          ├─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤
│ expat                  │ ELSA-2022-0951 │          │ 2.2.5-4.el8         │ 2.2.5-4.el8_5.3          │ https://linux.oracle.com/errata/ELSA-2022-0951.html │
│                        ├────────────────┤          │                     ├──────────────────────────┼─────────────────────────────────────────────────────┤
│                        │ ELSA-2022-9232 │          │                     │ 2.2.5-4.0.1.el8_5.3      │ https://linux.oracle.com/errata/ELSA-2022-9232.html │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤

Keeping CVE ID as the key yields more familiar results on an older client:

┌────────────────────────┬────────────────┬──────────┬─────────────────────┬──────────────────────┬──────────────────────────────────────────────────────────────┐
│        Library         │ Vulnerability  │ Severity │  Installed Version  │    Fixed Version     │                            Title                             │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────┼──────────────────────────────────────────────────────────────┤
│ cyrus-sasl-lib         │ CVE-2022-24407 │ HIGH     │ 2.1.27-5.el8        │ 2.1.27-6.el8_5       │ cyrus-sasl: failure to properly escape SQL input allows an   │
│                        │                │          │                     │                      │ attacker to execute...                                       │
│                        │                │          │                     │                      │ https://avd.aquasec.com/nvd/cve-2022-24407                   │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────┼──────────────────────────────────────────────────────────────┤
│ expat                  │ CVE-2022-25235 │ CRITICAL │ 2.2.5-4.el8         │ 2.2.5-4.el8_5.3      │ expat: Malformed 2- and 3-byte UTF-8 sequences can lead to   │
│                        │                │          │                     │                      │ arbitrary code...                                            │
│                        │                │          │                     │                      │ https://avd.aquasec.com/nvd/cve-2022-25235                   │
│                        ├────────────────┤          │                     │                      ├──────────────────────────────────────────────────────────────┤
│                        │ CVE-2022-25236 │          │                     │                      │ expat: Namespace-separator characters in "xmlns[:prefix]"    │
│                        │                │          │                     │                      │ attribute values can lead to arbitrary code...               │
│                        │                │          │                     │                      │ https://avd.aquasec.com/nvd/cve-2022-25236                   │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────┼──────────────────────────────────────────────────────────────┤
  1. It is not as flexible as the Entries approach. Trivy does not currently support it for Oracle Linux, but once the dust settles on this I would propose adding support for architectures on the entry. To your point of "if there are several fixed versions in the same ELSA-ID" - There are cases where an ELSA only applies to 1 architecture (ELSA-2022-9496 for example), and there are cases where an ELSA has different versions for different architectures (ELSA-2022-4803 for example). Introducing an Arches field to Entry would be a non-breaking change.

All that said, if you have suggestions on how to improve this, I'm happy to make them so we can move this forward.

@bpfoster
Copy link
Author

bpfoster commented Jul 7, 2022

@knqyf263 @DmitriyLewen I apologize if my last reply was too strong. I'd be happy to make some changes here if there's something you'd like done.

@bpfoster
Copy link
Author

@knqyf263 @DmitriyLewen checking in... anything needed here? Thanks!

@CLAassistant
Copy link

CLAassistant commented Aug 29, 2022

CLA assistant check
All committers have signed the CLA.

@DmitriyLewen
Copy link
Contributor

DmitriyLewen commented Aug 30, 2022

@knqyf263 if i remember correctly - if we use ELSAs we still need to change db structure. Because ELSA can include multiple versions (e.g. default, fips and ksplice) and we can't save them in FixedVersion field. We need to use a different field for this, ut old Trivy uses this field to get version.
uses this field to get the version.
Then we need to store the versions in 2 fields.

@bpfoster am i right?

@bpfoster
Copy link
Author

@DmitriyLewen I don't think there's anything technically restricting ELSAs from including multiple flavors (default, fips, and ksplice), but it looks like it's Oracle's practice to split them into separate ELSAs. All the one's I've looked at are specific to the flavor.

While out of scope of this change, I would like to point out that the ELSAs support multiple architectures, and there are cases that a single ELSA has different versions for different architectures. See ELSA-2022-4803 for example, which has rsyslog-8.24.0-57.0.4.el7_9.3 for aarch64 and rsyslog-8.24.0-57.0.1.el7_9.3 for x86_64.

Trivy does not currently support architectures for Oracle Linux, but does for RedHat. If we change the key to ELSA ID and leave the database schema as-is with just a FixedVersion, you could not support this in the future. If however we change the schema to what you and I had discussed earlier with a list of Entries (similar to the way RedHat is handled), then we could easily add architecture to the entries (also similar to how the RedHat sources are handeled).

If the changes in this PR are merged in and you have interest in it, I would be happy to submit a change request to add architecture support in the future. If you'd rather fix it all at once, I'd be happy to incorporate that into this PR as well.

From that standpoint, we could use ELSA ID as the key, and use the modified value schema to support this, if there is benefit in using ELSA ID as the key instead of CVE ID.

It is unfortunate that we duplicate the version of the default package in the value, but I'm not sure there's an alternative that both provides the flexibility to solve all these issues and maintains backwards compatibility.

I did have one concern with using ELSA ID as the key, regardless of the structure of the value.
Since we've been emphasizing backwards compatibility - I believe, but could very well be mistaken, that this would provide a degraded report for older clients. This is not a huge issue, but worth mentioning.

Because the existing oracle vulnsrc does not translate the DB vulnerability ID to CVE ID like the redhat one does, the report on an older client will show the ELSA ID as the vulnerability ID instead of CVE ID, and won't include the vulnerability information:

┌────────────────────────┬────────────────┬──────────┬─────────────────────┬──────────────────────────┬─────────────────────────────────────────────────────┐
│        Library         │ Vulnerability  │ Severity │  Installed Version  │      Fixed Version       │                        Title                        │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤
│ cyrus-sasl-lib         │ ELSA-2022-0658 │ HIGH     │ 2.1.27-5.el8        │ 2.1.27-6.el8_5           │ https://linux.oracle.com/errata/ELSA-2022-0658.html │
├────────────────────────┼────────────────┤          ├─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤
│ expat                  │ ELSA-2022-0951 │          │ 2.2.5-4.el8         │ 2.2.5-4.el8_5.3          │ https://linux.oracle.com/errata/ELSA-2022-0951.html │
│                        ├────────────────┤          │                     ├──────────────────────────┼─────────────────────────────────────────────────────┤
│                        │ ELSA-2022-9232 │          │                     │ 2.2.5-4.0.1.el8_5.3      │ https://linux.oracle.com/errata/ELSA-2022-9232.html │
├────────────────────────┼────────────────┼──────────┼─────────────────────┼──────────────────────────┼─────────────────────────────────────────────────────┤

I hope that clears up my earlier comments. If I'm wrong on any analysis, please feel free to correct me, and I'm happy to make any changes requested. Looking forward to getting this resolved so I can stop getting false positives on FIPS versions 😄 .

Copy link
Contributor

@DmitriyLewen DmitriyLewen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

research on the choice of structure and dimensions of the various options can be seen here - #452

versions := lo.Values(fixedVers)
slices.Sort(versions)

fixedVersion := fixedVers[NormalPackageFlavor]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this case.
Should we use fips or ksplice version here?

example - https://linux.oracle.com/errata/ELSA-2016-3515.html

Comment on lines 255 to 256
Ksplice1PackageFlavor PkgFlavor = "ksplice1"
Ksplice2PackageFlavor PkgFlavor = "ksplice2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use ksplice1 flavor for ksplice2 (and vice versa) in Trivy:
https://github.com/aquasecurity/trivy/blob/dd0a64a1cf0cd76e6f81e3ff55fa6ccb95ce3c3d/pkg/detector/ospkg/oracle/oracle.go#L72-L77

So i separated ksplice1 and ksplice2.
After these changes db size increased to 0.9MB:

➜  du -sh ./assets-with-flavors
539M	./assets-with-flavors
➜  du -sh ./assets             
540M	./assets 

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been long enough that I've lost track of all the details on this, but I did want to pass along some information I got from @tvierling (from the Oracle Linux support/development group) when I was working though this. I won't quote his email directly without his permission, but the gist of it is that ksplice is the flavor, and the number after ksplice is just a revision / build number (which should be considered.. x.y.z.ksplice2 > x.y.z.ksplice1). So I don't think you want to separate out as different flavors.

Copy link
Contributor

@DmitriyLewen DmitriyLewen Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @bpfoster
I'm glad you're still here and helping with this task.
Sorry we're working on this after so long...

Also, I want to thank you for your work! Our work with you helped me remember the details and update this PR.

but the gist of it is that ksplice is the flavor, and the number after ksplice is just a revision / build number (which should be considered.. x.y.z.ksplice2 > x.y.z.ksplice1). So I don't think you want to separate out as different flavors.

I originally used your PackageFlavor function.
But I was confused that we separate ksplice1 and ksplice2 in Trivy and i updated PR.

But since the person from Oracle Linux says that we shouldn't divide them, then there is a mistake in our logic Trivy.

Thanks! I will revert last commit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done - a135499

@knqyf263
Copy link
Collaborator

knqyf263 commented Nov 7, 2024

@santhosh1729 Can you also please review this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

DB does not contain all advisories for Oracle Linux
4 participants