From: Pierre Le Magourou <lemagoup@gmail.com>
To: openembedded-core@lists.openembedded.org
Subject: [meta-oe][PATCH 2/3] cve-update-db: Use NVD CPE data to populate PRODUCTS table
Date: Thu, 4 Jul 2019 17:19:07 +0200 [thread overview]
Message-ID: <20190704151908.5094-2-lemagoup@gmail.com> (raw)
In-Reply-To: <20190704151908.5094-1-lemagoup@gmail.com>
From: Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com>
Instead of using expanded list of affected versions that is not
reliable, use the 'cpe_match' node in the 'configurations' json node.
For cve-check to correctly match affected CVE, the sqlite database need to
contain operator_start, operator_end and the corresponding versions fields.
Signed-off-by: Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com>
---
meta/recipes-core/meta/cve-update-db.bb | 88 +++++++++++++++++++++++++++------
1 file changed, 74 insertions(+), 14 deletions(-)
diff --git a/meta/recipes-core/meta/cve-update-db.bb b/meta/recipes-core/meta/cve-update-db.bb
index 8e553b4f9b..3ba80a0d28 100644
--- a/meta/recipes-core/meta/cve-update-db.bb
+++ b/meta/recipes-core/meta/cve-update-db.bb
@@ -25,7 +25,7 @@ python do_populate_cve_db() {
YEAR_START = 2002
db_dir = d.getVar("DL_DIR") + '/CVE_CHECK'
- db_file = db_dir + '/nvd-json.db'
+ db_file = db_dir + '/nvdcve.db'
json_tmpfile = db_dir + '/nvd.json.gz'
proxy = d.getVar("https_proxy")
cve_f = open(d.getVar("TMPDIR") + '/cve_check', 'a')
@@ -99,9 +99,76 @@ def initialize_db(c):
c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \
SCOREV2 TEXT, SCOREV3 TEXT, MODIFIED INTEGER, VECTOR TEXT)")
c.execute("CREATE TABLE IF NOT EXISTS PRODUCTS (HASH INTEGER UNIQUE, ID TEXT, \
- VENDOR TEXT, PRODUCT TEXT, VERSION TEXT, OPERATOR TEXT)")
- c.execute("CREATE INDEX IF NOT EXISTS PRODUCT_IDX ON PRODUCTS \
- (PRODUCT, VERSION)")
+ VENDOR TEXT, PRODUCT TEXT, VERSION_START TEXT, OPERATOR_START TEXT, \
+ VERSION_END TEXT, OPERATOR_END TEXT)")
+
+def insert_elt(c, db_values):
+ product_str = db_values[0] + db_values[1] + db_values[2] + db_values[3]
+ hashstr = hash_djb2(product_str)
+ db_values.insert(0, hashstr)
+ query = "insert or replace into PRODUCTS values (?, ?, ?, ?, ?, ?, ?, ?)"
+ c.execute(query, db_values)
+
+def parse_node_and_insert(c, node, cveId):
+ # Parse children node if needed
+ try:
+ for child in node['children']:
+ parse_node_and_insert(c, child, cveId)
+ except:
+ pass
+
+ # Exit if the cpe_match node does not exists
+ try:
+ cpe_match = node['cpe_match']
+ except:
+ return
+
+ for cpe in cpe_match:
+ if not cpe['vulnerable']:
+ return
+ cpe23 = cpe['cpe23Uri'].split(':')
+ vendor = cpe23[3]
+ product = cpe23[4]
+ version = cpe23[5]
+
+ if version != '*':
+ # Version is defined, this is a '=' match
+ db_values = [cveId, vendor, product, version, '=', '', '']
+ insert_elt(c, db_values)
+ else:
+ # Parse start version, end version and operators
+ op_start = ''
+ op_end = ''
+ v_start = ''
+ v_end = ''
+
+ try:
+ if cpe['versionStartIncluding']:
+ op_start = '>='
+ v_start = cpe['versionStartIncluding']
+ except:
+ pass
+ try:
+ if cpe['versionStartExcluding']:
+ op_start = '>'
+ v_start = cpe['versionStartExcluding']
+ except:
+ pass
+ try:
+ if cpe['versionEndIncluding']:
+ op_end = '<='
+ v_end = cpe['versionEndIncluding']
+ except:
+ pass
+ try:
+ if cpe['versionEndExcluding']:
+ op_end = '<'
+ v_end = cpe['versionEndExcluding']
+ except:
+ pass
+
+ db_values = [cveId, vendor, product, v_start, op_start, v_end, op_end]
+ insert_elt(c, db_values)
def update_db(c, json_filename):
import json
@@ -125,16 +192,9 @@ def update_db(c, json_filename):
c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)",
[cveId, cveDesc, cvssv2, cvssv3, date, accessVector])
- for vendor in elt['cve']['affects']['vendor']['vendor_data']:
- for product in vendor['product']['product_data']:
- for version in product['version']['version_data']:
- product_str = cveId+vendor['vendor_name']+product['product_name']+version['version_value']
- hashstr = hash_djb2(product_str)
- c.execute("insert or replace into PRODUCTS values (?, ?, ?, ?, ?, ?)",
- [ hashstr, cveId, vendor['vendor_name'],
- product['product_name'], version['version_value'],
- version['version_affected']])
-
+ configurations = elt['configurations']['nodes']
+ for config in configurations:
+ parse_node_and_insert(c, config, cveId)
addtask do_populate_cve_db before do_fetch
--
2.11.0
next prev parent reply other threads:[~2019-07-04 15:19 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-04 15:19 [meta-oe][PATCH 1/3] cve-check: Depends on cve-update-db-native Pierre Le Magourou
2019-07-04 15:19 ` Pierre Le Magourou [this message]
2019-07-04 15:19 ` [meta-oe][PATCH 3/3] cve-check: Update unpatched CVE matching Pierre Le Magourou
2019-07-04 15:30 ` ✗ patchtest: failure for "[meta-oe] cve-check: Depends o..." and 2 more Patchwork
2019-07-04 16:53 ` [meta-oe][PATCH 1/3] cve-check: Depends on cve-update-db-native Richard Purdie
2019-07-05 9:34 ` Pierre Le Magourou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190704151908.5094-2-lemagoup@gmail.com \
--to=lemagoup@gmail.com \
--cc=openembedded-core@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.