summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre Le Magourou <pierre.lemagourou@softbankrobotics.com>2019-11-06 17:37:35 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-11-07 19:47:26 +0000
commit1fd5cfa59d191bd11cc57dffb6c6e381d6abac60 (patch)
tree58cb95cd33f459d9c2bcdbb858a6cd6b7eb5f653
parent723bd744df2e9d87c6f115a98a0fbc3ea515c3ec (diff)
downloadpoky-1fd5cfa59d191bd11cc57dffb6c6e381d6abac60.tar.gz
cve-update-db: Use NVD CPE data to populate PRODUCTS table
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. (From OE-Core rev: f7676e9a38d595564922e5f59acbc69c2109a78f) (From OE-Core rev: 6977d15fbc3b78958768b21f6c501e7d63be9499) Signed-off-by: Pierre Le Magourou <pierre.lemagourou@softbankrobotics.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/meta/cve-update-db-native.bb88
1 files changed, 74 insertions, 14 deletions
diff --git a/meta/recipes-core/meta/cve-update-db-native.bb b/meta/recipes-core/meta/cve-update-db-native.bb
index d60159bc2a..cd270443b1 100644
--- a/meta/recipes-core/meta/cve-update-db-native.bb
+++ b/meta/recipes-core/meta/cve-update-db-native.bb
@@ -25,7 +25,7 @@ python do_populate_cve_db() {
25 YEAR_START = 2002 25 YEAR_START = 2002
26 26
27 db_dir = d.getVar("DL_DIR") + '/CVE_CHECK' 27 db_dir = d.getVar("DL_DIR") + '/CVE_CHECK'
28 db_file = db_dir + '/nvd-json.db' 28 db_file = db_dir + '/nvdcve.db'
29 json_tmpfile = db_dir + '/nvd.json.gz' 29 json_tmpfile = db_dir + '/nvd.json.gz'
30 proxy = d.getVar("https_proxy") 30 proxy = d.getVar("https_proxy")
31 cve_f = open(d.getVar("TMPDIR") + '/cve_check', 'a') 31 cve_f = open(d.getVar("TMPDIR") + '/cve_check', 'a')
@@ -99,9 +99,76 @@ def initialize_db(c):
99 c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \ 99 c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \
100 SCOREV2 TEXT, SCOREV3 TEXT, MODIFIED INTEGER, VECTOR TEXT)") 100 SCOREV2 TEXT, SCOREV3 TEXT, MODIFIED INTEGER, VECTOR TEXT)")
101 c.execute("CREATE TABLE IF NOT EXISTS PRODUCTS (HASH INTEGER UNIQUE, ID TEXT, \ 101 c.execute("CREATE TABLE IF NOT EXISTS PRODUCTS (HASH INTEGER UNIQUE, ID TEXT, \
102 VENDOR TEXT, PRODUCT TEXT, VERSION TEXT, OPERATOR TEXT)") 102 VENDOR TEXT, PRODUCT TEXT, VERSION_START TEXT, OPERATOR_START TEXT, \
103 c.execute("CREATE INDEX IF NOT EXISTS PRODUCT_IDX ON PRODUCTS \ 103 VERSION_END TEXT, OPERATOR_END TEXT)")
104 (PRODUCT, VERSION)") 104
105def insert_elt(c, db_values):
106 product_str = db_values[0] + db_values[1] + db_values[2] + db_values[3]
107 hashstr = hash_djb2(product_str)
108 db_values.insert(0, hashstr)
109 query = "insert or replace into PRODUCTS values (?, ?, ?, ?, ?, ?, ?, ?)"
110 c.execute(query, db_values)
111
112def parse_node_and_insert(c, node, cveId):
113 # Parse children node if needed
114 try:
115 for child in node['children']:
116 parse_node_and_insert(c, child, cveId)
117 except:
118 pass
119
120 # Exit if the cpe_match node does not exists
121 try:
122 cpe_match = node['cpe_match']
123 except:
124 return
125
126 for cpe in cpe_match:
127 if not cpe['vulnerable']:
128 return
129 cpe23 = cpe['cpe23Uri'].split(':')
130 vendor = cpe23[3]
131 product = cpe23[4]
132 version = cpe23[5]
133
134 if version != '*':
135 # Version is defined, this is a '=' match
136 db_values = [cveId, vendor, product, version, '=', '', '']
137 insert_elt(c, db_values)
138 else:
139 # Parse start version, end version and operators
140 op_start = ''
141 op_end = ''
142 v_start = ''
143 v_end = ''
144
145 try:
146 if cpe['versionStartIncluding']:
147 op_start = '>='
148 v_start = cpe['versionStartIncluding']
149 except:
150 pass
151 try:
152 if cpe['versionStartExcluding']:
153 op_start = '>'
154 v_start = cpe['versionStartExcluding']
155 except:
156 pass
157 try:
158 if cpe['versionEndIncluding']:
159 op_end = '<='
160 v_end = cpe['versionEndIncluding']
161 except:
162 pass
163 try:
164 if cpe['versionEndExcluding']:
165 op_end = '<'
166 v_end = cpe['versionEndExcluding']
167 except:
168 pass
169
170 db_values = [cveId, vendor, product, v_start, op_start, v_end, op_end]
171 insert_elt(c, db_values)
105 172
106def update_db(c, json_filename): 173def update_db(c, json_filename):
107 import json 174 import json
@@ -125,16 +192,9 @@ def update_db(c, json_filename):
125 c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)", 192 c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)",
126 [cveId, cveDesc, cvssv2, cvssv3, date, accessVector]) 193 [cveId, cveDesc, cvssv2, cvssv3, date, accessVector])
127 194
128 for vendor in elt['cve']['affects']['vendor']['vendor_data']: 195 configurations = elt['configurations']['nodes']
129 for product in vendor['product']['product_data']: 196 for config in configurations:
130 for version in product['version']['version_data']: 197 parse_node_and_insert(c, config, cveId)
131 product_str = cveId+vendor['vendor_name']+product['product_name']+version['version_value']
132 hashstr = hash_djb2(product_str)
133 c.execute("insert or replace into PRODUCTS values (?, ?, ?, ?, ?, ?)",
134 [ hashstr, cveId, vendor['vendor_name'],
135 product['product_name'], version['version_value'],
136 version['version_affected']])
137
138 198
139 199
140addtask do_populate_cve_db before do_fetch 200addtask do_populate_cve_db before do_fetch