<div dir="ltr">On 24 February 2016 at 15:27,  <span dir="ltr">&lt;<a href="mailto:mariano.lopez@linux.intel.com" target="_blank">mariano.lopez@linux.intel.com</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+# Whitelist for packages (PN)<br>
+cve_check_pn_whitelist () {<br>
+    glibc-locale<br>
+}</blockquote><div><br></div><div>Why is this a shell function?  CVE_CHECK_PN_WHITELIST = &quot;glibc-locale&quot; please. </div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+# Whitelist for CVE and version of package<br>
+python cve_check_cve_whitelist () {<br>
+    {&quot;CVE-2014-2524&quot;: (&quot;6.3&quot;,), \<br>
+    }<br>
+}</blockquote><div><br></div><div>Why is this a Python function?  Make it a bare string with implied formatting and it can be extended from outside this class, where as this can&#39;t.</div><div>  </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+addtask cve_check before do_build<br></blockquote><div><br></div><div>If you&#39;re expecting to look at the sources, you&#39;ll want to be after do_fetch too.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+do_cve_check[depends] = &quot;cve-check-tool-native:do_populate_cve_db&quot;<br></blockquote><div><br></div><div><br></div><div>And cve-check-tool-native:do_populate_sysroot.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+def get_patches_cves(d):<br>
+    &quot;&quot;&quot;<br>
+    Get patches that solve CVEs using the &quot;CVE: &quot; tag.<br>
+    &quot;&quot;&quot;<br>
+<br>
+    import re<br>
+<br>
+    pn = d.getVar(&quot;PN&quot;, True)<br>
+    cve_match = re.compile(&quot;CVE:( CVE\-\d+\-\d+)+&quot;)<br></blockquote><div><br></div><div>How does this work as the backslashes are escaping the - and d and d?  Use r&quot;&quot; strings.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+    patched_cves = set()<br>
+    for url in src_patches(d):<br>
+        patch_file = bb.fetch.decodeurl(url)[2]<br>
+        with open(patch_file, &quot;r&quot;) as f:<br>
+            patch_text = f.read()<br>
+<br>
+        # Search for the &quot;CVE: &quot; line<br>
+        match = cve_match.search(patch_text)<br>
+        if match:<br>
+            # Get only the CVEs without the &quot;CVE: &quot; tag<br>
+            cves = patch_text[match.start()+5:match.end()]<br>
+            for cve in cves.split():<br>
+                patched_cves.add(cve)<br><br></blockquote><div><br></div><div>Breaks for patches such as this in glibc:</div><div><br></div><div>meta/recipes-core/glibc/glibc/CVE-2015-9761_1.patch:CVE: CVE-2015-9761 patch #1</div><div><br></div><div>I&#39;d probably look for a line that starts with &quot;CVE:&quot; and the use re.findall to find all strings matching r&quot;CVE-\d{4}-\d+&quot;</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+    # It is needed to export the proxies to download the database using HTTP<br>
+    export_proxies(d)<br></blockquote><div><br></div><div>The database has already been downloaded hasn&#39;t it?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+    # Write the faux CSV file to be used with cve-check-tool<br>
+    fd, faux = tempfile.mkstemp(prefix=&quot;cve-faux-&quot;)<br>
+    with os.fdopen(fd, &quot;w&quot;) as f:<br>
+        f.write(&quot;%s,%s,%s,&quot; % (bpn, pv, cves))<br><br></blockquote><div><br></div><div>Put this inside the try incase the write fails so the file will still be deleted.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+    cmd += &quot; %s&quot; % faux<br>
+    try:<br>
+        popen = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)<br>
+        output, error = popen.communicate()<br></blockquote><div><br></div><div>Don&#39;t use the low-level function, the higher level helpers are clearer.</div><div><br></div><div>Always write cmd as a list unless you *need* the shell.</div><div><br></div><div>try:</div><div>    subprocess.check_output(cmd, stderr=subprocess.STDOUT)</div><div>except CommandCalledException as e:</div><div>    bb.warn(&quot;Couldn&#39;t check for CVEs: %s (output %s)&quot; % (e, e.output))</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+def get_cve_info(d, cves):<br>
+    &quot;&quot;&quot;<br>
+    Get CVE information from the database used by cve-check-tool.<br>
+    &quot;&quot;&quot;<br>
+<br>
+    try:<br>
+        import sqlite3<br>
+    except ImportError:<br>
+        from pysqlite2 import dbapi2 as sqlite3<br>
</blockquote><div><br></div><div>Isn&#39;t the output from cve-check-tool good enough?  Would it be nicer to extend the log instead of assuming that the database format won&#39;t ever change?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+def cve_write_data(d, patched, unpatched, cve_data):<br>
+    &quot;&quot;&quot;<br>
+    Write CVE information in WORKDIR; and to CVE_CHECK_DIR, and<br>
+    CVE manifest if enabled.<br>
+    &quot;&quot;&quot;<br>
+<br>
+    from bb.utils import mkdirhier<br>
+<br>
+    cve_file = d.getVar(&quot;CVE_CHECK_LOCAL_FILE&quot;, True)<br>
+    nvd_link = &quot;<a href="https://web.nvd.nist.gov/view/vuln/detail?vulnId=" rel="noreferrer" target="_blank">https://web.nvd.nist.gov/view/vuln/detail?vulnId=</a>&quot;<br>
+    write_string = &quot;&quot;<br>
+    mkdirhier(d.getVar(&quot;CVE_CHECK_LOCAL_DIR&quot;, True))<br>
+<br>
+    for cve in sorted(cve_data):<br>
+        write_string += &quot;PACKAGE NAME: %s\n&quot; % d.getVar(&quot;PN&quot;, True)<br>
+        write_string += &quot;PACKAGE VERSION: %s\n&quot; % d.getVar(&quot;PV&quot;, True)<br>
+        write_string += &quot;CVE: %s\n&quot; % cve<br>
+        if cve in patched:<br>
+            write_string += &quot;CVE STATUS: Patched\n&quot;<br>
+        else:<br>
+            write_string += &quot;CVE STATUS: Unpatched\n&quot;<br>
+            bb.warn(&quot;Found unpatched CVE, for more information check %s&quot; % cve_file)<br>
+        write_string += &quot;CVE SUMMARY: %s\n&quot; % cve_data[cve][&quot;summary&quot;]<br>
+        write_string += &quot;CVSS v2 BASE SCORE: %s\n&quot; % cve_data[cve][&quot;score&quot;]<br>
+        write_string += &quot;VECTOR: %s\n&quot; % cve_data[cve][&quot;vector&quot;]<br>
+        write_string += &quot;MORE INFORMATION: %s%s\n\n&quot; % (nvd_link, cve)<br>
+<br>
+    with open(cve_file, &quot;w&quot;) as f:<br>
+        f.write(write_string)<br></blockquote><div><br></div><div>Just write to the file instead of to a temporary string.</div><div><br></div><div>Ross</div></div></div></div>