Hello Andrej,
This patch is splitting the Patched state, not the ignore one. This is not
incorrect CPE or anything else.

Currently Patched means one of two situations: either this issue has never
affected the code base (example: we have version 1.0, issue was introduced
in 2.0 and fixed in 2.1), or the issue has been fixed.

Yes, another reason to say ignore, not affected is a manual analysis
showing a thing like: the issue affects only windows.

Regards,
Marta


On Wed, 25 Oct 2023, 12:18 Andrej Valek, <[email protected]> wrote:

> Hi Marta,
>
> That's fine, as I said we designed the "ignore" with status
> "cpe-incorrect" or "ignored" exactly for those purposes. Extending the
> option with "not affected" doesn't make any sense.
>
> You have to set the status to "why is not affected" = "ignored". Which
> completely covers the requested case.
>
> Regards,
> Andrej
>
> On 25.10.2023 11:33, Marta Rybczynska wrote:
> > Hi Andrej,
> > This is more complex. "Not affected" is also an issue that isn't present
> in the
> > code - like when we have a version that has never had the vulnerability.
> > Those are also currently 'Patched' in cve-check.
> >
> > This work is in sync with what VEX is doing, is it the use-case
> > Matsanaga-Shinji?
> >
> > Regards,
> > Marta
> >
> > On Wed, Oct 25, 2023 at 8:44 AM Andrej Valek <[email protected]>
> wrote:
> >> Hi all,
> >>
> >> Do we really need a new "not_affected" state? I guess the ignore state
> >> is exactly designed for those purposes.
> >>
> >> Regards,
> >> Andrej
> >>
> >> On 25.10.2023 07:13, Matsunaga-Shinji wrote:
> >>> CVEs that are currently considered "Patched" are classified into the
> following 3 statuses:
> >>> 1. "Patched"      - means that a patch file that fixed the
> vulnerability has been applied
> >>> 2. "Not affected" - means that the package version (PV) is not
> affected by the vulnerability
> >>> 3. "Undecidable"  - means that versions cannot be compared to
> determine if they are affected by the vulnerability
> >>>
> >>> Signed-off-by: Shinji Matsunaga <[email protected]>
> >>> Signed-off-by: Shunsuke Tokumoto <[email protected]>
> >>> ---
> >>>
> >>> Changes for v2:
> >>>      - Fix the status "Out of range" to "Not affected"
> >>>
> >>>    meta/classes/cve-check.bbclass | 55
> +++++++++++++++++++++++-----------
> >>>    1 file changed, 38 insertions(+), 17 deletions(-)
> >>>
> >>> diff --git a/meta/classes/cve-check.bbclass
> b/meta/classes/cve-check.bbclass
> >>> index b55f4299da..502db324df 100644
> >>> --- a/meta/classes/cve-check.bbclass
> >>> +++ b/meta/classes/cve-check.bbclass
> >>> @@ -185,10 +185,10 @@ python do_cve_check () {
> >>>                    patched_cves = get_patched_cves(d)
> >>>                except FileNotFoundError:
> >>>                    bb.fatal("Failure in searching patches")
> >>> -            ignored, patched, unpatched, status = check_cves(d,
> patched_cves)
> >>> -            if patched or unpatched or
> (d.getVar("CVE_CHECK_COVERAGE") == "1" and status):
> >>> -                cve_data = get_cve_info(d, patched + unpatched +
> ignored)
> >>> -                cve_write_data(d, patched, unpatched, ignored,
> cve_data, status)
> >>> +            ignored, patched, unpatched, not_affected, undecidable,
> status = check_cves(d, patched_cves)
> >>> +            if patched or unpatched or not_affected or undecidable or
> (d.getVar("CVE_CHECK_COVERAGE") == "1" and status):
> >>> +                cve_data = get_cve_info(d, patched + unpatched +
> ignored + not_affected + undecidable)
> >>> +                cve_write_data(d, patched, unpatched, ignored,
> not_affected, undecidable, cve_data, status)
> >>>            else:
> >>>                bb.note("No CVE database found, skipping CVE check")
> >>>
> >>> @@ -308,13 +308,13 @@ def check_cves(d, patched_cves):
> >>>        products = d.getVar("CVE_PRODUCT").split()
> >>>        # If this has been unset then we're not scanning for CVEs here
> (for example, image recipes)
> >>>        if not products:
> >>> -        return ([], [], [], [])
> >>> +        return ([], [], [], [], [], [])
> >>>        pv = d.getVar("CVE_VERSION").split("+git")[0]
> >>>
> >>>        # If the recipe has been skipped/ignored we return empty lists
> >>>        if pn in d.getVar("CVE_CHECK_SKIP_RECIPE").split():
> >>>            bb.note("Recipe has been skipped by cve-check")
> >>> -        return ([], [], [], [])
> >>> +        return ([], [], [], [], [], [])
> >>>
> >>>        # Convert CVE_STATUS into ignored CVEs and check validity
> >>>        cve_ignore = []
> >>> @@ -328,6 +328,8 @@ def check_cves(d, patched_cves):
> >>>        conn = sqlite3.connect(db_file, uri=True)
> >>>
> >>>        # For each of the known product names (e.g. curl has CPEs using
> curl and libcurl)...
> >>> +    cves_not_affected = []
> >>> +    cves_undecidable = []
> >>>        for product in products:
> >>>            cves_in_product = False
> >>>            if ":" in product:
> >>> @@ -355,6 +357,7 @@ def check_cves(d, patched_cves):
> >>>
> >>>                vulnerable = False
> >>>                ignored = False
> >>> +            undecidable = False
> >>>
> >>>                product_cursor = conn.execute("SELECT * FROM PRODUCTS
> WHERE ID IS ? AND PRODUCT IS ? AND VENDOR LIKE ?", (cve, product, vendor))
> >>>                for row in product_cursor:
> >>> @@ -376,7 +379,7 @@ def check_cves(d, patched_cves):
> >>>                            except:
> >>>                                bb.warn("%s: Failed to compare %s %s %s
> for %s" %
> >>>                                        (product, pv, operator_start,
> version_start, cve))
> >>> -                            vulnerable_start = False
> >>> +                            undecidable = True
> >>>                        else:
> >>>                            vulnerable_start = False
> >>>
> >>> @@ -387,10 +390,15 @@ def check_cves(d, patched_cves):
> >>>                            except:
> >>>                                bb.warn("%s: Failed to compare %s %s %s
> for %s" %
> >>>                                        (product, pv, operator_end,
> version_end, cve))
> >>> -                            vulnerable_end = False
> >>> +                            undecidable = True
> >>>                        else:
> >>>                            vulnerable_end = False
> >>>
> >>> +                    if undecidable:
> >>> +                        bb.note("%s-%s is undecidable to %s" % (pn,
> real_pv, cve))
> >>> +                        cves_undecidable.append(cve)
> >>> +                        break
> >>> +
> >>>                        if operator_start and operator_end:
> >>>                            vulnerable = vulnerable_start and
> vulnerable_end
> >>>                        else:
> >>> @@ -406,9 +414,9 @@ def check_cves(d, patched_cves):
> >>>                        break
> >>>                product_cursor.close()
> >>>
> >>> -            if not vulnerable:
> >>> +            if not undecidable and not vulnerable:
> >>>                    bb.note("%s-%s is not vulnerable to %s" % (pn,
> real_pv, cve))
> >>> -                patched_cves.add(cve)
> >>> +                cves_not_affected.append(cve)
> >>>            cve_cursor.close()
> >>>
> >>>            if not cves_in_product:
> >>> @@ -420,7 +428,7 @@ def check_cves(d, patched_cves):
> >>>        if not cves_in_recipe:
> >>>            bb.note("No CVE records for products in recipe %s" % (pn))
> >>>
> >>> -    return (list(cves_ignored), list(patched_cves), cves_unpatched,
> cves_status)
> >>> +    return (list(cves_ignored), list(patched_cves), cves_unpatched,
> cves_not_affected, cves_undecidable, cves_status)
> >>>
> >>>    def get_cve_info(d, cves):
> >>>        """
> >>> @@ -447,7 +455,7 @@ def get_cve_info(d, cves):
> >>>        conn.close()
> >>>        return cve_data
> >>>
> >>> -def cve_write_data_text(d, patched, unpatched, ignored, cve_data):
> >>> +def cve_write_data_text(d, patched, unpatched, ignored, not_affected,
> undecidable, cve_data):
> >>>        """
> >>>        Write CVE information in WORKDIR; and to CVE_CHECK_DIR, and
> >>>        CVE manifest if enabled.
> >>> @@ -471,7 +479,7 @@ def cve_write_data_text(d, patched, unpatched,
> ignored, cve_data):
> >>>            return
> >>>
> >>>        # Early exit, the text format does not report packages without
> CVEs
> >>> -    if not patched+unpatched+ignored:
> >>> +    if not patched+unpatched+ignored+not_affected+undecidable:
> >>>            return
> >>>
> >>>        nvd_link = "https://nvd.nist.gov/vuln/detail/";
> >>> @@ -482,6 +490,8 @@ def cve_write_data_text(d, patched, unpatched,
> ignored, cve_data):
> >>>        for cve in sorted(cve_data):
> >>>            is_patched = cve in patched
> >>>            is_ignored = cve in ignored
> >>> +        is_not_affected = cve in not_affected
> >>> +        is_undecidable = cve in undecidable
> >>>
> >>>            status = "Unpatched"
> >>>            if (is_patched or is_ignored) and not report_all:
> >>> @@ -490,6 +500,10 @@ def cve_write_data_text(d, patched, unpatched,
> ignored, cve_data):
> >>>                status = "Ignored"
> >>>            elif is_patched:
> >>>                status = "Patched"
> >>> +        elif is_not_affected:
> >>> +            status = "Not affected"
> >>> +        elif is_undecidable:
> >>> +            status = "Undecidable"
> >>>            else:
> >>>                # default value of status is Unpatched
> >>>                unpatched_cves.append(cve)
> >>> @@ -561,7 +575,7 @@ def cve_check_write_json_output(d, output,
> direct_file, deploy_file, manifest_fi
> >>>            with open(index_path, "a+") as f:
> >>>                f.write("%s\n" % fragment_path)
> >>>
> >>> -def cve_write_data_json(d, patched, unpatched, ignored, cve_data,
> cve_status):
> >>> +def cve_write_data_json(d, patched, unpatched, ignored, not_affected,
> undecidable, cve_data, cve_status):
> >>>        """
> >>>        Prepare CVE data for the JSON format, then write it.
> >>>        """
> >>> @@ -606,6 +620,9 @@ def cve_write_data_json(d, patched, unpatched,
> ignored, cve_data, cve_status):
> >>>        for cve in sorted(cve_data):
> >>>            is_patched = cve in patched
> >>>            is_ignored = cve in ignored
> >>> +        is_not_affected = cve in not_affected
> >>> +        is_undecidable = cve in undecidable
> >>> +
> >>>            status = "Unpatched"
> >>>            if (is_patched or is_ignored) and not report_all:
> >>>                continue
> >>> @@ -613,6 +630,10 @@ def cve_write_data_json(d, patched, unpatched,
> ignored, cve_data, cve_status):
> >>>                status = "Ignored"
> >>>            elif is_patched:
> >>>                status = "Patched"
> >>> +        elif is_not_affected:
> >>> +            status = "Not affected"
> >>> +        elif is_undecidable:
> >>> +            status = "Undecidable"
> >>>            else:
> >>>                # default value of status is Unpatched
> >>>                unpatched_cves.append(cve)
> >>> @@ -645,12 +666,12 @@ def cve_write_data_json(d, patched, unpatched,
> ignored, cve_data, cve_status):
> >>>
> >>>        cve_check_write_json_output(d, output, direct_file,
> deploy_file, manifest_file)
> >>>
> >>> -def cve_write_data(d, patched, unpatched, ignored, cve_data, status):
> >>> +def cve_write_data(d, patched, unpatched, ignored, not_affected,
> undecidable, cve_data, status):
> >>>        """
> >>>        Write CVE data in each enabled format.
> >>>        """
> >>>
> >>>        if d.getVar("CVE_CHECK_FORMAT_TEXT") == "1":
> >>> -        cve_write_data_text(d, patched, unpatched, ignored, cve_data)
> >>> +        cve_write_data_text(d, patched, unpatched, ignored,
> not_affected, undecidable, cve_data)
> >>>        if d.getVar("CVE_CHECK_FORMAT_JSON") == "1":
> >>> -        cve_write_data_json(d, patched, unpatched, ignored, cve_data,
> status)
> >>> +        cve_write_data_json(d, patched, unpatched, ignored,
> not_affected, undecidable, cve_data, status)
> >>>
> >>> 
> >>>
>
>
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#189676): 
https://lists.openembedded.org/g/openembedded-core/message/189676
Mute This Topic: https://lists.openembedded.org/mt/102172913/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to