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 * This code was provided to AOSP by Zimperium Inc and was 18 * written by: 19 * 20 * Simone "evilsocket" Margaritelli 21 * Joshua "jduck" Drake 22 */ 23 package android.security.cts; 24 25 import android.test.AndroidTestCase; 26 import android.util.Log; 27 import android.content.Context; 28 import android.content.res.AssetFileDescriptor; 29 import android.content.res.Resources; 30 import android.graphics.Bitmap; 31 import android.graphics.BitmapFactory; 32 import android.graphics.SurfaceTexture; 33 import android.media.MediaCodec; 34 import android.media.MediaCodecInfo; 35 import android.media.MediaCodecList; 36 import android.media.MediaDrm; 37 import android.media.MediaDrm.MediaDrmStateException; 38 import android.media.MediaExtractor; 39 import android.media.MediaFormat; 40 import android.media.MediaMetadataRetriever; 41 import android.media.MediaPlayer; 42 import android.opengl.GLES20; 43 import android.opengl.GLES11Ext; 44 import android.os.Looper; 45 import android.os.SystemClock; 46 import android.platform.test.annotations.SecurityTest; 47 import android.test.InstrumentationTestCase; 48 import android.util.Log; 49 import android.view.Surface; 50 import android.webkit.cts.CtsTestServer; 51 52 import java.io.BufferedInputStream; 53 import java.io.FileInputStream; 54 import java.io.IOException; 55 import java.io.InputStream; 56 import java.net.URL; 57 import java.nio.ByteBuffer; 58 import java.io.FileOutputStream; 59 import java.io.File; 60 import java.util.ArrayList; 61 import java.util.HashMap; 62 import java.util.UUID; 63 import java.util.concurrent.locks.Condition; 64 import java.util.concurrent.locks.ReentrantLock; 65 66 import android.security.cts.R; 67 68 69 /** 70 * Verify that the device is not vulnerable to any known Stagefright 71 * vulnerabilities. 72 */ 73 @SecurityTest 74 public class StagefrightTest extends InstrumentationTestCase { 75 static final String TAG = "StagefrightTest"; 76 77 private final long TIMEOUT_NS = 10000000000L; // 10 seconds. 78 StagefrightTest()79 public StagefrightTest() { 80 } 81 82 /*********************************************************** 83 to prevent merge conflicts, add K tests below this comment, 84 before any existing test methods 85 ***********************************************************/ 86 87 @SecurityTest testStagefright_bug_36725407()88 public void testStagefright_bug_36725407() throws Exception { 89 doStagefrightTest(R.raw.bug_36725407); 90 } 91 92 @SecurityTest testStagefright_cve_2016_3829()93 public void testStagefright_cve_2016_3829() throws Exception { 94 doStagefrightTest(R.raw.cve_2016_3829); 95 } 96 97 @SecurityTest testStagefright_cve_2016_3828()98 public void testStagefright_cve_2016_3828() throws Exception { 99 doStagefrightTest(R.raw.cve_2016_3828); 100 } 101 102 @SecurityTest testStagefright_bug_64710074()103 public void testStagefright_bug_64710074() throws Exception { 104 doStagefrightTest(R.raw.bug_64710074); 105 } 106 107 @SecurityTest testStagefright_cve_2017_0643()108 public void testStagefright_cve_2017_0643() throws Exception { 109 doStagefrightTest(R.raw.cve_2017_0643); 110 } 111 112 @SecurityTest testStagefright_cve_2017_0728()113 public void testStagefright_cve_2017_0728() throws Exception { 114 doStagefrightTest(R.raw.cve_2017_0728); 115 } 116 117 @SecurityTest testStagefright_bug_62187433()118 public void testStagefright_bug_62187433() throws Exception { 119 doStagefrightTest(R.raw.bug_62187433); 120 } 121 122 @SecurityTest testStagefrightANR_bug_62673844()123 public void testStagefrightANR_bug_62673844() throws Exception { 124 doStagefrightTestANR(R.raw.bug_62673844); 125 } 126 127 @SecurityTest testStagefright_bug_37079296()128 public void testStagefright_bug_37079296() throws Exception { 129 doStagefrightTest(R.raw.bug_37079296); 130 } 131 132 @SecurityTest testStagefright_bug_38342499()133 public void testStagefright_bug_38342499() throws Exception { 134 doStagefrightTest(R.raw.bug_38342499); 135 } 136 137 @SecurityTest testStagefright_bug_22771132()138 public void testStagefright_bug_22771132() throws Exception { 139 doStagefrightTest(R.raw.bug_22771132); 140 } 141 testStagefright_bug_21443020()142 public void testStagefright_bug_21443020() throws Exception { 143 doStagefrightTest(R.raw.bug_21443020_webm); 144 } 145 testStagefright_bug_34360591()146 public void testStagefright_bug_34360591() throws Exception { 147 doStagefrightTest(R.raw.bug_34360591); 148 } 149 testStagefright_bug_35763994()150 public void testStagefright_bug_35763994() throws Exception { 151 doStagefrightTest(R.raw.bug_35763994); 152 } 153 154 @SecurityTest testStagefright_bug_33137046()155 public void testStagefright_bug_33137046() throws Exception { 156 doStagefrightTest(R.raw.bug_33137046); 157 } 158 159 @SecurityTest testStagefright_cve_2016_2507()160 public void testStagefright_cve_2016_2507() throws Exception { 161 doStagefrightTest(R.raw.cve_2016_2507); 162 } 163 164 @SecurityTest testStagefright_bug_31647370()165 public void testStagefright_bug_31647370() throws Exception { 166 doStagefrightTest(R.raw.bug_31647370); 167 } 168 169 @SecurityTest testStagefright_bug_32577290()170 public void testStagefright_bug_32577290() throws Exception { 171 doStagefrightTest(R.raw.bug_32577290); 172 } 173 174 @SecurityTest testStagefright_cve_2015_1538_1()175 public void testStagefright_cve_2015_1538_1() throws Exception { 176 doStagefrightTest(R.raw.cve_2015_1538_1); 177 } 178 179 @SecurityTest testStagefright_cve_2015_1538_2()180 public void testStagefright_cve_2015_1538_2() throws Exception { 181 doStagefrightTest(R.raw.cve_2015_1538_2); 182 } 183 184 @SecurityTest testStagefright_cve_2015_1538_3()185 public void testStagefright_cve_2015_1538_3() throws Exception { 186 doStagefrightTest(R.raw.cve_2015_1538_3); 187 } 188 189 @SecurityTest testStagefright_cve_2015_1538_4()190 public void testStagefright_cve_2015_1538_4() throws Exception { 191 doStagefrightTest(R.raw.cve_2015_1538_4); 192 } 193 194 @SecurityTest testStagefright_cve_2015_1539()195 public void testStagefright_cve_2015_1539() throws Exception { 196 doStagefrightTest(R.raw.cve_2015_1539); 197 } 198 199 @SecurityTest testStagefright_cve_2015_3824()200 public void testStagefright_cve_2015_3824() throws Exception { 201 doStagefrightTest(R.raw.cve_2015_3824); 202 } 203 204 @SecurityTest testStagefright_cve_2015_3826()205 public void testStagefright_cve_2015_3826() throws Exception { 206 doStagefrightTest(R.raw.cve_2015_3826); 207 } 208 209 @SecurityTest testStagefright_cve_2015_3827()210 public void testStagefright_cve_2015_3827() throws Exception { 211 doStagefrightTest(R.raw.cve_2015_3827); 212 } 213 214 @SecurityTest testStagefright_cve_2015_3828()215 public void testStagefright_cve_2015_3828() throws Exception { 216 doStagefrightTest(R.raw.cve_2015_3828); 217 } 218 219 @SecurityTest testStagefright_cve_2015_3829()220 public void testStagefright_cve_2015_3829() throws Exception { 221 doStagefrightTest(R.raw.cve_2015_3829); 222 } 223 224 @SecurityTest testStagefright_cve_2015_3836()225 public void testStagefright_cve_2015_3836() throws Exception { 226 doStagefrightTest(R.raw.cve_2015_3836); 227 } 228 229 @SecurityTest testStagefright_cve_2015_3864()230 public void testStagefright_cve_2015_3864() throws Exception { 231 doStagefrightTest(R.raw.cve_2015_3864); 232 } 233 234 @SecurityTest testStagefright_cve_2015_3864_b23034759()235 public void testStagefright_cve_2015_3864_b23034759() throws Exception { 236 doStagefrightTest(R.raw.cve_2015_3864_b23034759); 237 } 238 239 @SecurityTest testStagefright_cve_2015_6598()240 public void testStagefright_cve_2015_6598() throws Exception { 241 doStagefrightTest(R.raw.cve_2015_6598); 242 } 243 244 @SecurityTest testStagefright_cve_2016_6766()245 public void testStagefright_cve_2016_6766() throws Exception { 246 doStagefrightTest(R.raw.cve_2016_6766); 247 } 248 249 @SecurityTest testStagefright_bug_26366256()250 public void testStagefright_bug_26366256() throws Exception { 251 doStagefrightTest(R.raw.bug_26366256); 252 } 253 254 @SecurityTest testStagefright_cve_2016_2429_b_27211885()255 public void testStagefright_cve_2016_2429_b_27211885() throws Exception { 256 doStagefrightTest(R.raw.cve_2016_2429_b_27211885); 257 } 258 259 @SecurityTest testStagefright_bug_34031018()260 public void testStagefright_bug_34031018() throws Exception { 261 doStagefrightTest(R.raw.bug_34031018_32bit); 262 doStagefrightTest(R.raw.bug_34031018_64bit); 263 } 264 265 /*********************************************************** 266 to prevent merge conflicts, add L tests below this comment, 267 before any existing test methods 268 ***********************************************************/ 269 270 @SecurityTest testStagefright_bug_65123471()271 public void testStagefright_bug_65123471() throws Exception { 272 doStagefrightTest(R.raw.bug_65123471); 273 } 274 275 @SecurityTest testStagefright_bug_72165027()276 public void testStagefright_bug_72165027() throws Exception { 277 doStagefrightTest(R.raw.bug_72165027); 278 } 279 280 @SecurityTest testStagefright_bug_65483665()281 public void testStagefright_bug_65483665() throws Exception { 282 doStagefrightTest(R.raw.bug_65483665); 283 } 284 285 @SecurityTest testStagefright_cve_2017_0852_b_62815506()286 public void testStagefright_cve_2017_0852_b_62815506() throws Exception { 287 doStagefrightTest(R.raw.cve_2017_0852_b_62815506); 288 } 289 290 @SecurityTest testStagefright_cve_2017_13229()291 public void testStagefright_cve_2017_13229() throws Exception { 292 doStagefrightTest(R.raw.cve_2017_13229); 293 } 294 295 @SecurityTest testStagefright_cve_2017_0763()296 public void testStagefright_cve_2017_0763() throws Exception { 297 doStagefrightTest(R.raw.cve_2017_0763); 298 } 299 300 /*********************************************************** 301 to prevent merge conflicts, add M tests below this comment, 302 before any existing test methods 303 ***********************************************************/ 304 305 @SecurityTest testStagefright_bug_68953854()306 public void testStagefright_bug_68953854() throws Exception { 307 doStagefrightTest(R.raw.bug_68953854, 1 * 60 * 1000); 308 } 309 310 @SecurityTest testStagefright_bug_38448381()311 public void testStagefright_bug_38448381() throws Exception { 312 doStagefrightTest(R.raw.bug_38448381); 313 } 314 315 @SecurityTest testStagefright_cve_2016_3821()316 public void testStagefright_cve_2016_3821() throws Exception { 317 doStagefrightTest(R.raw.cve_2016_3821); 318 } 319 320 @SecurityTest testStagefright_bug_70897454()321 public void testStagefright_bug_70897454() throws Exception { 322 doStagefrightTestRawBlob(R.raw.b70897454_avc, "video/avc", 320, 420); 323 } 324 325 @SecurityTest testStagefright_bug_38115076()326 public void testStagefright_bug_38115076() throws Exception { 327 doStagefrightTest(R.raw.bug_38115076); 328 } 329 330 @SecurityTest testStagefright_bug_34618607()331 public void testStagefright_bug_34618607() throws Exception { 332 doStagefrightTest(R.raw.bug_34618607); 333 } 334 335 @SecurityTest testStagefright_bug_69478425()336 public void testStagefright_bug_69478425() throws Exception { 337 doStagefrightTest(R.raw.bug_69478425); 338 } 339 340 @SecurityTest testStagefright_bug_65735716()341 public void testStagefright_bug_65735716() throws Exception { 342 doStagefrightTestRawBlob(R.raw.bug_65735716_avc, "video/avc", 320, 240); 343 } 344 345 @SecurityTest testStagefright_bug_65717533()346 public void testStagefright_bug_65717533() throws Exception { 347 doStagefrightTest(R.raw.bug_65717533_header_corrupt); 348 } 349 350 @SecurityTest testStagefright_bug_38239864()351 public void testStagefright_bug_38239864() throws Exception { 352 doStagefrightTest(R.raw.bug_38239864, (4 * 60 * 1000)); 353 } 354 355 @SecurityTest testStagefright_cve_2017_0600()356 public void testStagefright_cve_2017_0600() throws Exception { 357 doStagefrightTest(R.raw.cve_2017_0600); 358 } 359 360 @SecurityTest testBug_38014992()361 public void testBug_38014992() throws Exception { 362 int[] frameSizes = getFrameSizes(R.raw.bug_38014992_framelen); 363 doStagefrightTestRawBlob(R.raw.bug_38014992_avc, "video/avc", 640, 480, frameSizes); 364 } 365 366 @SecurityTest testBug_35584425()367 public void testBug_35584425() throws Exception { 368 int[] frameSizes = getFrameSizes(R.raw.bug_35584425_framelen); 369 doStagefrightTestRawBlob(R.raw.bug_35584425_avc, "video/avc", 352, 288, frameSizes); 370 } 371 372 @SecurityTest testBug_31092462()373 public void testBug_31092462() throws Exception { 374 int[] frameSizes = getFrameSizes(R.raw.bug_31092462_framelen); 375 doStagefrightTestRawBlob(R.raw.bug_31092462_avc, "video/avc", 1280, 1024, frameSizes); 376 } 377 378 @SecurityTest testBug_34097866()379 public void testBug_34097866() throws Exception { 380 int[] frameSizes = getFrameSizes(R.raw.bug_34097866_frame_len); 381 doStagefrightTestRawBlob(R.raw.bug_34097866_avc, "video/avc", 352, 288, frameSizes); 382 } 383 384 @SecurityTest testBug_33862021()385 public void testBug_33862021() throws Exception { 386 int[] frameSizes = getFrameSizes(R.raw.bug_33862021_frame_len); 387 doStagefrightTestRawBlob(R.raw.bug_33862021_hevc, "video/hevc", 160, 96, frameSizes); 388 } 389 390 @SecurityTest testBug_33387820()391 public void testBug_33387820() throws Exception { 392 int[] frameSizes = {45, 3202, 430, 2526}; 393 doStagefrightTestRawBlob(R.raw.bug_33387820_avc, "video/avc", 320, 240, frameSizes); 394 } 395 396 @SecurityTest testBug_37008096()397 public void testBug_37008096() throws Exception { 398 int[] frameSizes = {245, 12, 33, 140, 164}; 399 doStagefrightTestRawBlob(R.raw.bug_37008096_avc, "video/avc", 320, 240, frameSizes); 400 } 401 402 @SecurityTest testStagefright_bug_34231163()403 public void testStagefright_bug_34231163() throws Exception { 404 int[] frameSizes = {22, 357, 217, 293, 175}; 405 doStagefrightTestRawBlob(R.raw.bug_34231163_mpeg2, "video/mpeg2", 320, 240, frameSizes); 406 } 407 408 @SecurityTest testStagefright_bug_33933140()409 public void testStagefright_bug_33933140() throws Exception { 410 int[] frameSizes = getFrameSizes(R.raw.bug_33933140_framelen); 411 doStagefrightTestRawBlob(R.raw.bug_33933140_avc, "video/avc", 320, 240, frameSizes); 412 } 413 414 @SecurityTest testStagefright_bug_34097915()415 public void testStagefright_bug_34097915() throws Exception { 416 int[] frameSizes = {4140, 593, 0, 15495}; 417 doStagefrightTestRawBlob(R.raw.bug_34097915_avc, "video/avc", 320, 240, frameSizes); 418 } 419 420 @SecurityTest testStagefright_bug_34097213()421 public void testStagefright_bug_34097213() throws Exception { 422 int[] frameSizes = {2571, 210, 33858}; 423 doStagefrightTestRawBlob(R.raw.bug_34097213_avc, "video/avc", 320, 240, frameSizes); 424 } 425 426 @SecurityTest testBug_28816956()427 public void testBug_28816956() throws Exception { 428 int[] frameSizes = getFrameSizes(R.raw.bug_28816956_framelen); 429 doStagefrightTestRawBlob(R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes); 430 } 431 432 @SecurityTest testBug_33818500()433 public void testBug_33818500() throws Exception { 434 int[] frameSizes = getFrameSizes(R.raw.bug_33818500_framelen); 435 doStagefrightTestRawBlob(R.raw.bug_33818500_avc, "video/avc", 64, 32, frameSizes); 436 } 437 438 @SecurityTest testBug_64784973()439 public void testBug_64784973() throws Exception { 440 int[] frameSizes = getFrameSizes(R.raw.bug_64784973_framelen); 441 doStagefrightTestRawBlob(R.raw.bug_64784973_hevc, "video/hevc", 1280, 720, frameSizes); 442 } 443 444 @SecurityTest testBug_34231231()445 public void testBug_34231231() throws Exception { 446 int[] frameSizes = getFrameSizes(R.raw.bug_34231231_framelen); 447 doStagefrightTestRawBlob(R.raw.bug_34231231_mpeg2, "video/mpeg2", 352, 288, frameSizes); 448 } 449 450 @SecurityTest testBug_63045918()451 public void testBug_63045918() throws Exception { 452 int[] frameSizes = getFrameSizes(R.raw.bug_63045918_framelen); 453 doStagefrightTestRawBlob(R.raw.bug_63045918_hevc, "video/hevc", 352, 288, frameSizes); 454 } 455 456 @SecurityTest testBug_33298089()457 public void testBug_33298089() throws Exception { 458 int[] frameSizes = {3247, 430, 221, 2305}; 459 doStagefrightTestRawBlob(R.raw.bug_33298089_avc, "video/avc", 32, 64, frameSizes); 460 } 461 462 @SecurityTest testStagefright_cve_2017_0599()463 public void testStagefright_cve_2017_0599() throws Exception { 464 doStagefrightTest(R.raw.cve_2017_0599); 465 } 466 467 @SecurityTest testStagefright_bug_36492741()468 public void testStagefright_bug_36492741() throws Exception { 469 doStagefrightTest(R.raw.bug_36492741); 470 } 471 472 @SecurityTest testStagefright_bug_38487564()473 public void testStagefright_bug_38487564() throws Exception { 474 doStagefrightTest(R.raw.bug_38487564, (4 * 60 * 1000)); 475 } 476 477 @SecurityTest testStagefright_bug_37237396()478 public void testStagefright_bug_37237396() throws Exception { 479 doStagefrightTest(R.raw.bug_37237396); 480 } 481 482 @SecurityTest testStagefright_cve_2016_0842()483 public void testStagefright_cve_2016_0842() throws Exception { 484 doStagefrightTest(R.raw.cve_2016_0842); 485 } 486 487 @SecurityTest testStagefright_bug_63121644()488 public void testStagefright_bug_63121644() throws Exception { 489 doStagefrightTest(R.raw.bug_63121644); 490 } 491 492 @SecurityTest testStagefright_cve_2016_6712()493 public void testStagefright_cve_2016_6712() throws Exception { 494 doStagefrightTest(R.raw.cve_2016_6712); 495 } 496 497 @SecurityTest testStagefright_bug_34097231()498 public void testStagefright_bug_34097231() throws Exception { 499 doStagefrightTestRawBlob(R.raw.bug_34097231_avc, "video/avc", 320, 240); 500 } 501 502 @SecurityTest testStagefright_bug_34097672()503 public void testStagefright_bug_34097672() throws Exception { 504 doStagefrightTest(R.raw.bug_34097672); 505 } 506 507 508 @SecurityTest testStagefright_bug_33751193()509 public void testStagefright_bug_33751193() throws Exception { 510 doStagefrightTestRawBlob(R.raw.bug_33751193_avc, "video/avc", 320, 240); 511 } 512 513 @SecurityTest testBug_36993291()514 public void testBug_36993291() throws Exception { 515 doStagefrightTestRawBlob(R.raw.bug_36993291_avc, "video/avc", 320, 240); 516 } 517 518 @SecurityTest testStagefright_bug_33818508()519 public void testStagefright_bug_33818508() throws Exception { 520 doStagefrightTest(R.raw.bug_33818508); 521 } 522 523 @SecurityTest testStagefright_bug_32873375()524 public void testStagefright_bug_32873375() throws Exception { 525 doStagefrightTest(R.raw.bug_32873375); 526 } 527 528 @SecurityTest testStagefright_bug_63522067()529 public void testStagefright_bug_63522067() throws Exception { 530 doStagefrightTestRawBlob(R.raw.bug_63522067_1_hevc, "video/hevc", 320, 420); 531 doStagefrightTestRawBlob(R.raw.bug_63522067_2_hevc, "video/hevc", 320, 420); 532 doStagefrightTestRawBlob(R.raw.bug_63522067_3_hevc, "video/hevc", 320, 420); 533 doStagefrightTestRawBlob(R.raw.bug_63522067_4_hevc, "video/hevc", 320, 420); 534 } 535 536 @SecurityTest testStagefright_bug_25765591()537 public void testStagefright_bug_25765591() throws Exception { 538 doStagefrightTest(R.raw.bug_25765591); 539 } 540 541 @SecurityTest testStagefright_bug_62673179()542 public void testStagefright_bug_62673179() throws Exception { 543 doStagefrightTest(R.raw.bug_62673179_ts, (4 * 60 * 1000)); 544 } 545 546 @SecurityTest testStagefright_bug_69269702()547 public void testStagefright_bug_69269702() throws Exception { 548 doStagefrightTest(R.raw.bug_69269702); 549 } 550 551 @SecurityTest testStagefright_cve_2015_3867()552 public void testStagefright_cve_2015_3867() throws Exception { 553 doStagefrightTest(R.raw.cve_2015_3867); 554 } 555 556 @SecurityTest testStagefright_bug_65398821()557 public void testStagefright_bug_65398821() throws Exception { 558 doStagefrightTest(R.raw.bug_65398821, ( 4 * 60 * 1000 ) ); 559 } 560 561 @SecurityTest testStagefright_cve_2015_3869()562 public void testStagefright_cve_2015_3869() throws Exception { 563 doStagefrightTest(R.raw.cve_2015_3869); 564 } 565 566 @SecurityTest testStagefright_bug_23452792()567 public void testStagefright_bug_23452792() throws Exception { 568 doStagefrightTest(R.raw.bug_23452792); 569 } 570 571 @SecurityTest testStagefright_cve_2016_3820()572 public void testStagefright_cve_2016_3820() throws Exception { 573 doStagefrightTest(R.raw.cve_2016_3820); 574 } 575 576 @SecurityTest testStagefright_cve_2016_3741()577 public void testStagefright_cve_2016_3741() throws Exception { 578 doStagefrightTest(R.raw.cve_2016_3741); 579 } 580 581 @SecurityTest testStagefright_cve_2016_2506()582 public void testStagefright_cve_2016_2506() throws Exception { 583 doStagefrightTest(R.raw.cve_2016_2506); 584 } 585 586 @SecurityTest testStagefright_cve_2016_2428()587 public void testStagefright_cve_2016_2428() throws Exception { 588 doStagefrightTest(R.raw.cve_2016_2428); 589 } 590 591 @SecurityTest testStagefright_bug_36592202()592 public void testStagefright_bug_36592202() throws Exception { 593 Resources resources = getInstrumentation().getContext().getResources(); 594 AssetFileDescriptor fd = resources.openRawResourceFd(R.raw.bug_36592202); 595 int page_size = 25627; 596 byte [] blob = new byte[page_size]; 597 598 // 127 bytes read and 25500 zeros constitute one Ogg page 599 FileInputStream fis = fd.createInputStream(); 600 int numRead = fis.read(blob); 601 fis.close(); 602 603 // Creating temp file 604 final File tempFile = File.createTempFile("poc_tmp", ".ogg", null); 605 606 try { 607 final FileOutputStream tempFos = new FileOutputStream(tempFile.getAbsolutePath()); 608 int bytesWritten = 0; 609 // Repeat data till size is ~1 GB 610 for (int i = 0; i < 50000; i++) { 611 tempFos.write(blob); 612 bytesWritten += page_size; 613 } 614 tempFos.close(); 615 616 final int fileSize = bytesWritten; 617 int timeout = (10 * 60 * 1000); 618 619 runWithTimeout(new Runnable() { 620 @Override 621 public void run() { 622 try { 623 doStagefrightTestMediaCodec(tempFile.getAbsolutePath()); 624 } catch (Exception | AssertionError e) { 625 if (!tempFile.delete()) { 626 Log.e(TAG, "Failed to delete temporary PoC file"); 627 } 628 fail("Operation was not successful"); 629 } 630 } 631 }, timeout); 632 } catch (Exception e) { 633 fail("Failed to test b/36592202"); 634 } finally { 635 if (!tempFile.delete()) { 636 Log.e(TAG, "Failed to delete temporary PoC file"); 637 } 638 } 639 } 640 641 @SecurityTest testStagefright_bug_30822755()642 public void testStagefright_bug_30822755() throws Exception { 643 doStagefrightTest(R.raw.bug_30822755); 644 } 645 646 @SecurityTest testStagefright_bug_32322258()647 public void testStagefright_bug_32322258() throws Exception { 648 doStagefrightTest(R.raw.bug_32322258); 649 } 650 651 @SecurityTest testStagefright_bug_37710346()652 public void testStagefright_bug_37710346() throws Exception { 653 UUID CLEARKEY_SCHEME_UUID = new UUID(0x1077efecc0b24d02L, 0xace33c1e52e2fb4bL); 654 655 String drmInitString = "0000003470737368" + 656 "01000000" + 657 "1077efecc0b24d02" + 658 "ace33c1e52e2fb4b" + 659 "10000001" + 660 "60061e017e477e87" + 661 "7e57d00d1ed00d1e" + 662 "00000000"; 663 int len = drmInitString.length(); 664 byte[] drmInitData = new byte[len / 2]; 665 for (int i = 0; i < len; i += 2) { 666 drmInitData[i / 2] = (byte) ((Character.digit(drmInitString.charAt(i), 16) << 4) + 667 Character.digit(drmInitString.charAt(i + 1), 16)); 668 } 669 670 try { 671 MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID); 672 byte[] sessionId; 673 String initDataType = "video/mp4"; 674 675 sessionId = drm.openSession(); 676 MediaDrm.KeyRequest drmRequest = drm.getKeyRequest(sessionId, drmInitData, 677 initDataType, MediaDrm.KEY_TYPE_STREAMING, null); 678 } catch (Exception e) { 679 if (!(e instanceof MediaDrmStateException)) 680 fail("media drm server died"); 681 } 682 } 683 684 @SecurityTest testStagefright_cve_2015_3873_b_23248776()685 public void testStagefright_cve_2015_3873_b_23248776() throws Exception { 686 doStagefrightTest(R.raw.cve_2015_3873_b_23248776); 687 } 688 689 @SecurityTest testStagefright_bug_35472997()690 public void testStagefright_bug_35472997() throws Exception { 691 doStagefrightTest(R.raw.bug_35472997); 692 } 693 694 @SecurityTest testStagefright_cve_2015_3873_b_20718524()695 public void testStagefright_cve_2015_3873_b_20718524() throws Exception { 696 doStagefrightTest(R.raw.cve_2015_3873_b_20718524); 697 } 698 699 @SecurityTest testStagefright_bug_34896431()700 public void testStagefright_bug_34896431() throws Exception { 701 doStagefrightTest(R.raw.bug_34896431); 702 } 703 704 @SecurityTest testStagefright_cve_2015_3862_b_22954006()705 public void testStagefright_cve_2015_3862_b_22954006() throws Exception { 706 doStagefrightTest(R.raw.cve_2015_3862_b_22954006); 707 } 708 709 @SecurityTest testStagefright_cve_2015_3867_b_23213430()710 public void testStagefright_cve_2015_3867_b_23213430() throws Exception { 711 doStagefrightTest(R.raw.cve_2015_3867_b_23213430); 712 } 713 714 @SecurityTest testStagefright_cve_2015_3873_b_21814993()715 public void testStagefright_cve_2015_3873_b_21814993() throws Exception { 716 doStagefrightTest(R.raw.cve_2015_3873_b_21814993); 717 } 718 719 @SecurityTest testStagefright_bug_25812590()720 public void testStagefright_bug_25812590() throws Exception { 721 doStagefrightTest(R.raw.bug_25812590); 722 } 723 testStagefright_cve_2015_6600()724 public void testStagefright_cve_2015_6600() throws Exception { 725 doStagefrightTest(R.raw.cve_2015_6600); 726 } 727 testStagefright_cve_2015_6603()728 public void testStagefright_cve_2015_6603() throws Exception { 729 doStagefrightTest(R.raw.cve_2015_6603); 730 } 731 testStagefright_cve_2015_6604()732 public void testStagefright_cve_2015_6604() throws Exception { 733 doStagefrightTest(R.raw.cve_2015_6604); 734 } 735 736 @SecurityTest testStagefright_bug_24157524()737 public void testStagefright_bug_24157524() throws Exception { 738 doStagefrightTest(R.raw.bug_24157524); 739 } 740 741 @SecurityTest testStagefright_cve_2015_3871()742 public void testStagefright_cve_2015_3871() throws Exception { 743 doStagefrightTest(R.raw.cve_2015_3871); 744 } 745 testStagefright_bug_26070014()746 public void testStagefright_bug_26070014() throws Exception { 747 doStagefrightTest(R.raw.bug_26070014); 748 } 749 testStagefright_bug_32915871()750 public void testStagefright_bug_32915871() throws Exception { 751 doStagefrightTest(R.raw.bug_32915871); 752 } 753 754 @SecurityTest testStagefright_bug_28333006()755 public void testStagefright_bug_28333006() throws Exception { 756 doStagefrightTest(R.raw.bug_28333006); 757 } 758 759 @SecurityTest testStagefright_bug_14388161()760 public void testStagefright_bug_14388161() throws Exception { 761 doStagefrightTestMediaPlayer(R.raw.bug_14388161); 762 } 763 764 @SecurityTest testStagefright_cve_2016_3755()765 public void testStagefright_cve_2016_3755() throws Exception { 766 doStagefrightTest(R.raw.cve_2016_3755); 767 } 768 769 @SecurityTest testStagefright_cve_2016_3878_b_29493002()770 public void testStagefright_cve_2016_3878_b_29493002() throws Exception { 771 doStagefrightTest(R.raw.cve_2016_3878_b_29493002); 772 } 773 774 @SecurityTest testStagefright_cve_2015_6608_b_23680780()775 public void testStagefright_cve_2015_6608_b_23680780() throws Exception { 776 doStagefrightTest(R.raw.cve_2015_6608_b_23680780); 777 } 778 779 @SecurityTest testStagefright_bug_27855419_CVE_2016_2463()780 public void testStagefright_bug_27855419_CVE_2016_2463() throws Exception { 781 doStagefrightTest(R.raw.bug_27855419); 782 } 783 testStagefright_bug_19779574()784 public void testStagefright_bug_19779574() throws Exception { 785 doStagefrightTest(R.raw.bug_19779574); 786 } 787 788 /*********************************************************** 789 to prevent merge conflicts, add N tests below this comment, 790 before any existing test methods 791 ***********************************************************/ 792 793 @SecurityTest testStagefright_cve_2017_0474()794 public void testStagefright_cve_2017_0474() throws Exception { 795 doStagefrightTest(R.raw.cve_2017_0474, 120000); 796 } 797 798 @SecurityTest testStagefright_cve_2017_0765()799 public void testStagefright_cve_2017_0765() throws Exception { 800 doStagefrightTest(R.raw.cve_2017_0765); 801 } 802 803 @SecurityTest testStagefright_cve_2017_13276()804 public void testStagefright_cve_2017_13276() throws Exception { 805 doStagefrightTest(R.raw.cve_2017_13276); 806 } 807 808 @SecurityTest testStagefright_cve_2016_6764()809 public void testStagefright_cve_2016_6764() throws Exception { 810 doStagefrightTest(R.raw.cve_2016_6764); 811 } 812 813 @SecurityTest testStagefright_cve_2017_13214()814 public void testStagefright_cve_2017_13214() throws Exception { 815 doStagefrightTest(R.raw.cve_2017_13214); 816 } 817 818 @SecurityTest testStagefright_bug_35467107()819 public void testStagefright_bug_35467107() throws Exception { 820 doStagefrightTest(R.raw.bug_35467107); 821 } 822 823 /*********************************************************** 824 to prevent merge conflicts, add O tests below this comment, 825 before any existing test methods 826 ***********************************************************/ 827 828 @SecurityTest testBug_67737022()829 public void testBug_67737022() throws Exception { 830 doStagefrightTest(R.raw.bug_67737022); 831 } 832 833 @SecurityTest testStagefright_bug_37093318()834 public void testStagefright_bug_37093318() throws Exception { 835 doStagefrightTest(R.raw.bug_37093318, (4 * 60 * 1000)); 836 } 837 838 @SecurityTest testStagefright_bug_73172046()839 public void testStagefright_bug_73172046() throws Exception { 840 doStagefrightTest(R.raw.bug_73172046); 841 842 Bitmap bitmap = BitmapFactory.decodeResource( 843 getInstrumentation().getContext().getResources(), R.raw.bug_73172046); 844 // OK if the decoding failed, but shouldn't cause crashes 845 if (bitmap != null) { 846 bitmap.recycle(); 847 } 848 } 849 850 @SecurityTest testStagefright_cve_2016_0824()851 public void testStagefright_cve_2016_0824() throws Exception { 852 doStagefrightTest(R.raw.cve_2016_0824); 853 } 854 855 @SecurityTest testStagefright_cve_2016_0815()856 public void testStagefright_cve_2016_0815() throws Exception { 857 doStagefrightTest(R.raw.cve_2016_0815); 858 } 859 860 @SecurityTest testStagefright_cve_2016_2454()861 public void testStagefright_cve_2016_2454() throws Exception { 862 doStagefrightTest(R.raw.cve_2016_2454); 863 } 864 865 @SecurityTest testStagefright_cve_2016_6765()866 public void testStagefright_cve_2016_6765() throws Exception { 867 doStagefrightTest(R.raw.cve_2016_6765); 868 } 869 870 @SecurityTest testStagefright_cve_2016_2508()871 public void testStagefright_cve_2016_2508() throws Exception { 872 doStagefrightTest(R.raw.cve_2016_2508); 873 } 874 875 @SecurityTest testStagefright_cve_2016_6699()876 public void testStagefright_cve_2016_6699() throws Exception { 877 doStagefrightTest(R.raw.cve_2016_6699); 878 } 879 doStagefrightTest(final int rid)880 private void doStagefrightTest(final int rid) throws Exception { 881 doStagefrightTestMediaPlayer(rid); 882 doStagefrightTestMediaCodec(rid); 883 doStagefrightTestMediaMetadataRetriever(rid); 884 885 Context context = getInstrumentation().getContext(); 886 Resources resources = context.getResources(); 887 CtsTestServer server = new CtsTestServer(context); 888 String rname = resources.getResourceEntryName(rid); 889 String url = server.getAssetUrl("raw/" + rname); 890 verifyServer(rid, url); 891 doStagefrightTestMediaPlayer(url); 892 doStagefrightTestMediaCodec(url); 893 doStagefrightTestMediaMetadataRetriever(url); 894 server.shutdown(); 895 } 896 897 // verify that CtsTestServer is functional by retrieving the asset 898 // and comparing it to the resource verifyServer(final int rid, final String uri)899 private void verifyServer(final int rid, final String uri) throws Exception { 900 Log.i(TAG, "checking server"); 901 URL url = new URL(uri); 902 InputStream in1 = new BufferedInputStream(url.openStream()); 903 904 AssetFileDescriptor fd = getInstrumentation().getContext().getResources() 905 .openRawResourceFd(rid); 906 InputStream in2 = new BufferedInputStream(fd.createInputStream()); 907 908 while (true) { 909 int b1 = in1.read(); 910 int b2 = in2.read(); 911 assertEquals("CtsTestServer fail", b1, b2); 912 if (b1 < 0) { 913 break; 914 } 915 } 916 917 in1.close(); 918 in2.close(); 919 Log.i(TAG, "checked server"); 920 } 921 doStagefrightTest(final int rid, int timeout)922 private void doStagefrightTest(final int rid, int timeout) throws Exception { 923 runWithTimeout(new Runnable() { 924 @Override 925 public void run() { 926 try { 927 doStagefrightTest(rid); 928 } catch (Exception e) { 929 fail(e.toString()); 930 } 931 } 932 }, timeout); 933 } 934 doStagefrightTestANR(final int rid)935 private void doStagefrightTestANR(final int rid) throws Exception { 936 doStagefrightTestMediaPlayerANR(rid, null); 937 } 938 getDummySurface()939 private Surface getDummySurface() { 940 int[] textures = new int[1]; 941 GLES20.glGenTextures(1, textures, 0); 942 GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]); 943 GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 944 GLES20.GL_TEXTURE_MIN_FILTER, 945 GLES20.GL_NEAREST); 946 GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 947 GLES20.GL_TEXTURE_MAG_FILTER, 948 GLES20.GL_LINEAR); 949 GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 950 GLES20.GL_TEXTURE_WRAP_S, 951 GLES20.GL_CLAMP_TO_EDGE); 952 GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 953 GLES20.GL_TEXTURE_WRAP_T, 954 GLES20.GL_CLAMP_TO_EDGE); 955 SurfaceTexture surfaceTex = new SurfaceTexture(textures[0]); 956 surfaceTex.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { 957 @Override 958 public void onFrameAvailable(SurfaceTexture surfaceTexture) { 959 Log.i(TAG, "new frame available"); 960 } 961 }); 962 return new Surface(surfaceTex); 963 } 964 965 class MediaPlayerCrashListener 966 implements MediaPlayer.OnErrorListener, 967 MediaPlayer.OnPreparedListener, 968 MediaPlayer.OnCompletionListener { 969 @Override onError(MediaPlayer mp, int newWhat, int extra)970 public boolean onError(MediaPlayer mp, int newWhat, int extra) { 971 Log.i(TAG, "error: " + newWhat + "/" + extra); 972 // don't overwrite a more severe error with a less severe one 973 if (what != MediaPlayer.MEDIA_ERROR_SERVER_DIED) { 974 what = newWhat; 975 } 976 lock.lock(); 977 condition.signal(); 978 lock.unlock(); 979 980 return true; // don't call oncompletion 981 } 982 983 @Override onPrepared(MediaPlayer mp)984 public void onPrepared(MediaPlayer mp) { 985 mp.start(); 986 } 987 988 @Override onCompletion(MediaPlayer mp)989 public void onCompletion(MediaPlayer mp) { 990 // preserve error condition, if any 991 lock.lock(); 992 completed = true; 993 condition.signal(); 994 lock.unlock(); 995 } 996 waitForError()997 public int waitForError() throws InterruptedException { 998 lock.lock(); 999 if (condition.awaitNanos(TIMEOUT_NS) <= 0) { 1000 Log.d(TAG, "timed out on waiting for error"); 1001 } 1002 lock.unlock(); 1003 if (what != 0) { 1004 // Sometimes mediaserver signals a decoding error first, and *then* crashes 1005 // due to additional in-flight buffers being processed, so wait a little 1006 // and see if more errors show up. 1007 SystemClock.sleep(1000); 1008 } 1009 return what; 1010 } 1011 waitForErrorOrCompletion()1012 public boolean waitForErrorOrCompletion() throws InterruptedException { 1013 lock.lock(); 1014 if (condition.awaitNanos(TIMEOUT_NS) <= 0) { 1015 Log.d(TAG, "timed out on waiting for error or completion"); 1016 } 1017 lock.unlock(); 1018 return (what != 0 && what != MediaPlayer.MEDIA_ERROR_SERVER_DIED) || completed; 1019 } 1020 1021 ReentrantLock lock = new ReentrantLock(); 1022 Condition condition = lock.newCondition(); 1023 int what; 1024 boolean completed = false; 1025 } 1026 1027 class LooperThread extends Thread { 1028 private Looper mLooper; 1029 LooperThread(Runnable runner)1030 LooperThread(Runnable runner) { 1031 super(runner); 1032 } 1033 1034 @Override run()1035 public void run() { 1036 Looper.prepare(); 1037 mLooper = Looper.myLooper(); 1038 super.run(); 1039 } 1040 stopLooper()1041 public void stopLooper() { 1042 mLooper.quitSafely(); 1043 } 1044 } 1045 doStagefrightTestMediaPlayer(final int rid)1046 private void doStagefrightTestMediaPlayer(final int rid) throws Exception { 1047 doStagefrightTestMediaPlayer(rid, null); 1048 } 1049 doStagefrightTestMediaPlayer(final String url)1050 private void doStagefrightTestMediaPlayer(final String url) throws Exception { 1051 doStagefrightTestMediaPlayer(-1, url); 1052 } 1053 closeQuietly(AutoCloseable closeable)1054 private void closeQuietly(AutoCloseable closeable) { 1055 if (closeable != null) { 1056 try { 1057 closeable.close(); 1058 } catch (RuntimeException rethrown) { 1059 throw rethrown; 1060 } catch (Exception ignored) { 1061 } 1062 } 1063 } 1064 doStagefrightTestMediaPlayer(final int rid, final String uri)1065 private void doStagefrightTestMediaPlayer(final int rid, final String uri) throws Exception { 1066 1067 String name = uri != null ? uri : 1068 getInstrumentation().getContext().getResources().getResourceEntryName(rid); 1069 Log.i(TAG, "start mediaplayer test for: " + name); 1070 1071 final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(); 1072 1073 LooperThread t = new LooperThread(new Runnable() { 1074 @Override 1075 public void run() { 1076 1077 MediaPlayer mp = new MediaPlayer(); 1078 mp.setOnErrorListener(mpcl); 1079 mp.setOnPreparedListener(mpcl); 1080 mp.setOnCompletionListener(mpcl); 1081 Surface surface = getDummySurface(); 1082 mp.setSurface(surface); 1083 AssetFileDescriptor fd = null; 1084 try { 1085 if (uri == null) { 1086 fd = getInstrumentation().getContext().getResources() 1087 .openRawResourceFd(rid); 1088 1089 mp.setDataSource(fd.getFileDescriptor(), 1090 fd.getStartOffset(), 1091 fd.getLength()); 1092 1093 } else { 1094 mp.setDataSource(uri); 1095 } 1096 mp.prepareAsync(); 1097 } catch (Exception e) { 1098 } finally { 1099 closeQuietly(fd); 1100 } 1101 1102 Looper.loop(); 1103 mp.release(); 1104 } 1105 }); 1106 1107 t.start(); 1108 String cve = name.replace("_", "-").toUpperCase(); 1109 assertFalse("Device *IS* vulnerable to " + cve, 1110 mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED); 1111 t.stopLooper(); 1112 t.join(); // wait for thread to exit so we're sure the player was released 1113 } 1114 doStagefrightTestMediaCodec(final int rid)1115 private void doStagefrightTestMediaCodec(final int rid) throws Exception { 1116 doStagefrightTestMediaCodec(rid, null); 1117 } 1118 doStagefrightTestMediaCodec(final String url)1119 private void doStagefrightTestMediaCodec(final String url) throws Exception { 1120 doStagefrightTestMediaCodec(-1, url); 1121 } 1122 doStagefrightTestMediaCodec(final int rid, final String url)1123 private void doStagefrightTestMediaCodec(final int rid, final String url) throws Exception { 1124 1125 final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(); 1126 1127 LooperThread thr = new LooperThread(new Runnable() { 1128 @Override 1129 public void run() { 1130 1131 MediaPlayer mp = new MediaPlayer(); 1132 mp.setOnErrorListener(mpcl); 1133 try { 1134 AssetFileDescriptor fd = getInstrumentation().getContext().getResources() 1135 .openRawResourceFd(R.raw.good); 1136 1137 // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until 1138 // setDataSource has been called 1139 mp.setDataSource(fd.getFileDescriptor(), 1140 fd.getStartOffset(), 1141 fd.getLength()); 1142 fd.close(); 1143 } catch (Exception e) { 1144 // this is a known-good file, so no failure should occur 1145 fail("setDataSource of known-good file failed"); 1146 } 1147 1148 synchronized(mpcl) { 1149 mpcl.notify(); 1150 } 1151 Looper.loop(); 1152 mp.release(); 1153 } 1154 }); 1155 thr.start(); 1156 // wait until the thread has initialized the MediaPlayer 1157 synchronized(mpcl) { 1158 mpcl.wait(); 1159 } 1160 1161 Resources resources = getInstrumentation().getContext().getResources(); 1162 MediaExtractor ex = new MediaExtractor(); 1163 if (url == null) { 1164 AssetFileDescriptor fd = resources.openRawResourceFd(rid); 1165 try { 1166 ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); 1167 } catch (IOException e) { 1168 // ignore 1169 } finally { 1170 closeQuietly(fd); 1171 } 1172 } else { 1173 try { 1174 ex.setDataSource(url); 1175 } catch (Exception e) { 1176 // indicative of problems with our tame CTS test web server 1177 } 1178 } 1179 int numtracks = ex.getTrackCount(); 1180 String rname = url != null ? url: resources.getResourceEntryName(rid); 1181 Log.i(TAG, "start mediacodec test for: " + rname + ", which has " + numtracks + " tracks"); 1182 for (int t = 0; t < numtracks; t++) { 1183 // find all the available decoders for this format 1184 ArrayList<String> matchingCodecs = new ArrayList<String>(); 1185 MediaFormat format = null; 1186 try { 1187 format = ex.getTrackFormat(t); 1188 } catch (IllegalArgumentException e) { 1189 Log.e(TAG, "could not get track format for track " + t); 1190 continue; 1191 } 1192 String mime = format.getString(MediaFormat.KEY_MIME); 1193 int numCodecs = MediaCodecList.getCodecCount(); 1194 for (int i = 0; i < numCodecs; i++) { 1195 MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); 1196 if (info.isEncoder()) { 1197 continue; 1198 } 1199 try { 1200 MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime); 1201 if (caps != null) { 1202 matchingCodecs.add(info.getName()); 1203 Log.i(TAG, "Found matching codec " + info.getName() + " for track " + t); 1204 } 1205 } catch (IllegalArgumentException e) { 1206 // type is not supported 1207 } 1208 } 1209 1210 if (matchingCodecs.size() == 0) { 1211 Log.w(TAG, "no codecs for track " + t + ", type " + mime); 1212 } 1213 // decode this track once with each matching codec 1214 try { 1215 ex.selectTrack(t); 1216 } catch (IllegalArgumentException e) { 1217 Log.w(TAG, "couldn't select track " + t); 1218 // continue on with codec initialization anyway, since that might still crash 1219 } 1220 for (String codecName: matchingCodecs) { 1221 Log.i(TAG, "Decoding track " + t + " using codec " + codecName); 1222 ex.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); 1223 MediaCodec codec = MediaCodec.createByCodecName(codecName); 1224 Surface surface = null; 1225 if (mime.startsWith("video/")) { 1226 surface = getDummySurface(); 1227 } 1228 try { 1229 codec.configure(format, surface, null, 0); 1230 codec.start(); 1231 } catch (Exception e) { 1232 Log.i(TAG, "Failed to start/configure:", e); 1233 } 1234 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); 1235 try { 1236 ByteBuffer [] inputBuffers = codec.getInputBuffers(); 1237 while (true) { 1238 int flags = ex.getSampleFlags(); 1239 long time = ex.getSampleTime(); 1240 ex.getCachedDuration(); 1241 int bufidx = codec.dequeueInputBuffer(5000); 1242 if (bufidx >= 0) { 1243 int n = ex.readSampleData(inputBuffers[bufidx], 0); 1244 if (n < 0) { 1245 flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM; 1246 time = 0; 1247 n = 0; 1248 } 1249 codec.queueInputBuffer(bufidx, 0, n, time, flags); 1250 ex.advance(); 1251 } 1252 int status = codec.dequeueOutputBuffer(info, 5000); 1253 if (status >= 0) { 1254 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 1255 break; 1256 } 1257 if (info.presentationTimeUs > TIMEOUT_NS / 1000) { 1258 Log.d(TAG, "stopping after 10 seconds worth of data"); 1259 break; 1260 } 1261 codec.releaseOutputBuffer(status, true); 1262 } 1263 } 1264 } catch (Exception e) { 1265 // local exceptions ignored, not security issues 1266 } finally { 1267 codec.release(); 1268 } 1269 } 1270 ex.unselectTrack(t); 1271 } 1272 ex.release(); 1273 String cve = rname.replace("_", "-").toUpperCase(); 1274 assertFalse("Device *IS* vulnerable to " + cve, 1275 mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED); 1276 thr.stopLooper(); 1277 thr.join(); 1278 } 1279 doStagefrightTestMediaMetadataRetriever(final int rid)1280 private void doStagefrightTestMediaMetadataRetriever(final int rid) throws Exception { 1281 doStagefrightTestMediaMetadataRetriever(rid, null); 1282 } 1283 doStagefrightTestMediaMetadataRetriever(final String url)1284 private void doStagefrightTestMediaMetadataRetriever(final String url) throws Exception { 1285 doStagefrightTestMediaMetadataRetriever(-1, url); 1286 } 1287 doStagefrightTestMediaMetadataRetriever( final int rid, final String url)1288 private void doStagefrightTestMediaMetadataRetriever( 1289 final int rid, final String url) throws Exception { 1290 1291 final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(); 1292 1293 LooperThread thr = new LooperThread(new Runnable() { 1294 @Override 1295 public void run() { 1296 1297 MediaPlayer mp = new MediaPlayer(); 1298 mp.setOnErrorListener(mpcl); 1299 AssetFileDescriptor fd = null; 1300 try { 1301 fd = getInstrumentation().getContext().getResources() 1302 .openRawResourceFd(R.raw.good); 1303 1304 // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until 1305 // setDataSource has been called 1306 mp.setDataSource(fd.getFileDescriptor(), 1307 fd.getStartOffset(), 1308 fd.getLength()); 1309 fd.close(); 1310 } catch (Exception e) { 1311 // this is a known-good file, so no failure should occur 1312 fail("setDataSource of known-good file failed"); 1313 } 1314 1315 synchronized(mpcl) { 1316 mpcl.notify(); 1317 } 1318 Looper.loop(); 1319 mp.release(); 1320 } 1321 }); 1322 thr.start(); 1323 // wait until the thread has initialized the MediaPlayer 1324 synchronized(mpcl) { 1325 mpcl.wait(); 1326 } 1327 1328 Resources resources = getInstrumentation().getContext().getResources(); 1329 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 1330 if (url == null) { 1331 AssetFileDescriptor fd = resources.openRawResourceFd(rid); 1332 try { 1333 retriever.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength()); 1334 } catch (Exception e) { 1335 // ignore 1336 } finally { 1337 closeQuietly(fd); 1338 } 1339 } else { 1340 try { 1341 retriever.setDataSource(url, new HashMap<String, String>()); 1342 } catch (Exception e) { 1343 // indicative of problems with our tame CTS test web server 1344 } 1345 } 1346 retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 1347 retriever.getEmbeddedPicture(); 1348 retriever.getFrameAtTime(); 1349 1350 retriever.release(); 1351 String rname = url != null ? url : resources.getResourceEntryName(rid); 1352 String cve = rname.replace("_", "-").toUpperCase(); 1353 assertFalse("Device *IS* vulnerable to " + cve, 1354 mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED); 1355 thr.stopLooper(); 1356 thr.join(); 1357 } 1358 testBug36215950()1359 public void testBug36215950() throws Exception { 1360 doStagefrightTestRawBlob(R.raw.bug_36215950, "video/hevc", 320, 240); 1361 } 1362 testBug36816007()1363 public void testBug36816007() throws Exception { 1364 doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240); 1365 } 1366 testBug36895511()1367 public void testBug36895511() throws Exception { 1368 doStagefrightTestRawBlob(R.raw.bug_36895511, "video/hevc", 320, 240); 1369 } 1370 testBug64836894()1371 public void testBug64836894() throws Exception { 1372 doStagefrightTestRawBlob(R.raw.bug_64836894, "video/avc", 320, 240); 1373 } 1374 1375 @SecurityTest testCve_2017_0687()1376 public void testCve_2017_0687() throws Exception { 1377 doStagefrightTestRawBlob(R.raw.cve_2017_0687, "video/avc", 320, 240); 1378 } 1379 1380 @SecurityTest testBug_37930177()1381 public void testBug_37930177() throws Exception { 1382 doStagefrightTestRawBlob(R.raw.bug_37930177_hevc, "video/hevc", 320, 240); 1383 } 1384 1385 @SecurityTest testBug_37712181()1386 public void testBug_37712181() throws Exception { 1387 doStagefrightTestRawBlob(R.raw.bug_37712181_hevc, "video/hevc", 320, 240); 1388 } 1389 1390 @SecurityTest testBug_70897394()1391 public void testBug_70897394() throws Exception { 1392 doStagefrightTestRawBlob(R.raw.bug_70897394_avc, "video/avc", 320, 240); 1393 } 1394 getFrameSizes(int rid)1395 private int[] getFrameSizes(int rid) throws IOException { 1396 final Context context = getInstrumentation().getContext(); 1397 final Resources resources = context.getResources(); 1398 AssetFileDescriptor fd = resources.openRawResourceFd(rid); 1399 FileInputStream fis = fd.createInputStream(); 1400 byte[] frameInfo = new byte[(int) fd.getLength()]; 1401 fis.read(frameInfo); 1402 fis.close(); 1403 String[] valueStr = new String(frameInfo).trim().split("\\s+"); 1404 int[] frameSizes = new int[valueStr.length]; 1405 for (int i = 0; i < valueStr.length; i++) 1406 frameSizes[i] = Integer.parseInt(valueStr[i]); 1407 return frameSizes; 1408 } 1409 runWithTimeout(Runnable runner, int timeout)1410 private void runWithTimeout(Runnable runner, int timeout) { 1411 Thread t = new Thread(runner); 1412 t.start(); 1413 try { 1414 t.join(timeout); 1415 } catch (InterruptedException e) { 1416 fail("operation was interrupted"); 1417 } 1418 if (t.isAlive()) { 1419 fail("operation not completed within timeout of " + timeout + "ms"); 1420 } 1421 } 1422 releaseCodec(final MediaCodec codec)1423 private void releaseCodec(final MediaCodec codec) { 1424 runWithTimeout(new Runnable() { 1425 @Override 1426 public void run() { 1427 codec.release(); 1428 } 1429 }, 5000); 1430 } 1431 doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight)1432 private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight) throws Exception { 1433 1434 final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(); 1435 final Context context = getInstrumentation().getContext(); 1436 final Resources resources = context.getResources(); 1437 1438 LooperThread thr = new LooperThread(new Runnable() { 1439 @Override 1440 public void run() { 1441 1442 MediaPlayer mp = new MediaPlayer(); 1443 mp.setOnErrorListener(mpcl); 1444 AssetFileDescriptor fd = null; 1445 try { 1446 fd = resources.openRawResourceFd(R.raw.good); 1447 1448 // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until 1449 // setDataSource has been called 1450 mp.setDataSource(fd.getFileDescriptor(), 1451 fd.getStartOffset(), 1452 fd.getLength()); 1453 fd.close(); 1454 } catch (Exception e) { 1455 // this is a known-good file, so no failure should occur 1456 fail("setDataSource of known-good file failed"); 1457 } 1458 1459 synchronized(mpcl) { 1460 mpcl.notify(); 1461 } 1462 Looper.loop(); 1463 mp.release(); 1464 } 1465 }); 1466 thr.start(); 1467 // wait until the thread has initialized the MediaPlayer 1468 synchronized(mpcl) { 1469 mpcl.wait(); 1470 } 1471 1472 AssetFileDescriptor fd = resources.openRawResourceFd(rid); 1473 byte [] blob = new byte[(int)fd.getLength()]; 1474 FileInputStream fis = fd.createInputStream(); 1475 int numRead = fis.read(blob); 1476 fis.close(); 1477 //Log.i("@@@@", "read " + numRead + " bytes"); 1478 1479 // find all the available decoders for this format 1480 ArrayList<String> matchingCodecs = new ArrayList<String>(); 1481 int numCodecs = MediaCodecList.getCodecCount(); 1482 for (int i = 0; i < numCodecs; i++) { 1483 MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); 1484 if (info.isEncoder()) { 1485 continue; 1486 } 1487 try { 1488 MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime); 1489 if (caps != null) { 1490 matchingCodecs.add(info.getName()); 1491 } 1492 } catch (IllegalArgumentException e) { 1493 // type is not supported 1494 } 1495 } 1496 1497 if (matchingCodecs.size() == 0) { 1498 Log.w(TAG, "no codecs for mime type " + mime); 1499 } 1500 String rname = resources.getResourceEntryName(rid); 1501 // decode this blob once with each matching codec 1502 for (String codecName: matchingCodecs) { 1503 Log.i(TAG, "Decoding blob " + rname + " using codec " + codecName); 1504 MediaCodec codec = MediaCodec.createByCodecName(codecName); 1505 MediaFormat format = MediaFormat.createVideoFormat(mime, initWidth, initHeight); 1506 codec.configure(format, null, null, 0); 1507 codec.start(); 1508 1509 try { 1510 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); 1511 ByteBuffer [] inputBuffers = codec.getInputBuffers(); 1512 // enqueue the bad data a number of times, in case 1513 // the codec needs multiple buffers to fail. 1514 for(int i = 0; i < 64; i++) { 1515 int bufidx = codec.dequeueInputBuffer(5000); 1516 if (bufidx >= 0) { 1517 Log.i(TAG, "got input buffer of size " + inputBuffers[bufidx].capacity()); 1518 inputBuffers[bufidx].rewind(); 1519 inputBuffers[bufidx].put(blob, 0, numRead); 1520 codec.queueInputBuffer(bufidx, 0, numRead, 0, 0); 1521 } else { 1522 Log.i(TAG, "no input buffer"); 1523 } 1524 bufidx = codec.dequeueOutputBuffer(info, 5000); 1525 if (bufidx >= 0) { 1526 Log.i(TAG, "got output buffer"); 1527 codec.releaseOutputBuffer(bufidx, false); 1528 } else { 1529 Log.i(TAG, "no output buffer"); 1530 } 1531 } 1532 } catch (Exception e) { 1533 // ignore, not a security issue 1534 } finally { 1535 releaseCodec(codec); 1536 } 1537 } 1538 1539 String cve = rname.replace("_", "-").toUpperCase(); 1540 assertFalse("Device *IS* vulnerable to " + cve, 1541 mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED); 1542 thr.stopLooper(); 1543 thr.join(); 1544 } 1545 doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight, int frameSizes[])1546 private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight, 1547 int frameSizes[]) throws Exception { 1548 1549 final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(); 1550 final Context context = getInstrumentation().getContext(); 1551 final Resources resources = context.getResources(); 1552 1553 LooperThread thr = new LooperThread(new Runnable() { 1554 @Override 1555 public void run() { 1556 1557 MediaPlayer mp = new MediaPlayer(); 1558 mp.setOnErrorListener(mpcl); 1559 AssetFileDescriptor fd = null; 1560 try { 1561 fd = resources.openRawResourceFd(R.raw.good); 1562 1563 // the onErrorListener won't receive MEDIA_ERROR_SERVER_DIED until 1564 // setDataSource has been called 1565 mp.setDataSource(fd.getFileDescriptor(), 1566 fd.getStartOffset(), 1567 fd.getLength()); 1568 fd.close(); 1569 } catch (Exception e) { 1570 // this is a known-good file, so no failure should occur 1571 fail("setDataSource of known-good file failed"); 1572 } 1573 1574 synchronized(mpcl) { 1575 mpcl.notify(); 1576 } 1577 Looper.loop(); 1578 mp.release(); 1579 } 1580 }); 1581 thr.start(); 1582 // wait until the thread has initialized the MediaPlayer 1583 synchronized(mpcl) { 1584 mpcl.wait(); 1585 } 1586 1587 AssetFileDescriptor fd = resources.openRawResourceFd(rid); 1588 byte [] blob = new byte[(int)fd.getLength()]; 1589 FileInputStream fis = fd.createInputStream(); 1590 int numRead = fis.read(blob); 1591 fis.close(); 1592 1593 // find all the available decoders for this format 1594 ArrayList<String> matchingCodecs = new ArrayList<String>(); 1595 int numCodecs = MediaCodecList.getCodecCount(); 1596 for (int i = 0; i < numCodecs; i++) { 1597 MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i); 1598 if (info.isEncoder()) { 1599 continue; 1600 } 1601 try { 1602 MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime); 1603 if (caps != null) { 1604 matchingCodecs.add(info.getName()); 1605 } 1606 } catch (IllegalArgumentException e) { 1607 // type is not supported 1608 } 1609 } 1610 1611 if (matchingCodecs.size() == 0) { 1612 Log.w(TAG, "no codecs for mime type " + mime); 1613 } 1614 String rname = resources.getResourceEntryName(rid); 1615 // decode this blob once with each matching codec 1616 for (String codecName: matchingCodecs) { 1617 Log.i(TAG, "Decoding blob " + rname + " using codec " + codecName); 1618 MediaCodec codec = MediaCodec.createByCodecName(codecName); 1619 MediaFormat format = MediaFormat.createVideoFormat(mime, initWidth, initHeight); 1620 try { 1621 codec.configure(format, null, null, 0); 1622 codec.start(); 1623 } catch (Exception e) { 1624 Log.i(TAG, "Exception from codec " + codecName); 1625 releaseCodec(codec); 1626 continue; 1627 } 1628 1629 try { 1630 MediaCodec.BufferInfo info = new MediaCodec.BufferInfo(); 1631 ByteBuffer [] inputBuffers = codec.getInputBuffers(); 1632 int numFrames = 0; 1633 if (frameSizes != null) { 1634 numFrames = frameSizes.length; 1635 } 1636 1637 if (0 == numFrames) { 1638 fail("Improper picture length file"); 1639 } 1640 1641 int offset = 0; 1642 int bytesToFeed = 0; 1643 int flags = 0; 1644 byte [] tempBlob = new byte[(int)inputBuffers[0].capacity()]; 1645 for (int j = 0; j < numFrames; j++) { 1646 int bufidx = codec.dequeueInputBuffer(5000); 1647 if (bufidx >= 0) { 1648 inputBuffers[bufidx].rewind(); 1649 bytesToFeed = Math.min((int)(fd.getLength() - offset), 1650 inputBuffers[bufidx].capacity()); 1651 if(j == (numFrames - 1)) { 1652 flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM; 1653 } 1654 System.arraycopy(blob, offset, tempBlob, 0, bytesToFeed); 1655 inputBuffers[bufidx].put(tempBlob, 0, inputBuffers[bufidx].capacity()); 1656 codec.queueInputBuffer(bufidx, 0, bytesToFeed, 0, flags); 1657 offset = offset + frameSizes[j]; 1658 } else { 1659 Log.i(TAG, "no input buffer"); 1660 } 1661 bufidx = codec.dequeueOutputBuffer(info, 5000); 1662 if (bufidx >= 0) { 1663 codec.releaseOutputBuffer(bufidx, false); 1664 } else { 1665 Log.i(TAG, "no output buffer"); 1666 } 1667 } 1668 } catch (Exception e) { 1669 // ignore, not a security issue 1670 } finally { 1671 releaseCodec(codec); 1672 } 1673 } 1674 1675 String cve = rname.replace("_", "-").toUpperCase(); 1676 assertFalse("Device *IS* vulnerable to " + cve, 1677 mpcl.waitForError() == MediaPlayer.MEDIA_ERROR_SERVER_DIED); 1678 thr.stopLooper(); 1679 thr.join(); 1680 } 1681 doStagefrightTestMediaPlayerANR(final int rid, final String uri)1682 private void doStagefrightTestMediaPlayerANR(final int rid, final String uri) throws Exception { 1683 String name = uri != null ? uri : 1684 getInstrumentation().getContext().getResources().getResourceEntryName(rid); 1685 Log.i(TAG, "start mediaplayerANR test for: " + name); 1686 1687 final MediaPlayerCrashListener mpl = new MediaPlayerCrashListener(); 1688 1689 LooperThread t = new LooperThread(new Runnable() { 1690 @Override 1691 public void run() { 1692 MediaPlayer mp = new MediaPlayer(); 1693 mp.setOnErrorListener(mpl); 1694 mp.setOnPreparedListener(mpl); 1695 mp.setOnCompletionListener(mpl); 1696 Surface surface = getDummySurface(); 1697 mp.setSurface(surface); 1698 AssetFileDescriptor fd = null; 1699 try { 1700 if (uri == null) { 1701 fd = getInstrumentation().getContext().getResources() 1702 .openRawResourceFd(rid); 1703 1704 mp.setDataSource(fd.getFileDescriptor(), 1705 fd.getStartOffset(), 1706 fd.getLength()); 1707 } else { 1708 mp.setDataSource(uri); 1709 } 1710 mp.prepareAsync(); 1711 } catch (Exception e) { 1712 } finally { 1713 closeQuietly(fd); 1714 } 1715 1716 Looper.loop(); 1717 mp.release(); 1718 } 1719 }); 1720 1721 t.start(); 1722 String cve = name.replace("_", "-").toUpperCase(); 1723 assertTrue("Device *IS* vulnerable to " + cve, mpl.waitForErrorOrCompletion()); 1724 t.stopLooper(); 1725 t.join(); // wait for thread to exit so we're sure the player was released 1726 } 1727 } 1728