Merge ~alexmurray/ubuntu-cve-tracker:check-syntax-support-for-kernel-patches into ubuntu-cve-tracker:master
- Git
- lp:~alexmurray/ubuntu-cve-tracker
- check-syntax-support-for-kernel-patches
- Merge into master
Proposed by
Alex Murray
Status: | Merged |
---|---|
Merged at revision: | 09d9db546cb44ac19c999a34cf41e2a1b2f5a8cc |
Proposed branch: | ~alexmurray/ubuntu-cve-tracker:check-syntax-support-for-kernel-patches |
Merge into: | ubuntu-cve-tracker:master |
Diff against target: |
456 lines (+162/-97) (has conflicts) 15 files modified
active/CVE-2021-46904 (+1/-0) active/CVE-2021-46905 (+1/-0) active/CVE-2022-48626 (+1/-0) active/CVE-2023-52469 (+1/-0) active/CVE-2024-26602 (+4/-0) ignored/CVE-2019-12379 (+1/-0) ignored/CVE-2019-12454 (+1/-0) ignored/CVE-2022-3642 (+1/-0) ignored/CVE-2023-35825 (+1/-0) retired/CVE-2008-1375 (+1/-0) retired/CVE-2019-12455 (+2/-1) retired/CVE-2021-3542 (+1/-0) scripts/active_edit (+2/-96) scripts/check-syntax (+32/-0) scripts/cve_lib.py (+112/-0) Conflict in active/CVE-2024-26602 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marc Deslauriers | Approve | ||
Review via email: mp+461311@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Seth Arnold (seth-arnold) wrote : | # |
Revision history for this message
Alex Murray (alexmurray) wrote : | # |
This will likely be easier to review by looking at the individual commits.
Revision history for this message
Alex Murray (alexmurray) wrote : | # |
Thanks Seth - I've added some extra changes for the regex precompilation etc, and tried to address your other comments too.
Revision history for this message
Marc Deslauriers (mdeslaur) wrote : | # |
The commits look good! Now that I think about it, I agree that putting it in check-syntax and only applying it if there is no break-fix is the right approach.
The only thing that may need changing in the future is:
+ assert commit_hash is not None
+
I'd probably just "return []" there so that a bad upstream patch for some reason wouldn't break our triage, but I think that's unlikely to ever happen.
review:
Approve
Revision history for this message
Alex Murray (alexmurray) wrote : | # |
Thanks Marc - good point, I made it print an error as well in that case.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/active/CVE-2021-46904 b/active/CVE-2021-46904 | |||
2 | index f19d00f..72c1b40 100644 | |||
3 | --- a/active/CVE-2021-46904 | |||
4 | +++ b/active/CVE-2021-46904 | |||
5 | @@ -15,6 +15,7 @@ Assigned-to: | |||
6 | 15 | CVSS: | 15 | CVSS: |
7 | 16 | 16 | ||
8 | 17 | Patches_linux: | 17 | Patches_linux: |
9 | 18 | break-fix: 72dc1c096c7051a48ab1dbb12f71976656b55eb5 8a12f8836145ffe37e9c8733dce18c22fb668b66 | ||
10 | 18 | upstream_linux: needs-triage | 19 | upstream_linux: needs-triage |
11 | 19 | trusty_linux: ignored (end of standard support) | 20 | trusty_linux: ignored (end of standard support) |
12 | 20 | trusty/esm_linux: needs-triage | 21 | trusty/esm_linux: needs-triage |
13 | diff --git a/active/CVE-2021-46905 b/active/CVE-2021-46905 | |||
14 | index c1b64e9..c422718 100644 | |||
15 | --- a/active/CVE-2021-46905 | |||
16 | +++ b/active/CVE-2021-46905 | |||
17 | @@ -15,6 +15,7 @@ Assigned-to: | |||
18 | 15 | CVSS: | 15 | CVSS: |
19 | 16 | 16 | ||
20 | 17 | Patches_linux: | 17 | Patches_linux: |
21 | 18 | break-fix: 8a12f8836145ffe37e9c8733dce18c22fb668b66 2ad5692db72874f02b9ad551d26345437ea4f7f3 | ||
22 | 18 | upstream_linux: not-affected (debian: No Debian released version vulnerable) | 19 | upstream_linux: not-affected (debian: No Debian released version vulnerable) |
23 | 19 | trusty_linux: ignored (end of standard support) | 20 | trusty_linux: ignored (end of standard support) |
24 | 20 | trusty/esm_linux: needs-triage | 21 | trusty/esm_linux: needs-triage |
25 | diff --git a/active/CVE-2022-48626 b/active/CVE-2022-48626 | |||
26 | index dc2d16c..76d45c6 100644 | |||
27 | --- a/active/CVE-2022-48626 | |||
28 | +++ b/active/CVE-2022-48626 | |||
29 | @@ -15,6 +15,7 @@ Assigned-to: | |||
30 | 15 | CVSS: | 15 | CVSS: |
31 | 16 | 16 | ||
32 | 17 | Patches_linux: | 17 | Patches_linux: |
33 | 18 | break-fix: - bd2db32e7c3e35bd4d9b8bbff689434a50893546 | ||
34 | 18 | upstream_linux: needs-triage | 19 | upstream_linux: needs-triage |
35 | 19 | trusty_linux: ignored (end of standard support) | 20 | trusty_linux: ignored (end of standard support) |
36 | 20 | trusty/esm_linux: needs-triage | 21 | trusty/esm_linux: needs-triage |
37 | diff --git a/active/CVE-2023-52469 b/active/CVE-2023-52469 | |||
38 | index 5d4154b..f4d8a33 100644 | |||
39 | --- a/active/CVE-2023-52469 | |||
40 | +++ b/active/CVE-2023-52469 | |||
41 | @@ -17,6 +17,7 @@ Assigned-to: | |||
42 | 17 | CVSS: | 17 | CVSS: |
43 | 18 | 18 | ||
44 | 19 | Patches_linux: | 19 | Patches_linux: |
45 | 20 | break-fix: a2e73f56fa6282481927ec43aa9362c03c2e2104 28dd788382c43b330480f57cd34cde0840896743 | ||
46 | 20 | upstream_linux: needs-triage | 21 | upstream_linux: needs-triage |
47 | 21 | trusty_linux: ignored (end of standard support) | 22 | trusty_linux: ignored (end of standard support) |
48 | 22 | trusty/esm_linux: needs-triage | 23 | trusty/esm_linux: needs-triage |
49 | diff --git a/active/CVE-2024-26602 b/active/CVE-2024-26602 | |||
50 | index b7e01d9..630af59 100644 | |||
51 | --- a/active/CVE-2024-26602 | |||
52 | +++ b/active/CVE-2024-26602 | |||
53 | @@ -15,6 +15,10 @@ Assigned-to: | |||
54 | 15 | CVSS: | 15 | CVSS: |
55 | 16 | 16 | ||
56 | 17 | Patches_linux: | 17 | Patches_linux: |
57 | 18 | <<<<<<< active/CVE-2024-26602 | ||
58 | 19 | ======= | ||
59 | 20 | break-fix: 22e4ebb975822833b083533035233d128b30e98f 944d5fe50f3f03daacfea16300e656a1691c4a23 | ||
60 | 21 | >>>>>>> active/CVE-2024-26602 | ||
61 | 18 | break-fix: c5f58bd58f432be5d92df33c5458e0bcbee3aadf 944d5fe50f3f03daacfea16300e656a1691c4a23 | 22 | break-fix: c5f58bd58f432be5d92df33c5458e0bcbee3aadf 944d5fe50f3f03daacfea16300e656a1691c4a23 |
62 | 19 | upstream_linux: needs-triage | 23 | upstream_linux: needs-triage |
63 | 20 | trusty_linux: ignored (end of standard support) | 24 | trusty_linux: ignored (end of standard support) |
64 | diff --git a/ignored/CVE-2019-12379 b/ignored/CVE-2019-12379 | |||
65 | index a4f7043..8dd5d99 100644 | |||
66 | --- a/ignored/CVE-2019-12379 | |||
67 | +++ b/ignored/CVE-2019-12379 | |||
68 | @@ -21,6 +21,7 @@ CVSS: | |||
69 | 21 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H [5.5 MEDIUM] | 21 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H [5.5 MEDIUM] |
70 | 22 | 22 | ||
71 | 23 | Patches_linux: | 23 | Patches_linux: |
72 | 24 | break-fix: - 84ecc2f6eb1cb12e6d44818f94fa49b50f06e6ac | ||
73 | 24 | upstream_linux: ignored (not an issue) | 25 | upstream_linux: ignored (not an issue) |
74 | 25 | precise/esm_linux: ignored (end of life, was needs-triage) | 26 | precise/esm_linux: ignored (end of life, was needs-triage) |
75 | 26 | trusty_linux: ignored (end of standard support) | 27 | trusty_linux: ignored (end of standard support) |
76 | diff --git a/ignored/CVE-2019-12454 b/ignored/CVE-2019-12454 | |||
77 | index b77df14..ec5441e 100644 | |||
78 | --- a/ignored/CVE-2019-12454 | |||
79 | +++ b/ignored/CVE-2019-12454 | |||
80 | @@ -24,6 +24,7 @@ CVSS: | |||
81 | 24 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H [7.8 HIGH] | 24 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H [7.8 HIGH] |
82 | 25 | 25 | ||
83 | 26 | Patches_linux: | 26 | Patches_linux: |
84 | 27 | break-fix: - a54988113985ca22e414e132054f234fc8a92604 | ||
85 | 27 | upstream_linux: not-affected (debian: Vulnerable code not present, introduced in 5.1-rc1) | 28 | upstream_linux: not-affected (debian: Vulnerable code not present, introduced in 5.1-rc1) |
86 | 28 | precise/esm_linux: ignored (end of life, was needs-triage) | 29 | precise/esm_linux: ignored (end of life, was needs-triage) |
87 | 29 | trusty_linux: ignored (end of standard support) | 30 | trusty_linux: ignored (end of standard support) |
88 | diff --git a/ignored/CVE-2022-3642 b/ignored/CVE-2022-3642 | |||
89 | index 5d2904a..f3cf007 100644 | |||
90 | --- a/ignored/CVE-2022-3642 | |||
91 | +++ b/ignored/CVE-2022-3642 | |||
92 | @@ -19,6 +19,7 @@ CVSS: | |||
93 | 19 | nvd: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N [5.5 MEDIUM] | 19 | nvd: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N [5.5 MEDIUM] |
94 | 20 | 20 | ||
95 | 21 | Patches_linux: | 21 | Patches_linux: |
96 | 22 | break-fix: c888183b21f36a247bb166ca9365705611bea847 80e5acb6dd72b25a6e6527443b9e9c1c3a7bcef6 | ||
97 | 22 | upstream_linux: not-affected (debian: only wireless-next) | 23 | upstream_linux: not-affected (debian: only wireless-next) |
98 | 23 | esm-infra/xenial_linux: needs-triage | 24 | esm-infra/xenial_linux: needs-triage |
99 | 24 | trusty_linux: ignored (end of standard support) | 25 | trusty_linux: ignored (end of standard support) |
100 | diff --git a/ignored/CVE-2023-35825 b/ignored/CVE-2023-35825 | |||
101 | index ff67bb5..6e42c4e 100644 | |||
102 | --- a/ignored/CVE-2023-35825 | |||
103 | +++ b/ignored/CVE-2023-35825 | |||
104 | @@ -23,6 +23,7 @@ Assigned-to: | |||
105 | 23 | CVSS: | 23 | CVSS: |
106 | 24 | 24 | ||
107 | 25 | Patches_linux: | 25 | Patches_linux: |
108 | 26 | break-fix: - 63264422785021704c39b38f65a78ab9e4a186d7 | ||
109 | 26 | upstream_linux: released (6.3.7-1) | 27 | upstream_linux: released (6.3.7-1) |
110 | 27 | trusty_linux: ignored (end of standard support) | 28 | trusty_linux: ignored (end of standard support) |
111 | 28 | trusty/esm_linux: needs-triage | 29 | trusty/esm_linux: needs-triage |
112 | diff --git a/retired/CVE-2008-1375 b/retired/CVE-2008-1375 | |||
113 | index cfacb91..87c677d 100644 | |||
114 | --- a/retired/CVE-2008-1375 | |||
115 | +++ b/retired/CVE-2008-1375 | |||
116 | @@ -46,6 +46,7 @@ hardy_linux-source-2.6.22: DNE | |||
117 | 46 | devel_linux-source-2.6.22: DNE | 46 | devel_linux-source-2.6.22: DNE |
118 | 47 | 47 | ||
119 | 48 | Patches_linux: | 48 | Patches_linux: |
120 | 49 | break-fix: - 214b7049a7929f03bbd2786aaef04b8b79db34e2 | ||
121 | 49 | upstream_linux: pending (2.6.26-rc1) | 50 | upstream_linux: pending (2.6.26-rc1) |
122 | 50 | dapper_linux: DNE | 51 | dapper_linux: DNE |
123 | 51 | feisty_linux: DNE | 52 | feisty_linux: DNE |
124 | diff --git a/retired/CVE-2019-12455 b/retired/CVE-2019-12455 | |||
125 | index 61a8e7e..397354f 100644 | |||
126 | --- a/retired/CVE-2019-12455 | |||
127 | +++ b/retired/CVE-2019-12455 | |||
128 | @@ -2,7 +2,7 @@ Candidate: CVE-2019-12455 | |||
129 | 2 | PublicDate: 2019-05-30 04:29:00 UTC | 2 | PublicDate: 2019-05-30 04:29:00 UTC |
130 | 3 | References: | 3 | References: |
131 | 4 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12455 | 4 | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12455 |
133 | 5 | https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git/commit/?h=sunxi/clk-for-5.3&id=fcdf445ff42f036d22178b49cf64e92d527c1330 | 5 | https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fcdf445ff42f036d22178b49cf64e92d527c1330 |
134 | 6 | https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2010240.html | 6 | https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2010240.html |
135 | 7 | Description: | 7 | Description: |
136 | 8 | ** DISPUTED ** An issue was discovered in sunxi_divs_clk_setup in | 8 | ** DISPUTED ** An issue was discovered in sunxi_divs_clk_setup in |
137 | @@ -28,6 +28,7 @@ CVSS: | |||
138 | 28 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H [5.5 MEDIUM] | 28 | nvd: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H [5.5 MEDIUM] |
139 | 29 | 29 | ||
140 | 30 | Patches_linux: | 30 | Patches_linux: |
141 | 31 | break-fix: - fcdf445ff42f036d22178b49cf64e92d527c1330 | ||
142 | 31 | upstream_linux: needed | 32 | upstream_linux: needed |
143 | 32 | precise/esm_linux: ignored (end of life, was needs-triage) | 33 | precise/esm_linux: ignored (end of life, was needs-triage) |
144 | 33 | trusty_linux: ignored (end of standard support) | 34 | trusty_linux: ignored (end of standard support) |
145 | diff --git a/retired/CVE-2021-3542 b/retired/CVE-2021-3542 | |||
146 | index d24b901..f916d9b 100644 | |||
147 | --- a/retired/CVE-2021-3542 | |||
148 | +++ b/retired/CVE-2021-3542 | |||
149 | @@ -23,6 +23,7 @@ Assigned-to: | |||
150 | 23 | CVSS: | 23 | CVSS: |
151 | 24 | 24 | ||
152 | 25 | Patches_linux: | 25 | Patches_linux: |
153 | 26 | break-fix: - 35d2969ea3c7d32aee78066b1f3cf61a0d935a4e | ||
154 | 26 | upstream_linux: not-affected | 27 | upstream_linux: not-affected |
155 | 27 | trusty_linux: ignored (end of standard support) | 28 | trusty_linux: ignored (end of standard support) |
156 | 28 | trusty/esm_linux: not-affected | 29 | trusty/esm_linux: not-affected |
157 | diff --git a/scripts/active_edit b/scripts/active_edit | |||
158 | index dadaf35..d71f0b3 100755 | |||
159 | --- a/scripts/active_edit | |||
160 | +++ b/scripts/active_edit | |||
161 | @@ -14,7 +14,6 @@ import os | |||
162 | 14 | import pathlib | 14 | import pathlib |
163 | 15 | import re | 15 | import re |
164 | 16 | import sys | 16 | import sys |
165 | 17 | import urllib.request | ||
166 | 18 | 17 | ||
167 | 19 | import cve_lib | 18 | import cve_lib |
168 | 20 | import source_map | 19 | import source_map |
169 | @@ -72,99 +71,6 @@ def release_wants_dne(release): | |||
170 | 72 | _, product, _, _ = cve_lib.get_subproject_details(release) | 71 | _, product, _, _ = cve_lib.get_subproject_details(release) |
171 | 73 | return product != None and product == cve_lib.PRODUCT_UBUNTU | 72 | return product != None and product == cve_lib.PRODUCT_UBUNTU |
172 | 74 | 73 | ||
173 | 75 | def fetch_kernel_fixes(url): | ||
174 | 76 | '''Downloads a kernel commit and returns a list of break-fixes''' | ||
175 | 77 | commit_hash = None | ||
176 | 78 | fixes = [] | ||
177 | 79 | |||
178 | 80 | # Strip off comment at the end | ||
179 | 81 | if ' ' in url: | ||
180 | 82 | url = url.split(' ')[0] | ||
181 | 83 | |||
182 | 84 | # Short URL, turn it into long one | ||
183 | 85 | if url.startswith('https://git.kernel.org/linus/'): | ||
184 | 86 | url = url.replace('https://git.kernel.org/linus/', | ||
185 | 87 | 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=') | ||
186 | 88 | if url.startswith('https://git.kernel.org/stable/c/'): | ||
187 | 89 | url = url.replace('https://git.kernel.org/stable/c/', | ||
188 | 90 | 'https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=') | ||
189 | 91 | |||
190 | 92 | # Get the raw patch | ||
191 | 93 | url = url.replace('/commit/', '/patch/') | ||
192 | 94 | |||
193 | 95 | with urllib.request.urlopen(url) as response: | ||
194 | 96 | patch = response.read().decode('utf-8') | ||
195 | 97 | |||
196 | 98 | for line in patch.split("\n"): | ||
197 | 99 | if re.match("commit [0-9a-f]{40} upstream.", line): | ||
198 | 100 | # This is an LTS backport, skip it | ||
199 | 101 | return [] | ||
200 | 102 | if re.match("\[ Upstream commit [0-9a-f]{40} \]", line): | ||
201 | 103 | # This is an LTS backport, skip it | ||
202 | 104 | return [] | ||
203 | 105 | if not commit_hash and line.startswith("From "): | ||
204 | 106 | commit_hash = line.split(' ')[1] | ||
205 | 107 | continue | ||
206 | 108 | elif line.startswith("Fixes: "): | ||
207 | 109 | fix_hash = line.split(' ')[1] | ||
208 | 110 | fixes.append([fix_hash, commit_hash]) | ||
209 | 111 | |||
210 | 112 | # If we didn't find a Fixes tag, just use - | ||
211 | 113 | if fixes == []: | ||
212 | 114 | fixes.append(['-', commit_hash]) | ||
213 | 115 | |||
214 | 116 | return fixes | ||
215 | 117 | |||
216 | 118 | def in_break_fixes(commit, break_fixes): | ||
217 | 119 | '''See if a commit is in the hash_list''' | ||
218 | 120 | # properly handle comparing short and long hashes | ||
219 | 121 | for [break_hash,fix_hash] in break_fixes: | ||
220 | 122 | if commit.startswith(break_hash): | ||
221 | 123 | return True | ||
222 | 124 | if break_hash.startswith(commit): | ||
223 | 125 | return True | ||
224 | 126 | return False | ||
225 | 127 | |||
226 | 128 | def get_long_kernel_hash(short_hash): | ||
227 | 129 | '''Attempts to get a long kernel hash''' | ||
228 | 130 | |||
229 | 131 | url = 'https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/patch/?id=' + short_hash | ||
230 | 132 | with urllib.request.urlopen(url) as response: | ||
231 | 133 | patch = response.read().decode('utf-8') | ||
232 | 134 | |||
233 | 135 | for line in patch.split("\n"): | ||
234 | 136 | if line.startswith("From "): | ||
235 | 137 | commit_hash = line.split(' ')[1] | ||
236 | 138 | if commit_hash.startswith(short_hash): | ||
237 | 139 | return commit_hash | ||
238 | 140 | |||
239 | 141 | return short_hash | ||
240 | 142 | |||
241 | 143 | |||
242 | 144 | def validate_kernel_fixes(break_fixes): | ||
243 | 145 | '''Validate list of break-fixes''' | ||
244 | 146 | |||
245 | 147 | if break_fixes == []: | ||
246 | 148 | return [] | ||
247 | 149 | |||
248 | 150 | # Make sure a breaks URL wasn't listed in the URLs by mistake | ||
249 | 151 | validated = [] | ||
250 | 152 | for [break_hash,fix_hash] in break_fixes: | ||
251 | 153 | # Don't check this for now, it can result in false positives | ||
252 | 154 | #if not in_break_fixes(fix_hash, break_fixes): | ||
253 | 155 | if True: | ||
254 | 156 | if break_hash != '-' and len(break_hash) < 40: | ||
255 | 157 | break_hash = get_long_kernel_hash(break_hash) | ||
256 | 158 | # Make sure it's not a dupe | ||
257 | 159 | dupe = False | ||
258 | 160 | for [v_break_hash,v_fix_hash] in validated: | ||
259 | 161 | if break_hash == v_break_hash and fix_hash == v_fix_hash: | ||
260 | 162 | dupe = True | ||
261 | 163 | if not dupe: | ||
262 | 164 | validated.append([break_hash, fix_hash]) | ||
263 | 165 | |||
264 | 166 | return validated | ||
265 | 167 | |||
266 | 168 | def _add_pkg(p, fp, fixed, parent, embargoed, break_fixes): | 74 | def _add_pkg(p, fp, fixed, parent, embargoed, break_fixes): |
267 | 169 | print('', file=fp) | 75 | print('', file=fp) |
268 | 170 | print('Patches_%s:' % p, file=fp) | 76 | print('Patches_%s:' % p, file=fp) |
269 | @@ -291,8 +197,8 @@ def create_or_update_cve(cve, packages, priority=None, bug_urls=None, | |||
270 | 291 | url.startswith('https://git.kernel.org/stable/c/') or | 197 | url.startswith('https://git.kernel.org/stable/c/') or |
271 | 292 | url.startswith('https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=') or | 198 | url.startswith('https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=') or |
272 | 293 | url.startswith('https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=')): | 199 | url.startswith('https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=')): |
275 | 294 | break_fixes += fetch_kernel_fixes(url) | 200 | break_fixes += cve_lib.fetch_kernel_fixes(url) |
276 | 295 | break_fixes = validate_kernel_fixes(break_fixes) | 201 | break_fixes = cve_lib.validate_kernel_fixes(break_fixes) |
277 | 296 | 202 | ||
278 | 297 | # collect notes from pkg_db and add any extra pkgs from pkg_db as well | 203 | # collect notes from pkg_db and add any extra pkgs from pkg_db as well |
279 | 298 | notes = [] | 204 | notes = [] |
280 | diff --git a/scripts/check-syntax b/scripts/check-syntax | |||
281 | index e5c909f..f89a0e4 100755 | |||
282 | --- a/scripts/check-syntax | |||
283 | +++ b/scripts/check-syntax | |||
284 | @@ -475,6 +475,19 @@ def fixup_entry_wrong(filename, pkg, rel): | |||
285 | 475 | 475 | ||
286 | 476 | cve_lib.update_state(filename, pkg, rel, status, None) | 476 | cve_lib.update_state(filename, pkg, rel, status, None) |
287 | 477 | 477 | ||
288 | 478 | def fixup_entry_missing_break_fix(filename, pkg, ref): | ||
289 | 479 | urls = cve_lib.fetch_kernel_fixes(ref) | ||
290 | 480 | urls = cve_lib.validate_kernel_fixes(urls) | ||
291 | 481 | |||
292 | 482 | for url in urls: | ||
293 | 483 | # convert to the break-fix format as a string | ||
294 | 484 | url = " ".join(url) | ||
295 | 485 | if opt.dry_run: | ||
296 | 486 | print("Dry-Run: adding break-fix %s, %s, to %s" % (filename, pkg, url)) | ||
297 | 487 | return | ||
298 | 488 | |||
299 | 489 | cve_lib.add_patch(filename, pkg, url, "break-fix") | ||
300 | 490 | |||
301 | 478 | def get_cve_path(cve, rel): | 491 | def get_cve_path(cve, rel): |
302 | 479 | 492 | ||
303 | 480 | cve = os.path.basename(cve) | 493 | cve = os.path.basename(cve) |
304 | @@ -1132,6 +1145,25 @@ def check_cve(cve): | |||
305 | 1132 | ) | 1145 | ) |
306 | 1133 | cve_okay = False | 1146 | cve_okay = False |
307 | 1134 | 1147 | ||
308 | 1148 | # if there is a reference URL to a kernel commit then check there is a | ||
309 | 1149 | # break-fix entry against the linux package | ||
310 | 1150 | if "References" in data: | ||
311 | 1151 | for ref in data["References"].split("\n"): | ||
312 | 1152 | if "git.kernel.org" in ref: | ||
313 | 1153 | # the CVE needs to already be triaged against linux and hence | ||
314 | 1154 | # have a patches entry for it | ||
315 | 1155 | if "linux" in data["patches"] and len(data["patches"]["linux"]) == 0: | ||
316 | 1156 | filename = srcmap["References"][0] if "References" in srcmap else cvepath | ||
317 | 1157 | linenum = srcmap["References"][1] if "References" in srcmap else 1 | ||
318 | 1158 | print( | ||
319 | 1159 | "%s: %d: missing break-fix entry for kernel commit" | ||
320 | 1160 | % (filename, linenum), | ||
321 | 1161 | file=sys.stderr, | ||
322 | 1162 | ) | ||
323 | 1163 | cve_okay = False | ||
324 | 1164 | if opt.autofix: | ||
325 | 1165 | fixup_entry_missing_break_fix(filename, "linux", ref) | ||
326 | 1166 | |||
327 | 1135 | for entry in data["CVSS"]: | 1167 | for entry in data["CVSS"]: |
328 | 1136 | srcname = entry['source'] | 1168 | srcname = entry['source'] |
329 | 1137 | filename = srcmap["CVSS"][srcname][0] | 1169 | filename = srcmap["CVSS"][srcname][0] |
330 | diff --git a/scripts/cve_lib.py b/scripts/cve_lib.py | |||
331 | index c97cae6..416d5f7 100755 | |||
332 | --- a/scripts/cve_lib.py | |||
333 | +++ b/scripts/cve_lib.py | |||
334 | @@ -22,6 +22,8 @@ import time | |||
335 | 22 | import cache_urllib | 22 | import cache_urllib |
336 | 23 | import json | 23 | import json |
337 | 24 | import yaml | 24 | import yaml |
338 | 25 | import urllib.error | ||
339 | 26 | import urllib.request | ||
340 | 25 | 27 | ||
341 | 26 | from functools import reduce | 28 | from functools import reduce |
342 | 27 | 29 | ||
343 | @@ -3456,3 +3458,113 @@ def wrap_text(text, width=75): | |||
344 | 3456 | Wrap text to width chars wide. | 3458 | Wrap text to width chars wide. |
345 | 3457 | """ | 3459 | """ |
346 | 3458 | return wordwrap(text, width).replace(' \n', '\n') | 3460 | return wordwrap(text, width).replace(' \n', '\n') |
347 | 3461 | |||
348 | 3462 | def fetch_kernel_fixes(url): | ||
349 | 3463 | '''Downloads a kernel commit and returns a list of break-fixes''' | ||
350 | 3464 | commit_hash = None | ||
351 | 3465 | fixes = [] | ||
352 | 3466 | |||
353 | 3467 | # Strip off comment at the end | ||
354 | 3468 | if ' ' in url: | ||
355 | 3469 | url = url.split(' ')[0] | ||
356 | 3470 | |||
357 | 3471 | # Short URL, turn it into long one | ||
358 | 3472 | if url.startswith('https://git.kernel.org/linus/'): | ||
359 | 3473 | url = url.replace('https://git.kernel.org/linus/', | ||
360 | 3474 | 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=') | ||
361 | 3475 | if url.startswith('https://git.kernel.org/stable/c/'): | ||
362 | 3476 | url = url.replace('https://git.kernel.org/stable/c/', | ||
363 | 3477 | 'https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=') | ||
364 | 3478 | # old URL style - replace to be more modern | ||
365 | 3479 | if url.startswith('http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h='): | ||
366 | 3480 | url = url.replace('http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=', | ||
367 | 3481 | 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=') | ||
368 | 3482 | |||
369 | 3483 | # Get the raw patch | ||
370 | 3484 | url = url.replace('/commit/', '/patch/') | ||
371 | 3485 | |||
372 | 3486 | try: | ||
373 | 3487 | with urllib.request.urlopen(url) as response: | ||
374 | 3488 | patch = response.read().decode('utf-8') | ||
375 | 3489 | except urllib.error.HTTPError as e: | ||
376 | 3490 | print("WARNING: Failed to fetch patch URL %s: %s" % (url, str(e)), file=sys.stderr) | ||
377 | 3491 | return fixes | ||
378 | 3492 | |||
379 | 3493 | backport_re = re.compile(r"(commit [0-9a-f]{40} upstream.|\[ Upstream commit [0-9a-f]{40} \])") | ||
380 | 3494 | for line in patch.split("\n"): | ||
381 | 3495 | # stop early if we have reached the main patch body | ||
382 | 3496 | if line.startswith("---"): | ||
383 | 3497 | break | ||
384 | 3498 | if backport_re.match(line): | ||
385 | 3499 | # This is an LTS backport, skip it | ||
386 | 3500 | return [] | ||
387 | 3501 | if not commit_hash and line.startswith("From "): | ||
388 | 3502 | commit_hash = line.split(' ')[1] | ||
389 | 3503 | continue | ||
390 | 3504 | elif line.startswith("Fixes: "): | ||
391 | 3505 | fix_hash = line.split(' ')[1] | ||
392 | 3506 | fixes.append([fix_hash, commit_hash]) | ||
393 | 3507 | |||
394 | 3508 | if commit_hash is None: | ||
395 | 3509 | print("Failed to get commit hash from %s" % url, file=sys.stderr) | ||
396 | 3510 | return [] | ||
397 | 3511 | |||
398 | 3512 | # If we didn't find a Fixes tag, just use - | ||
399 | 3513 | if fixes == []: | ||
400 | 3514 | fixes.append(['-', commit_hash]) | ||
401 | 3515 | |||
402 | 3516 | return fixes | ||
403 | 3517 | |||
404 | 3518 | def in_break_fixes(commit, break_fixes): | ||
405 | 3519 | '''See if a commit is in the hash_list''' | ||
406 | 3520 | # properly handle comparing short and long hashes | ||
407 | 3521 | for [break_hash,fix_hash] in break_fixes: | ||
408 | 3522 | if commit.startswith(break_hash): | ||
409 | 3523 | return True | ||
410 | 3524 | if break_hash.startswith(commit): | ||
411 | 3525 | return True | ||
412 | 3526 | return False | ||
413 | 3527 | |||
414 | 3528 | def get_long_kernel_hash(short_hash): | ||
415 | 3529 | '''Attempts to get a long kernel hash''' | ||
416 | 3530 | |||
417 | 3531 | url = 'https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/patch/?id=' + short_hash | ||
418 | 3532 | with urllib.request.urlopen(url) as response: | ||
419 | 3533 | patch = response.read().decode('utf-8') | ||
420 | 3534 | |||
421 | 3535 | for line in patch.split("\n"): | ||
422 | 3536 | if line.startswith("From "): | ||
423 | 3537 | commit_hash = line.split(' ')[1] | ||
424 | 3538 | if commit_hash.startswith(short_hash): | ||
425 | 3539 | return commit_hash | ||
426 | 3540 | |||
427 | 3541 | return short_hash | ||
428 | 3542 | |||
429 | 3543 | |||
430 | 3544 | def validate_kernel_fixes(break_fixes): | ||
431 | 3545 | '''Validate list of break-fixes''' | ||
432 | 3546 | |||
433 | 3547 | if break_fixes == []: | ||
434 | 3548 | return [] | ||
435 | 3549 | |||
436 | 3550 | # Make sure a breaks URL wasn't listed in the URLs by mistake | ||
437 | 3551 | validated = [] | ||
438 | 3552 | for [break_hash,fix_hash] in break_fixes: | ||
439 | 3553 | # Don't check this for now, it can result in false positives | ||
440 | 3554 | #if not in_break_fixes(fix_hash, break_fixes): | ||
441 | 3555 | if True: | ||
442 | 3556 | if break_hash is None or fix_hash is None: | ||
443 | 3557 | continue | ||
444 | 3558 | if break_hash != '-' and len(break_hash) < 40: | ||
445 | 3559 | break_hash = get_long_kernel_hash(break_hash) | ||
446 | 3560 | # Make sure it's not a dupe | ||
447 | 3561 | dupe = False | ||
448 | 3562 | for [v_break_hash,v_fix_hash] in validated: | ||
449 | 3563 | if break_hash == v_break_hash and fix_hash == v_fix_hash: | ||
450 | 3564 | dupe = True | ||
451 | 3565 | if not dupe: | ||
452 | 3566 | validated.append([break_hash, fix_hash]) | ||
453 | 3567 | |||
454 | 3568 | return validated | ||
455 | 3569 | |||
456 | 3570 |
A few random comments throughout; I realize some are against the previous version, but it's better late than never...