1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.security.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assume.assumeTrue; 22 23 import com.android.compatibility.common.util.MetricsReportLog; 24 import com.android.compatibility.common.util.ResultType; 25 import com.android.compatibility.common.util.ResultUnit; 26 import com.android.ddmlib.CollectingOutputReceiver; 27 import com.android.ddmlib.IShellOutputReceiver; 28 import com.android.ddmlib.NullOutputReceiver; 29 import com.android.sts.common.tradefed.testtype.SecurityTestCase; 30 import com.android.sts.common.util.TombstoneUtils; 31 import com.android.tradefed.device.DeviceNotAvailableException; 32 import com.android.tradefed.device.ITestDevice; 33 import com.android.tradefed.log.LogUtil.CLog; 34 35 import java.io.BufferedOutputStream; 36 import java.io.File; 37 import java.io.FileOutputStream; 38 import java.io.InputStream; 39 import java.io.OutputStream; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.Collections; 43 import java.util.List; 44 import java.util.Map; 45 import java.util.concurrent.TimeUnit; 46 import java.util.regex.Matcher; 47 import java.util.regex.Pattern; 48 49 public class AdbUtils { 50 51 final static String TMP_PATH = "/data/local/tmp/"; 52 final static int TIMEOUT_SEC = 9 * 60; 53 final static String RESOURCE_ROOT = "/"; 54 55 final static String regexSpecialChars = "<([{\\^-=$!|]})?*+.>"; 56 @SuppressWarnings("InvalidPatternSyntax") // the errorprone test is incorrect for the following 57 final static String regexSpecialCharsEscaped = regexSpecialChars.replaceAll(".", "\\\\$0"); 58 final static Pattern regexSpecialCharsEscapedPattern = 59 Pattern.compile("[" + regexSpecialCharsEscaped + "]"); 60 61 /** 62 * @deprecated Use {@link NativePoc} instead. 63 */ 64 @Deprecated 65 public static class pocConfig { 66 String binaryName; 67 String arguments; 68 Map<String, String> envVars; 69 String inputFilesDestination; 70 ITestDevice device; 71 TombstoneUtils.Config config = new TombstoneUtils.Config(); 72 List<String> inputFiles = Collections.emptyList(); 73 pocConfig(String binaryName, ITestDevice device)74 pocConfig(String binaryName, ITestDevice device) { 75 this.binaryName = binaryName; 76 this.device = device; 77 } 78 } 79 80 /** 81 * Runs a commandline on the specified device 82 * 83 * @deprecated Use {@link CommandUtil} instead. 84 * @param command the command to be ran 85 * @param device device for the command to be ran on 86 * @return the console output from running the command 87 */ 88 @Deprecated runCommandLine(String command, ITestDevice device)89 public static String runCommandLine(String command, ITestDevice device) throws Exception { 90 if ("reboot".equals(command)) { 91 throw new IllegalArgumentException( 92 "You called a forbidden command! Please fix your tests."); 93 } 94 return device.executeShellCommand(command); 95 } 96 97 /** 98 * Pushes and runs a binary to the selected device 99 * 100 * @deprecated Use {@link NativePoc} instead. 101 * @param pocName name of the poc binary 102 * @param device device to be ran on 103 * @return the console output from the binary 104 */ 105 @Deprecated runPoc(String pocName, ITestDevice device)106 public static String runPoc(String pocName, ITestDevice device) throws Exception { 107 return runPoc(pocName, device, SecurityTestCase.TIMEOUT_NONDETERMINISTIC); 108 } 109 110 /** 111 * Pushes and runs a binary to the selected device 112 * 113 * @deprecated Use {@link NativePoc} instead. 114 * @param pocName name of the poc binary 115 * @param device device to be ran on 116 * @param timeout time to wait for output in seconds 117 * @return the console output from the binary 118 */ 119 @Deprecated runPoc(String pocName, ITestDevice device, int timeout)120 public static String runPoc(String pocName, ITestDevice device, int timeout) throws Exception { 121 return runPoc(pocName, device, timeout, null); 122 } 123 124 /** 125 * Pushes and runs a binary to the selected device 126 * 127 * @deprecated Use {@link NativePoc} instead. 128 * @param pocName name of the poc binary 129 * @param device device to be ran on 130 * @param timeout time to wait for output in seconds 131 * @param arguments the input arguments for the poc 132 * @return the console output from the binary 133 */ 134 @Deprecated runPoc(String pocName, ITestDevice device, int timeout, String arguments)135 public static String runPoc(String pocName, ITestDevice device, int timeout, String arguments) 136 throws Exception { 137 CollectingOutputReceiver receiver = new CollectingOutputReceiver(); 138 runPoc(pocName, device, timeout, arguments, receiver); 139 return receiver.getOutput(); 140 } 141 142 /** 143 * Pushes and runs a binary to the selected device and ignores any of its output. 144 * 145 * @deprecated Use {@link NativePoc} instead. 146 * @param pocName name of the poc binary 147 * @param device device to be ran on 148 * @param timeout time to wait for output in seconds 149 */ 150 @Deprecated runPocNoOutput(String pocName, ITestDevice device, int timeout)151 public static void runPocNoOutput(String pocName, ITestDevice device, int timeout) 152 throws Exception { 153 runPocNoOutput(pocName, device, timeout, null); 154 } 155 156 /** 157 * Pushes and runs a binary with arguments to the selected device and ignores any of its output. 158 * 159 * @deprecated Use {@link NativePoc} instead. 160 * @param pocName name of the poc binary 161 * @param device device to be ran on 162 * @param timeout time to wait for output in seconds 163 * @param arguments input arguments for the poc 164 */ 165 @Deprecated runPocNoOutput( String pocName, ITestDevice device, int timeout, String arguments)166 public static void runPocNoOutput( 167 String pocName, ITestDevice device, int timeout, String arguments) throws Exception { 168 runPoc(pocName, device, timeout, arguments, null); 169 } 170 171 /** 172 * Pushes and runs a binary with arguments to the selected device and ignores any of its output. 173 * 174 * @deprecated Use {@link NativePoc} instead. 175 * @param pocName name of the poc binary 176 * @param device device to be ran on 177 * @param timeout time to wait for output in seconds 178 * @param arguments input arguments for the poc 179 * @param receiver the type of receiver to run against 180 */ 181 @Deprecated runPoc( String pocName, ITestDevice device, int timeout, String arguments, IShellOutputReceiver receiver)182 public static int runPoc( 183 String pocName, 184 ITestDevice device, 185 int timeout, 186 String arguments, 187 IShellOutputReceiver receiver) 188 throws Exception { 189 return runPoc(pocName, device, timeout, arguments, null, receiver); 190 } 191 192 /** 193 * Pushes and runs a binary with arguments to the selected device and ignores any of its output. 194 * 195 * @deprecated Use {@link NativePoc} instead. 196 * @param pocName name of the poc binary 197 * @param device device to be ran on 198 * @param timeout time to wait for output in seconds 199 * @param arguments input arguments for the poc 200 * @param envVars run the poc with environment variables 201 * @param receiver the type of receiver to run against 202 */ 203 @Deprecated runPoc( String pocName, ITestDevice device, int timeout, String arguments, Map<String, String> envVars, IShellOutputReceiver receiver)204 public static int runPoc( 205 String pocName, 206 ITestDevice device, 207 int timeout, 208 String arguments, 209 Map<String, String> envVars, 210 IShellOutputReceiver receiver) 211 throws Exception { 212 String remoteFile = String.format("%s%s", TMP_PATH, pocName); 213 SecurityTestCase.getPocPusher(device).pushFile(pocName + "_sts", remoteFile); 214 215 assertPocExecutable(pocName, device); 216 if (receiver == null) { 217 receiver = new NullOutputReceiver(); 218 } 219 if (arguments == null) { 220 arguments = ""; 221 } 222 223 String env = ""; 224 if (envVars != null) { 225 StringBuilder sb = new StringBuilder(); 226 for (Map.Entry<String, String> entry : envVars.entrySet()) { 227 sb 228 .append(entry.getKey().trim()) 229 .append('=') 230 .append(entry.getValue().trim()) 231 .append(' '); 232 } 233 env = sb.toString(); 234 CLog.i("Running poc '%s' with env variables '%s'", pocName, env); 235 } 236 237 // since we have to return the exit status AND the poc stdout+stderr we redirect the exit 238 // status to a file temporarily 239 String exitStatusFilepath = TMP_PATH + "exit_status"; 240 runCommandLine("rm " + exitStatusFilepath, device); // remove any old exit status 241 device.executeShellCommand( 242 env + TMP_PATH + pocName + " " + arguments + 243 "; echo $? > " + exitStatusFilepath, // echo exit status to file 244 receiver, timeout, TimeUnit.SECONDS, 0); 245 246 // cat the exit status 247 String exitStatusString = runCommandLine("cat " + exitStatusFilepath, device).trim(); 248 249 MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device); 250 reportLog.addValue("poc_name", pocName, ResultType.NEUTRAL, ResultUnit.NONE); 251 int exitStatus = -1; 252 try { 253 exitStatus = Integer.parseInt(exitStatusString); 254 reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE); 255 } catch (NumberFormatException e) { 256 // Getting the exit status is a bonus. We can continue without it. 257 CLog.w("Could not parse exit status to int: %s", exitStatusString); 258 } 259 reportLog.submit(); 260 261 runCommandLine("rm " + exitStatusFilepath, device); 262 return exitStatus; 263 } 264 265 /** 266 * Assert the poc is executable 267 * 268 * @deprecated Use {@link NativePoc} instead. 269 * @param pocName name of the poc binary 270 * @param device device to be ran on 271 */ 272 @Deprecated assertPocExecutable(String pocName, ITestDevice device)273 private static void assertPocExecutable(String pocName, ITestDevice device) throws Exception { 274 String fullPocPath = TMP_PATH + pocName; 275 device.executeShellCommand("chmod 777 " + fullPocPath); 276 assertEquals("'" + pocName + "' must exist and be readable.", 0, 277 runCommandGetExitCode("test -r " + fullPocPath, device)); 278 assertEquals("'" + pocName + "'poc must exist and be writable.", 0, 279 runCommandGetExitCode("test -w " + fullPocPath, device)); 280 assertEquals("'" + pocName + "'poc must exist and be executable.", 0, 281 runCommandGetExitCode("test -x " + fullPocPath, device)); 282 } 283 284 /** 285 * Pushes and installs an apk to the selected device 286 * 287 * @param pathToApk a string path to apk from the /res folder 288 * @param device device to be ran on 289 * @return the output from attempting to install the apk 290 */ installApk(String pathToApk, ITestDevice device)291 public static String installApk(String pathToApk, ITestDevice device) throws Exception { 292 293 String fullResourceName = pathToApk; 294 File apkFile = File.createTempFile("apkFile", ".apk"); 295 try { 296 apkFile = extractResource(fullResourceName, apkFile); 297 return device.installPackage(apkFile, true); 298 } finally { 299 apkFile.delete(); 300 } 301 } 302 303 /** 304 * Extracts a resource and pushes it to the device 305 * 306 * @param fullResourceName a string path to resource from the res folder 307 * @param deviceFilePath the remote destination absolute file path 308 * @param device device to be ran on 309 */ pushResource(String fullResourceName, String deviceFilePath, ITestDevice device)310 public static void pushResource(String fullResourceName, String deviceFilePath, 311 ITestDevice device) throws Exception { 312 File resFile = File.createTempFile("CTSResource", ""); 313 try { 314 resFile = extractResource(fullResourceName, resFile); 315 device.pushFile(resFile, deviceFilePath); 316 } finally { 317 resFile.delete(); 318 } 319 } 320 321 /** 322 * Pushes the specified files to the specified destination directory 323 * 324 * @param inputFiles files required as input 325 * @param inputFilesDestination destination directory to which input files are 326 * pushed 327 * @param device device to be run on 328 */ pushResources(String[] inputFiles, String inputFilesDestination, ITestDevice device)329 public static void pushResources(String[] inputFiles, String inputFilesDestination, 330 ITestDevice device) throws Exception { 331 if (inputFiles == null || inputFilesDestination == null) { 332 throw new IllegalArgumentException( 333 "Can't push resources: input files or destination is null"); 334 } 335 for (String tempFile : inputFiles) { 336 pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device); 337 } 338 } 339 340 /** 341 * Removes the specified files from the specified destination directory 342 * 343 * @param inputFiles files required as input 344 * @param inputFilesDestination destination directory where input files are 345 * present 346 * @param device device to be run on 347 */ removeResources(String[] inputFiles, String inputFilesDestination, ITestDevice device)348 public static void removeResources(String[] inputFiles, String inputFilesDestination, 349 ITestDevice device) throws Exception { 350 if (inputFiles == null || inputFilesDestination == null) { 351 throw new IllegalArgumentException( 352 "Can't remove resources: input files or destination is null"); 353 } 354 for (String tempFile : inputFiles) { 355 runCommandLine("rm " + inputFilesDestination + tempFile, device); 356 } 357 } 358 359 /** 360 * Extracts the binary data from a resource and writes it to a temp file 361 */ extractResource(String fullResourceName, File file)362 private static File extractResource(String fullResourceName, File file) throws Exception { 363 try (InputStream in = AdbUtils.class.getResourceAsStream(fullResourceName); 364 OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) { 365 if (in == null) { 366 throw new IllegalArgumentException("Resource not found: " + fullResourceName); 367 } 368 byte[] buf = new byte[65536]; 369 int chunkSize; 370 while ((chunkSize = in.read(buf)) != -1) { 371 out.write(buf, 0, chunkSize); 372 } 373 return file; 374 } 375 376 } 377 /** 378 * Utility function to help check the exit code of a shell command 379 * 380 * @deprecated Use {@link CommandUtil} instead. 381 */ 382 @Deprecated runCommandGetExitCode(String cmd, ITestDevice device)383 public static int runCommandGetExitCode(String cmd, ITestDevice device) throws Exception { 384 long time = System.currentTimeMillis(); 385 String exitStatusString = runCommandLine( 386 "(" + cmd + ") > /dev/null 2>&1; echo $?", device).trim(); 387 time = System.currentTimeMillis() - time; 388 389 try { 390 int exitStatus = Integer.parseInt(exitStatusString); 391 MetricsReportLog reportLog = SecurityTestCase.buildMetricsReportLog(device); 392 reportLog.addValue("command", cmd, ResultType.NEUTRAL, ResultUnit.NONE); 393 reportLog.addValue("exit_status", exitStatus, ResultType.NEUTRAL, ResultUnit.NONE); 394 reportLog.submit(); 395 return exitStatus; 396 } catch (NumberFormatException e) { 397 throw new IllegalArgumentException(String.format( 398 "Could not get the exit status (%s) for '%s' (%d ms).", 399 exitStatusString, cmd, time)); 400 } 401 } 402 403 /** 404 * Pushes and runs a binary to the selected device and checks exit code Return code 113 is used 405 * to indicate the vulnerability 406 * 407 * @deprecated Use {@link NativePoc} instead. 408 * @param pocName a string path to poc from the /res folder 409 * @param device device to be ran on 410 * @param timeout time to wait for output in seconds 411 */ 412 @Deprecated runPocCheckExitCode(String pocName, ITestDevice device, int timeout)413 public static boolean runPocCheckExitCode(String pocName, ITestDevice device, int timeout) 414 throws Exception { 415 416 //Refer to go/asdl-sts-guide Test section for knowing the significance of 113 code 417 return runPocGetExitStatus(pocName, device, timeout) == 113; 418 } 419 420 /** 421 * Pushes and runs a binary to the device and returns the exit status. 422 * 423 * @deprecated Use {@link NativePoc} instead. 424 * @param pocName a string path to poc from the /res folder 425 * @param device device to be ran on 426 * @param timeout time to wait for output in seconds 427 */ 428 @Deprecated runPocGetExitStatus(String pocName, ITestDevice device, int timeout)429 public static int runPocGetExitStatus(String pocName, ITestDevice device, int timeout) 430 throws Exception { 431 return runPocGetExitStatus(pocName, null, device, timeout); 432 } 433 434 /** 435 * Pushes and runs a binary to the device and returns the exit status. 436 * 437 * @deprecated Use {@link NativePoc} instead. 438 * @param pocName a string path to poc from the /res folder 439 * @param arguments input arguments for the poc 440 * @param device device to be ran on 441 * @param timeout time to wait for output in seconds 442 */ 443 @Deprecated runPocGetExitStatus( String pocName, String arguments, ITestDevice device, int timeout)444 public static int runPocGetExitStatus( 445 String pocName, String arguments, ITestDevice device, int timeout) throws Exception { 446 return runPocGetExitStatus(pocName, arguments, null, device, timeout); 447 } 448 449 /** 450 * Pushes and runs a binary to the device and returns the exit status. 451 * 452 * @deprecated Use {@link NativePoc} instead. 453 * @param pocName name of the poc binary 454 * @param arguments input arguments for the poc 455 * @param envVars run the poc with environment variables 456 * @param device device to be run on 457 * @param timeout time to wait for output in seconds 458 */ 459 @Deprecated runPocGetExitStatus( String pocName, String arguments, Map<String, String> envVars, ITestDevice device, int timeout)460 public static int runPocGetExitStatus( 461 String pocName, 462 String arguments, 463 Map<String, String> envVars, 464 ITestDevice device, 465 int timeout) 466 throws Exception { 467 return runPoc(pocName, device, timeout, arguments, envVars, null); 468 } 469 470 /** 471 * Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable. 472 * 473 * @deprecated Use {@link NativePoc} instead. 474 * @param pocName a string path to poc from the /res folder 475 * @param device device to be ran on 476 * @param timeout time to wait for output in seconds 477 */ 478 @Deprecated runPocAssertExitStatusNotVulnerable( String pocName, ITestDevice device, int timeout)479 public static void runPocAssertExitStatusNotVulnerable( 480 String pocName, ITestDevice device, int timeout) throws Exception { 481 runPocAssertExitStatusNotVulnerable(pocName, null, device, timeout); 482 } 483 484 /** 485 * Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable. 486 * 487 * @deprecated Use {@link NativePoc} instead. 488 * @param pocName a string path to poc from the /res folder 489 * @param arguments input arguments for the poc 490 * @param device device to be ran on 491 * @param timeout time to wait for output in seconds 492 */ 493 @Deprecated runPocAssertExitStatusNotVulnerable( String pocName, String arguments, ITestDevice device, int timeout)494 public static void runPocAssertExitStatusNotVulnerable( 495 String pocName, String arguments, ITestDevice device, int timeout) throws Exception { 496 runPocAssertExitStatusNotVulnerable(pocName, arguments, null, device, timeout); 497 } 498 499 /** 500 * Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable. 501 * 502 * @deprecated Use {@link NativePoc} instead. 503 * @param pocName name of the poc binary 504 * @param arguments input arguments for the poc 505 * @param envVars run the poc with environment variables 506 * @param device device to be ran on 507 * @param timeout time to wait for output in seconds 508 */ 509 @Deprecated runPocAssertExitStatusNotVulnerable( String pocName, String arguments, Map<String, String> envVars, ITestDevice device, int timeout)510 public static void runPocAssertExitStatusNotVulnerable( 511 String pocName, 512 String arguments, 513 Map<String, String> envVars, 514 ITestDevice device, 515 int timeout) 516 throws Exception { 517 assertTrue("PoC returned exit status 113: vulnerable", 518 runPocGetExitStatus(pocName, arguments, envVars, device, timeout) != 113); 519 } 520 521 /** 522 * Runs the poc binary and asserts that there are no security crashes that match the expected 523 * process pattern. 524 * 525 * @deprecated Use {@link NativePoc} instead. 526 * @param pocName a string path to poc from the /res folder 527 * @param device device to be ran on 528 * @param processPatternStrings a Pattern string to match the crash tombstone process 529 */ 530 @Deprecated runPocAssertNoCrashes( String pocName, ITestDevice device, String... processPatternStrings)531 public static void runPocAssertNoCrashes( 532 String pocName, ITestDevice device, String... processPatternStrings) throws Exception { 533 runPocAssertNoCrashes(pocName, device, 534 new TombstoneUtils.Config().setProcessPatterns(processPatternStrings)); 535 } 536 537 /** 538 * Runs the poc binary and asserts that there are no security crashes that match the expected 539 * process pattern. 540 * 541 * @deprecated Use {@link NativePoc} instead. 542 * @param pocName a string path to poc from the /res folder 543 * @param device device to be ran on 544 * @param config a crash parser configuration 545 */ 546 @Deprecated runPocAssertNoCrashes( String pocName, ITestDevice device, TombstoneUtils.Config config)547 public static void runPocAssertNoCrashes( 548 String pocName, ITestDevice device, TombstoneUtils.Config config) throws Exception { 549 runPocAssertNoCrashes(pocName, device, null, config); 550 } 551 552 /** 553 * Runs the poc binary and asserts that there are no security crashes that match the expected 554 * process pattern, including arguments when running. 555 * 556 * @deprecated Use {@link NativePoc} instead. 557 * @param pocName a string path to poc from the /res folder 558 * @param device device to be ran on 559 * @param arguments input arguments for the poc 560 * @param config a crash parser configuration 561 */ 562 @Deprecated runPocAssertNoCrashes( String pocName, ITestDevice device, String arguments, TombstoneUtils.Config config)563 public static void runPocAssertNoCrashes( 564 String pocName, ITestDevice device, String arguments, TombstoneUtils.Config config) 565 throws Exception { 566 try (AutoCloseable a = TombstoneUtils.withAssertNoSecurityCrashes(device, config)) { 567 AdbUtils.runPocNoOutput(pocName, device, 568 SecurityTestCase.TIMEOUT_NONDETERMINISTIC, arguments); 569 } 570 } 571 572 /** 573 * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in 574 * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability 575 * condition). 576 * 577 * @deprecated Use {@link NativePoc} instead. 578 * @param binaryName name of the binary 579 * @param arguments arguments for running the binary 580 * @param device device to be run on 581 */ 582 @Deprecated runPocAssertNoCrashesNotVulnerable( String binaryName, String arguments, ITestDevice device)583 public static void runPocAssertNoCrashesNotVulnerable( 584 String binaryName, String arguments, ITestDevice device) throws Exception { 585 runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device, null); 586 } 587 588 /** 589 * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in 590 * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability 591 * condition). 592 * 593 * @deprecated Use {@link NativePoc} instead. 594 * @param binaryName name of the binary 595 * @param arguments arguments for running the binary 596 * @param device device to be run on 597 * @param processPatternStrings a Pattern string to match the crash tombstone process 598 */ 599 @Deprecated runPocAssertNoCrashesNotVulnerable( String binaryName, String arguments, ITestDevice device, String processPatternStrings[])600 public static void runPocAssertNoCrashesNotVulnerable( 601 String binaryName, String arguments, ITestDevice device, String processPatternStrings[]) 602 throws Exception { 603 runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device, 604 processPatternStrings); 605 } 606 607 /** 608 * Runs the poc binary and asserts following 2 conditions. 1. There are no security crashes in 609 * the binary. 2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability 610 * condition). 611 * 612 * @deprecated Use {@link NativePoc} instead. 613 * @param binaryName name of the binary 614 * @param arguments arguments for running the binary 615 * @param inputFiles files required as input 616 * @param inputFilesDestination destination directory to which input files are pushed 617 * @param device device to be run on 618 */ 619 @Deprecated runPocAssertNoCrashesNotVulnerable( String binaryName, String arguments, String inputFiles[], String inputFilesDestination, ITestDevice device)620 public static void runPocAssertNoCrashesNotVulnerable( 621 String binaryName, 622 String arguments, 623 String inputFiles[], 624 String inputFilesDestination, 625 ITestDevice device) 626 throws Exception { 627 runPocAssertNoCrashesNotVulnerable(binaryName, arguments, inputFiles, inputFilesDestination, 628 device, null); 629 } 630 631 /** 632 * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in 633 * the binary. 2. There are no security crashes that match the expected process pattern. 3. The 634 * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition). 635 * 636 * @deprecated Use {@link NativePoc} instead. 637 * @param binaryName name of the binary 638 * @param arguments arguments for running the binary 639 * @param inputFiles files required as input 640 * @param inputFilesDestination destination directory to which input files are pushed 641 * @param device device to be run on 642 * @param processPatternStrings a Pattern string to match the crash tombstone process 643 */ 644 @Deprecated runPocAssertNoCrashesNotVulnerable( String binaryName, String arguments, String inputFiles[], String inputFilesDestination, ITestDevice device, String processPatternStrings[])645 public static void runPocAssertNoCrashesNotVulnerable( 646 String binaryName, 647 String arguments, 648 String inputFiles[], 649 String inputFilesDestination, 650 ITestDevice device, 651 String processPatternStrings[]) 652 throws Exception { 653 runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, 654 inputFiles, inputFilesDestination, device, processPatternStrings); 655 } 656 657 /** 658 * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in 659 * the binary. 2. There are no security crashes that match the expected process pattern. 3. The 660 * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition). 661 * 662 * @deprecated Use {@link NativePoc} instead. 663 * @param binaryName name of the binary 664 * @param arguments arguments for running the binary 665 * @param envVars run the poc with environment variables 666 * @param inputFiles files required as input 667 * @param inputFilesDestination destination directory to which input files are pushed 668 * @param device device to be run on 669 * @param processPatternStrings a Pattern string (other than binary name) to match the crash 670 * tombstone process 671 */ 672 @Deprecated runPocAssertNoCrashesNotVulnerable( String binaryName, String arguments, Map<String, String> envVars, String inputFiles[], String inputFilesDestination, ITestDevice device, String... processPatternStrings)673 public static void runPocAssertNoCrashesNotVulnerable( 674 String binaryName, 675 String arguments, 676 Map<String, String> envVars, 677 String inputFiles[], 678 String inputFilesDestination, 679 ITestDevice device, 680 String... processPatternStrings) 681 throws Exception { 682 pocConfig testConfig = new pocConfig(binaryName, device); 683 testConfig.arguments = arguments; 684 testConfig.envVars = envVars; 685 686 if (inputFiles != null) { 687 testConfig.inputFiles = Arrays.asList(inputFiles); 688 testConfig.inputFilesDestination = inputFilesDestination; 689 } 690 691 List<String> processPatternList = new ArrayList<>(); 692 if (processPatternStrings != null) { 693 processPatternList.addAll(Arrays.asList(processPatternStrings)); 694 } 695 processPatternList.add(binaryName); 696 String[] processPatternStringsWithSelf = new String[processPatternList.size()]; 697 processPatternList.toArray(processPatternStringsWithSelf); 698 testConfig.config = 699 new TombstoneUtils.Config().setProcessPatterns(processPatternStringsWithSelf); 700 701 runPocAssertNoCrashesNotVulnerable(testConfig); 702 } 703 704 /** 705 * Runs the poc binary and asserts following 3 conditions. 1. There are no security crashes in 706 * the binary. 2. There are no security crashes that match the expected process pattern. 3. The 707 * exit status isn't 113 (Code 113 is used to indicate the vulnerability condition). 708 * 709 * @deprecated Use {@link NativePoc} instead. 710 * @param testConfig test configuration 711 */ 712 @Deprecated runPocAssertNoCrashesNotVulnerable(pocConfig testConfig)713 public static void runPocAssertNoCrashesNotVulnerable(pocConfig testConfig) throws Exception { 714 String[] inputFiles = null; 715 if(!testConfig.inputFiles.isEmpty()) { 716 inputFiles = testConfig.inputFiles.toArray(new String[testConfig.inputFiles.size()]); 717 pushResources(inputFiles, testConfig.inputFilesDestination, testConfig.device); 718 } 719 try (AutoCloseable a = 720 TombstoneUtils.withAssertNoSecurityCrashes(testConfig.device, testConfig.config)) { 721 runPocAssertExitStatusNotVulnerable(testConfig.binaryName, testConfig.arguments, 722 testConfig.envVars, testConfig.device, TIMEOUT_SEC); 723 } catch (IllegalArgumentException e) { 724 /* 725 * Since 'runPocGetExitStatus' method raises IllegalArgumentException upon 726 * hang/timeout, catching the exception here and ignoring it. Hangs are of 727 * Moderate severity and hence patches may not be ported. This piece of code can 728 * be removed once 'runPocGetExitStatus' is updated to handle hangs. 729 */ 730 CLog.w("Ignoring IllegalArgumentException: " + e); 731 } finally { 732 if (!testConfig.inputFiles.isEmpty()) { 733 removeResources(inputFiles, testConfig.inputFilesDestination, testConfig.device); 734 } 735 } 736 } 737 assumeHasNfc(ITestDevice device)738 public static void assumeHasNfc(ITestDevice device) throws DeviceNotAvailableException { 739 assumeTrue("nfc not available on device", device.hasFeature("android.hardware.nfc")); 740 } 741 742 /** 743 * Escapes regex special characters in the given string 744 * 745 * @param testString string for which special characters need to be escaped 746 * 747 * @return string with escaped special charcters 748 */ escapeRegexSpecialChars(String testString)749 public static String escapeRegexSpecialChars(String testString) { 750 Matcher m = regexSpecialCharsEscapedPattern.matcher(testString); 751 return m.replaceAll("\\\\$0"); 752 } 753 } 754