commands = new ArrayList<>();
360 | for (File patch : patchset) {
361 | if (isValidPatchName(patch.getName())) {
362 | String command = doesPatchApply(repoPath, patchesPath, patch.getAbsolutePath(),
363 | applyPatches, "", patchesPathScript);
364 | if (command != null) {
365 | commands.add(command);
366 | } else {
367 | return null;
368 | }
369 | }
370 | }
371 | return commands;
372 | }
373 |
374 | private static boolean isVersionInRange(Version repo, String patch, boolean ignoreMajor) {
375 | if (patch.equals("ANY")) {
376 | return true;
377 | } else if (repo.getVersionFull().equals(patch)) {
378 | return true;
379 | } else if (patch.startsWith("^")) {
380 | Version patchVersion = new Version(patch.replaceAll("\\^", ""));
381 | return repo.isLesserVersion(patchVersion, ignoreMajor);
382 | } else if (patch.endsWith("+")) {
383 | Version patchVersion = new Version(patch.replaceAll("\\+", ""));
384 | return repo.isGreaterVersion(patchVersion, ignoreMajor);
385 | } else if (patch.contains("-^")) {
386 | String[] patchS = patch.split("-\\^");
387 | Version patchVersionLower = new Version(patchS[0]);
388 | Version patchVersionHigher = new Version(patchS[1]);
389 | return (repo.isGreaterVersion(patchVersionLower, ignoreMajor)
390 | && repo.isLesserVersion(patchVersionHigher, ignoreMajor));
391 | }
392 | return false;
393 | }
394 |
395 | private static boolean isGitPatch(String patch) {
396 | try {
397 | Scanner file = new Scanner(new File(patch));
398 | String firstLine = file.nextLine();
399 | file.close();
400 | if (firstLine.contains("Mon Sep 17 00:00:00 2001")) {
401 | return true;
402 | }
403 | } catch (Exception e) {
404 | e.printStackTrace();
405 | }
406 | return false;
407 | }
408 |
409 | private static String getModulePath(String patch) {
410 | if (patch.contains("/audio-kernel/")) {
411 | return "techpack/audio";
412 | } else if (patch.contains("/camera-kernel/")) {
413 | return "techpack/camera";
414 | } else if (patch.contains("/dsp-kernel/")) {
415 | return "INVALID"; //TODO
416 | } else if (patch.contains("/eva-kernel/")) {
417 | return "drivers/media/platform";
418 | } else if (patch.contains("/fm-commonsys/")) {
419 | return "INVALID"; //TODO
420 | } else if (patch.contains("/graphics-kernel/")) {
421 | return "drivers/gpu/msm";
422 | } else if (patch.contains("/prima/")) {
423 | return "drivers/staging/prima";
424 | } else if (patch.contains("/qcacld-2.0/")) {
425 | return "drivers/staging/qcacld-2.0";
426 | } else if (patch.contains("/qcacld-3.0/")) {
427 | return "drivers/staging/qcacld-3.0";
428 | } else if (patch.contains("/qca-cmn/")) {
429 | return "drivers/staging/qca-wifi-host-cmn";
430 | } else if (patch.contains("/qcawifi-cmn-dev/")) {
431 | return "INVALID"; //TODO
432 | } else if (patch.contains("/qca-wifi-host-cmn/")) {
433 | return "drivers/staging/qca-wifi-host-cmn";
434 | } else if (patch.contains("/securemsm-kernel/")) {
435 | return "INVALID"; //TODO
436 | } else if (patch.contains("/video-driver/")) {
437 | return "techpack/video";
438 | } else {
439 | return "INVALID";
440 | }
441 | }
442 |
443 | }
444 |
--------------------------------------------------------------------------------
/src/Scraper.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2020-2022 Divested Computing Group
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 | */
17 | import java.io.File;
18 | import java.net.HttpURLConnection;
19 | import java.net.URL;
20 | import java.util.ArrayList;
21 | import java.util.Arrays;
22 | import java.util.Collections;
23 | import java.util.List;
24 | import java.util.Scanner;
25 | import java.util.regex.Matcher;
26 | import java.util.regex.Pattern;
27 |
28 |
29 | public class Scraper {
30 |
31 | public static void main(String[] args) {
32 | scrape("");
33 | }
34 |
35 | public static void scrape(String link) {
36 | if (link.startsWith("https://source.android.com/security/bulletin/")
37 | || link.startsWith("https://www.qualcomm.com/company/product-security/bulletins/")
38 | || link.startsWith("https://www.qualcomm.com/product-security/bulletins/")
39 | || link.startsWith("https://www.codeaurora.org/security-bulletin/")
40 | || link.endsWith("Qualcomm.html")) {
41 | scrapeTable(link);
42 | } else if (link.contains("cip-kernel-sec")) {
43 | scrapeCIP(link);
44 | } else {
45 | System.out.println("Link unsupported");
46 | }
47 | }
48 |
49 | public static void scrapeTable(String link) {
50 | try {
51 | URL url = new URL(link);
52 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
53 | connection.connect();
54 | Scanner page = new Scanner(connection.getInputStream());
55 | String line = "";
56 | boolean searching = false;
57 | while (page.hasNextLine()) {
58 | line = page.nextLine();
59 |
60 | if (line.startsWith("href")) {
61 | line = "")) {
65 | line += "";
66 | }
67 |
68 | if (line.contains("")) {
72 | searching = false;
73 | }
74 | if (searching) {
75 | if (line.contains("CVE-") && !line.contains(", CVE-")
76 | && !line.contains("/company/product-security/bulletins/")) {
77 | line = line.replace("", "").replaceAll(" | ", "").replaceAll("
", "")
78 | .replaceAll("", "").replaceAll("", "").trim();
79 | if (line.contains("href")) {
80 | line = line.split(">")[1].split("<")[0];
81 | }
82 | System.out.println(line);
83 | }
84 | if (line.contains("http://") || line.contains("https://")) {
85 | if (line.contains("href =http")) {
86 | line = line.replaceAll("href =http", "href=\"http").replaceAll(">http", "\">http");
87 | }
88 | ArrayList patches = getLinksFromLine(line);
89 | for (String patch : patches) {
90 | if (patch.contains("platform/cts") || patch.contains("twitter.com")
91 | || patch.contains("/company/product-security/bulletins/")) {
92 | continue;
93 | }
94 |
95 | if (patch.contains("torvalds") || patch.contains("kernel.org")
96 | || patch.contains("/kernel/") || patch.contains("qcacld")
97 | || patch.contains("audio-kernel") || patch.contains("patchwork")
98 | || patch.contains("lkml.org") || patch.contains("qca-wifi-host-cmn")
99 | || patch.contains("redhat.com") || patch.contains("prima")
100 | || patch.contains("spinics.net") || patch.contains("kernel/msm-")) {
101 | continue; // TODO: Make this a toggle
102 | }
103 |
104 | patch = patch.replaceAll("%2F", "/");
105 | System.out.println("\tLink - " + getRepo(patch) + patch);
106 | }
107 | }
108 | }
109 | }
110 | page.close();
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | }
114 | }
115 |
116 | public static ArrayList getLinksFromLine(String line) {
117 | ArrayList out = new ArrayList<>();
118 | Pattern link = Pattern.compile("]+href=[\\\"']?([\\\"'>]+)[\\\"']?[^>]*>(.+?)<\\/a>",
119 | Pattern.CASE_INSENSITIVE | Pattern.DOTALL); // Credit (CC BY-SA 3.0): https://stackoverflow.com/a/5120599
120 | Matcher matcher = link.matcher(line);
121 | while (matcher.find()) {
122 | out.add(matcher.group().split("href=\"")[1].split("\"")[0]);
123 | }
124 | return out;
125 | }
126 |
127 | public static String getRepo(String line) {
128 | if (line.contains("android.googlesource.com/platform/")) {
129 | line = line.split(".com/platform/")[1].split("/\\+/")[0];
130 | return line + " - ";
131 | }
132 | if (line.contains("source.codeaurora.org/quic/la/platform") && !line.contains("kernel")) {
133 | line = line.split("la/platform/")[1].split("/commit/")[0];
134 | line = line.replaceAll("vendor/qcom-opensource/", "");
135 | return line + " - ";
136 | }
137 | return "";
138 | }
139 |
140 | public static void scrapeCIP(String path) {
141 | List issues = Arrays.asList(new File(path + "/issues/").listFiles(File::isFile));
142 | if (issues != null && issues.size() > 0) {
143 | Collections.sort(issues, new AlphanumComparator());
144 | for (File issue : issues) {
145 | try {
146 | System.out.println(issue.getName().replaceAll(".yml", ""));
147 | Scanner cve = new Scanner(issue);
148 | String line = "";
149 | boolean searching = false;
150 | while (cve.hasNextLine()) {
151 | line = cve.nextLine();
152 |
153 | if (line.contains("fixed-by:")) {
154 | searching = true;
155 | }
156 | if (line.contains("ignore:")) {
157 | searching = false;
158 | }
159 | if (searching && line.contains("never")) {
160 | continue;
161 | }
162 | if (searching) {
163 | while (line.endsWith(",")) {
164 | line += cve.nextLine().replaceAll(" ", " ");
165 | }
166 | if (line.contains("mainline:")) {
167 | final String commit = line.split("\\[")[1].split("\\]")[0];
168 | if (commit.contains(", ")) {
169 | for (String commitS : commit.split(", ")) {
170 | System.out.println("\tLink - " + Common.URL_LINUX_MAINLINE + commitS);
171 | }
172 | } else {
173 | System.out.println("\tLink - " + Common.URL_LINUX_MAINLINE + commit);
174 | }
175 | }
176 | if (line.contains("stable/")) {
177 | final String version = line.split("stable/")[1].split(":")[0];
178 | final String commit = line.split("\\[")[1].split("\\]")[0];
179 | if (commit.contains(", ")) {
180 | for (String commitS : commit.split(", ")) {
181 | System.out.println("\tLink - " + version + " - " + Common.URL_LINUX_STABLE + commitS);
182 | }
183 | } else {
184 | System.out.println("\tLink - " + version + " - " + Common.URL_LINUX_STABLE + commit);
185 | }
186 | }
187 | if (line.contains("cip/4.4") && !line.contains("4.4-st") && !line.contains("4.4-rt")) {
188 | final String version = line.split("cip/")[1].split(":")[0];
189 | final String commit = line.split("\\[")[1].split("\\]")[0];
190 | if (commit.contains(", ")) {
191 | for (String commitS : commit.split(", ")) {
192 | System.out.println("\tLink - " + version + " - " + Common.URL_LINUX_CIP + commitS);
193 | }
194 | } else {
195 | System.out.println("\tLink - " + version + " - " + Common.URL_LINUX_CIP + commit);
196 | }
197 | }
198 | if (line.contains("aosp/")) {
199 | final String version = line.split("aosp/")[1].split(":")[0];
200 | final String commit = line.split("\\[")[1].split("\\]")[0];
201 | if (commit.contains(", ")) {
202 | for (String commitS : commit.split(", ")) {
203 | System.out.println("\tLink - " + version + " - " + Common.URL_AOSP_STABLE + commitS);
204 | }
205 | } else {
206 | System.out.println("\tLink - " + version + " - " + Common.URL_AOSP_STABLE + commit);
207 | }
208 | }
209 | if (line.contains("openela/")) {
210 | final String version = line.split("openela/")[1].split(":")[0];
211 | final String commit = line.split("\\[")[1].split("\\]")[0];
212 | if (commit.contains(", ")) {
213 | for (String commitS : commit.split(", ")) {
214 | System.out.println("\tLink - " + version + " - " + Common.URL_OPENELA + commitS);
215 | }
216 | } else {
217 | System.out.println("\tLink - " + version + " - " + Common.URL_OPENELA + commit);
218 | }
219 | }
220 | }
221 | }
222 | cve.close();
223 | } catch (Exception e) {
224 | e.printStackTrace();
225 | }
226 | }
227 | }
228 | }
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/src/Sorter.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2017-2024 Divested Computing Group
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 | */
17 | import java.io.File;
18 | import java.util.ArrayList;
19 | import java.util.Collections;
20 | import java.util.Scanner;
21 |
22 | public class Sorter {
23 |
24 | private static ArrayList cves = new ArrayList<>();
25 |
26 | public static void sort(File manifest) {
27 | Common.initEnv();
28 | try {
29 | Scanner s = new Scanner(manifest);
30 | String curId = "";
31 | ArrayList lines = new ArrayList();
32 | while (s.hasNextLine()) {
33 | String line = s.nextLine();
34 | if (!line.startsWith("#") && (line.startsWith("CVE") || line.startsWith("LVT"))) {
35 | if (curId.length() > 0) {
36 | // System.out.println("Added a new CVE - " + curId);
37 | cves.add(new CVE(curId, lines));
38 | curId = "";
39 | lines = new ArrayList();
40 | }
41 | curId = line;
42 | } else {
43 | if(line.contains("=")) {
44 | String commitID = line.split("=")[1];
45 | lines.removeIf(previous -> previous.contains(commitID) && (previous.contains("android.googlesource") || previous.contains("cip/linux-cip") || previous.contains("openela")));
46 | }
47 | lines.add(line);
48 | }
49 | }
50 | } catch (Exception e) {
51 | e.printStackTrace();
52 | }
53 |
54 | Collections.sort(cves, new AlphanumComparator());
55 | for (CVE cve : cves) {
56 | if (cve.getLines().size() == 0) {
57 | continue;
58 | }
59 | System.out.println(cve.getId());
60 | for (String line : cve.getLines()) {
61 | if(Common.INCLUSIVE_KERNEL_PATH != null && (line.contains("Link - ^") || (line.contains("Link - https") && !manifest.toString().contains("CIP.")))
62 | && (line.contains(Common.URL_LINUX_MAINLINE) || line.contains(Common.URL_LINUX_STABLE) || line.contains(Common.URL_AOSP_STABLE))) {
63 | String[] lineSplit = line.split(" - ");
64 | String commitID = null;
65 | int offset = 1;
66 | if (line.contains("Link - ^")) {
67 | offset = 2;
68 | }
69 | if(lineSplit[offset].contains("=")) {
70 | commitID = lineSplit[offset].split("=")[1];
71 | }
72 | if(lineSplit[offset].contains("/+/")) {
73 | commitID = lineSplit[offset].split("/\\+/")[1];
74 | }
75 | if(commitID == null) {
76 | System.out.println("Unable to extract commit ID");
77 | System.exit(1);
78 | }
79 | Version kernelVersion = Common.getPatchVersion(commitID);
80 | if(kernelVersion != null) {
81 | if(line.startsWith("#")) {
82 | line = "#";
83 | } else {
84 | line = "";
85 | }
86 | line += "\tLink - ^" + kernelVersion.getVersionFull() + " - " + lineSplit[offset].trim();
87 | }
88 | }
89 | System.out.println(line);
90 | }
91 | }
92 | }
93 |
94 | public static class CVE {
95 | private String id;
96 | private ArrayList lines;
97 |
98 | public CVE(String id, ArrayList lines) {
99 | this.id = id.replaceAll("\u00AD", "-").replaceAll("--", "-");
100 | this.lines = lines;
101 | }
102 |
103 | public String getId() {
104 | return id;
105 | }
106 |
107 | public ArrayList getLines() {
108 | return lines;
109 | }
110 |
111 | @Override
112 | public String toString() {
113 | return getId();
114 | }
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/src/Version.java:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2017-2022 Divested Computing Group
3 |
4 | This program is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Affero General Public License as published by
6 | the Free Software Foundation, either version 3 of the License, or
7 | (at your option) any later version.
8 |
9 | This program is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Affero General Public License for more details.
13 |
14 | You should have received a copy of the GNU Affero General Public License
15 | along with this program. If not, see .
16 | */
17 | public class Version {
18 |
19 | private String versionFull = "";
20 | private int version = 0;
21 | private int patchLevel = 0;
22 | private int sublevel = 0;
23 |
24 | public Version(String version) {
25 | this.versionFull = version;
26 | String[] versionSplit = version.split("\\.");
27 | this.version = Integer.valueOf(versionSplit[0]);
28 | this.patchLevel = Integer.valueOf(versionSplit[1]);
29 | /* if(versionSplit.length == 3) {
30 | this.sublevel = Integer.valueOf(versionSplit[2]);
31 | }*/
32 | }
33 |
34 | public Version(int version, int patchLevel) {
35 | this.versionFull = version + "." + patchLevel;
36 | this.version = version;
37 | this.patchLevel = patchLevel;
38 | }
39 |
40 | public String getVersionFull() {
41 | return versionFull;
42 | }
43 |
44 | public int getVersion() {
45 | return version;
46 | }
47 |
48 | public int getPatchLevel() {
49 | return patchLevel;
50 | }
51 |
52 | public boolean isGreaterVersion(Version comparedTo, boolean ignoreMajor) {
53 | if (getVersion() > comparedTo.getVersion()) {
54 | return true;
55 | }
56 | if (!ignoreMajor) {
57 | return getVersion() == comparedTo.getVersion()
58 | && getPatchLevel() >= comparedTo.getPatchLevel();
59 | } else {
60 | return getVersion() >= comparedTo.getVersion()
61 | && getPatchLevel() >= comparedTo.getPatchLevel();
62 | }
63 | }
64 |
65 | public boolean isLesserVersion(Version comparedTo, boolean ignoreMajor) {
66 | if (getVersion() < comparedTo.getVersion()) {
67 | return true;
68 | }
69 | if (!ignoreMajor) {
70 | return getVersion() == comparedTo.getVersion()
71 | && getPatchLevel() <= comparedTo.getPatchLevel();
72 | } else {
73 | return getVersion() <= comparedTo.getVersion()
74 | && getPatchLevel() <= comparedTo.getPatchLevel();
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
|