From 4c7e3b64bc9cefb05fa4a995e83bb0f90160a9fc Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Fri, 6 Aug 2021 12:33:04 +0200 Subject: manuals: further documentation for cve-check This adds details about the actual implementation of vulnerability checks, about how to fix or ignore vulnerabilities in recipes, and documents the CVE_CHECK_PN_WHITELIST and CVE_CHECK_WHITELIST variables. (From yocto-docs rev: 55886d211218b3a604c2f8a29c854685ebf284dd) Signed-off-by: Michael Opdenacker Reviewed-by: Quentin Schulz Signed-off-by: Richard Purdie --- documentation/dev-manual/common-tasks.rst | 69 +++++++++++++++++++++++++++++++ documentation/ref-manual/classes.rst | 16 +++++++ documentation/ref-manual/variables.rst | 13 +++++- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/documentation/dev-manual/common-tasks.rst b/documentation/dev-manual/common-tasks.rst index 7fa0df4d39..37077d72d4 100644 --- a/documentation/dev-manual/common-tasks.rst +++ b/documentation/dev-manual/common-tasks.rst @@ -11131,6 +11131,75 @@ Enabling vulnerabily tracking in recipes The :term:`CVE_PRODUCT` variable defines the name used to match the recipe name against the name in the upstream `NIST CVE database `__. +Editing recipes to fix vulnerabilities +-------------------------------------- + +To fix a given known vulnerability, you need to add a patch file to your recipe. Here's +an example from the :oe_layerindex:`ffmpeg recipe`:: + + SRC_URI = "https://www.ffmpeg.org/releases/${BP}.tar.xz \ + file://0001-libavutil-include-assembly-with-full-path-from-sourc.patch \ + file://fix-CVE-2020-20446.patch \ + file://fix-CVE-2020-20453.patch \ + file://fix-CVE-2020-22015.patch \ + file://fix-CVE-2020-22021.patch \ + file://fix-CVE-2020-22033-CVE-2020-22019.patch \ + file://fix-CVE-2021-33815.patch \ + +The :ref:`cve-check ` class defines two ways of +supplying a patch for a given CVE. The first +way is to use a patch filename that matches the below pattern:: + + cve_file_name_match = re.compile(".*([Cc][Vv][Ee]\-\d{4}\-\d+)") + +As shown in the example above, multiple CVE IDs can appear in a patch filename, +but the :ref:`cve-check ` class will only consider +the last CVE ID in the file name as patched. + +The second way to recognize a patched CVE ID is when a line matching the +below pattern is found in any patch file provided by the recipe:: + + cve_match = re.compile("CVE:( CVE\-\d{4}\-\d+)+") + +This allows a single patch file to address multiple CVE IDs at the same time. + +Of course, another way to fix vulnerabilities is to upgrade to a version +of the package which is not impacted, typically a more recent one. +The NIST database knows which versions are vulnerable and which ones +are not. + +Last but not least, you can choose to ignore vulnerabilities through +the :term:`CVE_CHECK_PN_WHITELIST` and :term:`CVE_CHECK_WHITELIST` +variables. + +Implementation details +---------------------- + +Here's what the :ref:`cve-check ` class does to +find unpatched CVE IDs. + +First the code goes through each patch file provided by a recipe. If a valid CVE ID +is found in the name of the file, the corresponding CVE is considered as patched. +Don't forget that if multiple CVE IDs are found in the file name, only the last +one is considered. Then, the code looks for ``CVE: CVE-ID`` lines in the patch +file. The found CVE IDs are also considered as patched. + +Then, the code looks up all the CVE IDs in the NIST database for all the +products defined in :term:`CVE_PRODUCT`. Then, for each found CVE: + + - If the package name (:term:`PN`) is part of + :term:`CVE_CHECK_PN_WHITELIST`, it is considered as patched. + + - If the CVE ID is part of :term:`CVE_CHECK_WHITELIST`, it is + considered as patched too. + + - If the CVE ID is part of the patched CVE for the recipe, it is + already considered as patched. + + - Otherwise, the code checks whether the recipe version (:term:`PV`) + is within the range of versions impacted by the CVE. If so, the CVE + is considered as unpatched. + The CVE database is stored in :term:`DL_DIR` and can be inspected using ``sqlite3`` command as follows:: diff --git a/documentation/ref-manual/classes.rst b/documentation/ref-manual/classes.rst index 49905f2725..a98a64c432 100644 --- a/documentation/ref-manual/classes.rst +++ b/documentation/ref-manual/classes.rst @@ -404,6 +404,22 @@ cross-compilation tools used for building SDKs. See the section in the Yocto Project Overview and Concepts Manual for more discussion on these cross-compilation tools. +.. _ref-classes-cve-check: + +``cve-check.bbclass`` +===================== + +The ``cve-check`` class looks for known CVEs (Common Vulnerabilities +and Exposures) while building an image. This class is meant to be +inherited globally from a configuration file:: + + INHERIT += "cve-check" + +You can also look for vulnerabilities in specific packages by passing +``-c cve_check`` to BitBake. You will find details in the +":ref:`dev-manual/common-tasks:checking for vulnerabilities`" +section in the Development Tasks Manual. + .. _ref-classes-debian: ``debian.bbclass`` diff --git a/documentation/ref-manual/variables.rst b/documentation/ref-manual/variables.rst index 1150940133..f6d248a193 100644 --- a/documentation/ref-manual/variables.rst +++ b/documentation/ref-manual/variables.rst @@ -1471,11 +1471,22 @@ system and gives an overview of their function and contents. variable only in certain contexts (e.g. when building for kernel and kernel module recipes). + :term:`CVE_CHECK_PN_WHITELIST` + The list of package names (:term:`PN`) for which + CVEs (Common Vulnerabilities and Exposures) are ignored. + + :term:`CVE_CHECK_WHITELIST` + The list of CVE IDs which are ignored. Here is + an example from the :oe_layerindex:`Python3 recipe`:: + + # This is windows only issue. + CVE_CHECK_WHITELIST += "CVE-2020-15523" + :term:`CVE_PRODUCT` In a recipe, defines the name used to match the recipe name against the name in the upstream `NIST CVE database `__. - The default is ${:term:`BPN`}. If it does not match the name in NIST CVE + The default is ${:term:`BPN`}. If it does not match the name in the NIST CVE database or matches with multiple entries in the database, the default value needs to be changed. -- cgit v1.2.3-54-g00ecf