Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
Hello Matsunaga-Shinji, On Wed, 25 Oct 2023 14:13:44 +0900 "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 > Signed-off-by: Shunsuke Tokumoto This patch triggers a selftest failure: AssertionError: 'Not affected' != 'Patched' - Not affected + Patched https://autobuilder.yoctoproject.org/typhoon/#/builders/127/builds/2329/steps/15/logs/stdio https://autobuilder.yoctoproject.org/typhoon/#/builders/80/builds/5912/steps/14/logs/stdio https://autobuilder.yoctoproject.org/typhoon/#/builders/79/builds/5962/steps/14/logs/stdio Luca -- Luca Ceresoli, Bootlin Embedded Linux and Kernel engineering https://bootlin.com -=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#189701): https://lists.openembedded.org/g/openembedded-core/message/189701 Mute This Topic: https://lists.openembedded.org/mt/102172913/21656 Group Owner: openembedded-core+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
Hello Marko, I think that we will need to go back to the drawing board and have a look what we want to report from the CVE check. I'm not totally happy with the solution proposed here, because it is adding high-level states. However, it is a step forward to be able to map our status to VEX. In the RFQ work on SPDX3 (which includes VEX in the "security" profile) we had a look at that and realized that mapping of the information is not possible, we're missing information. The current state of "Ignore" is not great either. You have added additional context, but still some statuses do not make sense in Ignore. It is effectively used as an "override" of everything. I also have a multi-fetcher in the works, which downloads CVE data from other sources that NVD. Results are sometimes in conflict and we'll have to handle that too. And there are other sources lurking behind too. So, when the RFQ season is finished (Oct 31st), we'll get back to the drawing board to design what statuses we really want and need. I understand you'd like to be a part of this discussion. Kind regards, Marta On Wed, Oct 25, 2023 at 3:09 PM Marko, Peter wrote: > > Hello Marta, > > > > Major reason why we introduced CVE_STATUS was exactly to avoid patch like > this. > > There were ideas to introduce 5 or 10 or 15 different statuses and we decided > to keep 3 and introduce “sub-statuses”. > > These sub-statuses are listed in cve reports, too. > > > > Currently we have three main statuses: > > Patched – common status for all sub-statuses which indicate that component is > not vulnerable > > Unpatched - common status for all sub-statuses which indicate that component > is vulnerable > > Ignored - common status for all sub-statuses which indicate that component is > vulnerable but not in yocto configuration context > > > > If we don’t like “Patched” we can rename it (e.g. to “Unaffected”) and have > additional sub-statuses under this new name. > > Otherwise we start exploding the statuses as someone will “need” additional > one soon. > > > > If we really want to introduce these new statues (I hope not), please modify > this patch to handle its CVE_STATUS flags, too. > > Additionally, I’d drop “Undecidable” and map it to “Unpatched” (so someone > needs to analyze as any other open vulnerability report) > > > > Best Regards, > > Peter > > > > From: Marta Rybczynska > Sent: Wednesday, October 25, 2023 14:44 > To: Andrej Valek > Cc: Matsunaga-Shinji ; Richard Purdie > ; OE-core > ; Shunsuke Tokumoto > ; Marko, Peter (ADV D EU SK BFS1) > > Subject: Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 > statuses > > > > 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, 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 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. &qu
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
Hello Marta, Major reason why we introduced CVE_STATUS was exactly to avoid patch like this. There were ideas to introduce 5 or 10 or 15 different statuses and we decided to keep 3 and introduce “sub-statuses”. These sub-statuses are listed in cve reports, too. Currently we have three main statuses: Patched – common status for all sub-statuses which indicate that component is not vulnerable Unpatched - common status for all sub-statuses which indicate that component is vulnerable Ignored - common status for all sub-statuses which indicate that component is vulnerable but not in yocto configuration context If we don’t like “Patched” we can rename it (e.g. to “Unaffected”) and have additional sub-statuses under this new name. Otherwise we start exploding the statuses as someone will “need” additional one soon. If we really want to introduce these new statues (I hope not), please modify this patch to handle its CVE_STATUS flags, too. Additionally, I’d drop “Undecidable” and map it to “Unpatched” (so someone needs to analyze as any other open vulnerability report) Best Regards, Peter From: Marta Rybczynska Sent: Wednesday, October 25, 2023 14:44 To: Andrej Valek Cc: Matsunaga-Shinji ; Richard Purdie ; OE-core ; Shunsuke Tokumoto ; Marko, Peter (ADV D EU SK BFS1) Subject: Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses 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, mailto:andre...@skyrain.eu>> 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 > mailto:andre...@skyrain.eu>> 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 >>> mailto:shin.matsun...@fujitsu.com>> >>> Signed-off-by: Shunsuke Tokumoto >>> mailto:s-tokum...@fujitsu.com>> >>> --- >>> >>> 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_in
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
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, 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 > 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 > >>> Signed-off-by: Shunsuke Tokumoto > >>> --- > >>> > >>> 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 > >>>
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
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 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 Signed-off-by: Shunsuke Tokumoto --- 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 +
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
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 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 > > Signed-off-by: Shunsuke Tokumoto > > --- > > > > 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 > > +
Re: [OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
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 Signed-off-by: Shunsuke Tokumoto --- 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
[OE-core] [PATCH v2] cve-check: Classify patched CVEs into 3 statuses
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 Signed-off-by: Shunsuke Tokumoto --- 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