OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Base class for linker-specific test cases. | 5 """Base class for linker-specific test cases. |
6 | 6 |
7 The custom dynamic linker can only be tested through a custom test case | 7 The custom dynamic linker can only be tested through a custom test case |
8 for various technical reasons: | 8 for various technical reasons: |
9 | 9 |
10 - It's an 'invisible feature', i.e. it doesn't expose a new API or | 10 - It's an 'invisible feature', i.e. it doesn't expose a new API or |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 from pylib import android_commands | 45 from pylib import android_commands |
46 from pylib import flag_changer | 46 from pylib import flag_changer |
47 from pylib.base import base_test_result | 47 from pylib.base import base_test_result |
48 | 48 |
49 ResultType = base_test_result.ResultType | 49 ResultType = base_test_result.ResultType |
50 | 50 |
51 _PACKAGE_NAME='org.chromium.content_linker_test_apk' | 51 _PACKAGE_NAME='org.chromium.content_linker_test_apk' |
52 _ACTIVITY_NAME='.ContentLinkerTestActivity' | 52 _ACTIVITY_NAME='.ContentLinkerTestActivity' |
53 _COMMAND_LINE_FILE='/data/local/tmp/content-linker-test-command-line' | 53 _COMMAND_LINE_FILE='/data/local/tmp/content-linker-test-command-line' |
54 | 54 |
| 55 # Set this to False if the implemetation doesn't always place Shared RELROs |
| 56 # in the browser process. |
| 57 _BROWSER_USES_SHARED_RELRO = True |
| 58 |
55 # Logcat filters used during each test. Only the 'chromium' one is really | 59 # Logcat filters used during each test. Only the 'chromium' one is really |
56 # needed, but the logs are added to the TestResult in case of error, and | 60 # needed, but the logs are added to the TestResult in case of error, and |
57 # it is handy to have the 'content_android_linker' ones as well when | 61 # it is handy to have the 'content_android_linker' ones as well when |
58 # troubleshooting. | 62 # troubleshooting. |
59 _LOGCAT_FILTERS = [ '*:s', 'chromium:v', 'content_android_linker:v' ] | 63 _LOGCAT_FILTERS = [ '*:s', 'chromium:v', 'content_android_linker:v' ] |
60 #_LOGCAT_FILTERS = [ '*:v' ] ## DEBUG | 64 #_LOGCAT_FILTERS = [ '*:v' ] ## DEBUG |
61 | 65 |
62 # Regular expression used to match status lines in logcat. | 66 # Regular expression used to match status lines in logcat. |
63 re_status_line = re.compile(r'(BROWSER|RENDERER)_LINKER_TEST: (FAIL|SUCCESS)') | 67 re_status_line = re.compile(r'(BROWSER|RENDERER)_LINKER_TEST: (FAIL|SUCCESS)') |
64 | 68 |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 memory_boundary = 0x40000000 | 398 memory_boundary = 0x40000000 |
395 bad_libs = [] | 399 bad_libs = [] |
396 for lib_name, lib_address in renderer_libs.iteritems(): | 400 for lib_name, lib_address in renderer_libs.iteritems(): |
397 if lib_address >= memory_boundary: | 401 if lib_address >= memory_boundary: |
398 bad_libs.append((lib_name, lib_address)) | 402 bad_libs.append((lib_name, lib_address)) |
399 | 403 |
400 if bad_libs: | 404 if bad_libs: |
401 logging.error('Renderer libraries loaded at high addresses: %s', bad_libs) | 405 logging.error('Renderer libraries loaded at high addresses: %s', bad_libs) |
402 return ResultType.FAIL, logs | 406 return ResultType.FAIL, logs |
403 | 407 |
404 if self.is_low_memory: | 408 if _BROWSER_USES_SHARED_RELRO or self.is_low_memory: |
405 # For low-memory devices, the libraries must all be loaded at the same | 409 # The libraries must all be loaded at the same addresses. This also |
406 # addresses. This also implicitly checks that the browser libraries are at | 410 # implicitly checks that the browser libraries are at low addresses. |
407 # low addresses. | |
408 addr_mismatches = [] | 411 addr_mismatches = [] |
409 for lib_name, lib_address in browser_libs.iteritems(): | 412 for lib_name, lib_address in browser_libs.iteritems(): |
410 lib_address2 = renderer_libs[lib_name] | 413 lib_address2 = renderer_libs[lib_name] |
411 if lib_address != lib_address2: | 414 if lib_address != lib_address2: |
412 addr_mismatches.append((lib_name, lib_address, lib_address2)) | 415 addr_mismatches.append((lib_name, lib_address, lib_address2)) |
413 | 416 |
414 if addr_mismatches: | 417 if addr_mismatches: |
415 logging.error('Library load address mismatches: %s', | 418 logging.error('Library load address mismatches: %s', |
416 addr_mismatches) | 419 addr_mismatches) |
417 return ResultType.FAIL, logs | 420 return ResultType.FAIL, logs |
418 | 421 |
419 # For regular devices, check that libraries are loaded at 'high-addresses'. | 422 # Otherwise, check that libraries are loaded at 'high-addresses'. |
420 # Note that for low-memory devices, the previous checks ensure that they | 423 # Note that for low-memory devices, the previous checks ensure that they |
421 # were loaded at low-addresses. | 424 # were loaded at low-addresses. |
422 if not self.is_low_memory: | 425 else: |
423 bad_libs = [] | 426 bad_libs = [] |
424 for lib_name, lib_address in browser_libs.iteritems(): | 427 for lib_name, lib_address in browser_libs.iteritems(): |
425 if lib_address < memory_boundary: | 428 if lib_address < memory_boundary: |
426 bad_libs.append((lib_name, lib_address)) | 429 bad_libs.append((lib_name, lib_address)) |
427 | 430 |
428 if bad_libs: | 431 if bad_libs: |
429 logging.error('Browser libraries loaded at low addresses: %s', bad_libs) | 432 logging.error('Browser libraries loaded at low addresses: %s', bad_libs) |
430 return ResultType.FAIL, logs | 433 return ResultType.FAIL, logs |
431 | 434 |
432 # Everything's ok. | 435 # Everything's ok. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 # Check randomization in the browser libraries. | 470 # Check randomization in the browser libraries. |
468 logs = '\n'.join(logs_list) | 471 logs = '\n'.join(logs_list) |
469 | 472 |
470 browser_status, browser_logs = _CheckLoadAddressRandomization( | 473 browser_status, browser_logs = _CheckLoadAddressRandomization( |
471 browser_lib_map_list, 'Browser') | 474 browser_lib_map_list, 'Browser') |
472 | 475 |
473 renderer_status, renderer_logs = _CheckLoadAddressRandomization( | 476 renderer_status, renderer_logs = _CheckLoadAddressRandomization( |
474 renderer_lib_map_list, 'Renderer') | 477 renderer_lib_map_list, 'Renderer') |
475 | 478 |
476 if not browser_status: | 479 if not browser_status: |
477 if self.is_low_memory: | 480 if _BROWSER_USES_SHARED_RELRO or self.is_low_memory: |
478 return ResultType.FAIL, browser_logs | 481 return ResultType.FAIL, browser_logs |
479 | 482 |
480 # IMPORTANT NOTE: The system's ASLR implementation seems to be very poor | 483 # IMPORTANT NOTE: The system's ASLR implementation seems to be very poor |
481 # when starting an activity process in a loop with "adb shell am start". | 484 # when starting an activity process in a loop with "adb shell am start". |
482 # | 485 # |
483 # When simulating a regular device, loading libraries in the browser | 486 # When simulating a regular device, loading libraries in the browser |
484 # process uses a simple mmap(NULL, ...) to let the kernel device where to | 487 # process uses a simple mmap(NULL, ...) to let the kernel device where to |
485 # load the file (this is similar to what System.loadLibrary() does). | 488 # load the file (this is similar to what System.loadLibrary() does). |
486 # | 489 # |
487 # Unfortunately, at least in the context of this test, doing so while | 490 # Unfortunately, at least in the context of this test, doing so while |
488 # restarting the activity with the activity manager very, very, often | 491 # restarting the activity with the activity manager very, very, often |
489 # results in the system using the same load address for all 5 runs, or | 492 # results in the system using the same load address for all 5 runs, or |
490 # sometimes only 4 out of 5. | 493 # sometimes only 4 out of 5. |
491 # | 494 # |
492 # This has been tested experimentally on both Android 4.1.2 and 4.3. | 495 # This has been tested experimentally on both Android 4.1.2 and 4.3. |
493 # | 496 # |
494 # Note that this behaviour doesn't seem to happen when starting an | 497 # Note that this behaviour doesn't seem to happen when starting an |
495 # application 'normally', i.e. when using the application launcher to | 498 # application 'normally', i.e. when using the application launcher to |
496 # start the activity. | 499 # start the activity. |
497 logging.info('Ignoring system\'s low randomization of browser libraries' + | 500 logging.info('Ignoring system\'s low randomization of browser libraries' + |
498 ' for regular devices') | 501 ' for regular devices') |
499 | 502 |
500 if not renderer_status: | 503 if not renderer_status: |
501 return ResultType.FAIL, renderer_logs | 504 return ResultType.FAIL, renderer_logs |
502 | 505 |
503 return ResultType.PASS, logs | 506 return ResultType.PASS, logs |
OLD | NEW |