The volume and complexity of the software running in embedded devices is not only astonishing but ever increasing – yet each additional line of code has the potential to introduce a security vulnerability. An attacker may only need to exploit one single vulnerability for a bad outcome to occur. Therefore the obvious way to reduce risk and to reduce the attack surface is to remove all software that isn’t required and disable unused features. But what about the software that is required? In this post we’re going to look at how we can use Yocto to identify known vulnerabilities in software packages.
When security vulnerabilities are identified in software, those that are aware of the vulnerability may create a public record of it in the Common Vulnerabilities and Exposures (CVE) database. Each vulnerability is identified by a CVE identifier and holds a brief description of the issue and a link to information about the vulnerability. This provides a valuable tool for those building secure products as they can use the database to determine if a particular version of a software package has any known vulnerabilities. In fact there are various applications (for example cve-check-tool) and web sites (such as cvedetails.com) that provide ways to search for packages within the CVE (and related) databases.
Yocto provides a cve-check class which allows us to automatically scan images or individual packages for CVEs. We can enable this functionality by adding the class to the local.conf file or the machine’s .conf file, as follows:
INHERIT += "cve-check"
You can then check a specific package for CVEs by running the ‘cve_check’ task, as follows:
bitbake -c cve_check busybox
If the package has any CVEs, then you’ll see a warning containing the CVE identifiers for any unpatched vulnerabilities:
WARNING: busybox-1.31.1-r0 do_cve_check: Found unpatched CVE (CVE-2018-1000500), for more information check /home/andy/bsp/build/tmp/work/aarch64-fsl-linux/busybox/1.31.1-r0/temp/cve.log
You can find out more information about the CVE by searching online with the CVE identifier, you can also look at the log file referred to in the warning. This file contains all the known CVEs including those already patched, here is an example of the output:
PACKAGE NAME: busybox PACKAGE VERSION: 1.31.1 CVE: CVE-2018-1000500 CVE STATUS: Unpatched CVE SUMMARY: Busybox contains a Missing SSL certificate validation vulnerability in The "busybox wget" applet that can result in arbitrary code execution. This attack appear to be exploitable via Simply download any file over HTTPS using "busybox wget https://compromised-domain.com/important-file". CVSS v2 BASE SCORE: 6.8 CVSS v3 BASE SCORE: 8.1 VECTOR: NETWORK MORE INFORMATION: https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2018-1000500
You’ll now also get CVE warnings when you build your filesystem image (i.e. no need to use the -c cve_check task) – A summary of all the CVEs found can be found in the tmp/deploy/cve directory. If you find packages with CVEs and you’ve identified that they are of concern then you may wish to upgrade or patch them.
The Yocto cve-check class is clever enough to spot vulnerabilities that you’ve patched allowing it to suppress future warnings. It does this by looking at any patches added to a recipe with CVE numbers in the file name. Finally, if there are packages or CVEs that you wish to ignore warnings for then you can make use of the CVE_CHECK_PN_WHITELIST and CVE_CHECK_WHITELIST variables.
Whilst CVE’s can never identify all vulnerabilities, it is a great place to start. Thankfully Yocto’s cve-check class makes it very easy.