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