예제 #1
0
def get_runner(fuzzer_path, temp_dir=None):
    """Get a libfuzzer runner."""
    use_minijail = environment.get_value('USE_MINIJAIL')
    build_dir = environment.get_value('BUILD_DIR')
    dataflow_build_dir = environment.get_value('DATAFLOW_BUILD_DIR')
    if use_minijail:
        # Set up chroot and runner.
        if environment.is_chromeos_system_job():
            minijail_chroot = minijail.ChromeOSChroot(build_dir)
        else:
            minijail_chroot = minijail.MinijailChroot(base_dir=temp_dir)

        # While it's possible for dynamic binaries to run without this, they need
        # to be accessible for symbolization etc. For simplicity we bind BUILD_DIR
        # to the same location within the chroot, which leaks the directory
        # structure of CF but this shouldn't be a big deal.
        minijail_chroot.add_binding(
            minijail.ChrootBinding(build_dir, build_dir, False))

        if dataflow_build_dir:
            minijail_chroot.add_binding(
                minijail.ChrootBinding(dataflow_build_dir, dataflow_build_dir,
                                       False))

        # Also bind the build dir to /out to make it easier to hardcode references
        # to data files.
        minijail_chroot.add_binding(
            minijail.ChrootBinding(build_dir, '/out', False))

        minijail_bin = os.path.join(minijail_chroot.directory, 'bin')
        shell.create_directory(minijail_bin)

        # Set up /bin with llvm-symbolizer to allow symbolized stacktraces.
        # Don't copy if it already exists (e.g. ChromeOS chroot jail).
        llvm_symbolizer_source_path = environment.get_llvm_symbolizer_path()
        llvm_symbolizer_destination_path = os.path.join(
            minijail_bin, 'llvm-symbolizer')
        if not os.path.exists(llvm_symbolizer_destination_path):
            shutil.copy(llvm_symbolizer_source_path,
                        llvm_symbolizer_destination_path)

        # copy /bin/sh, necessary for system().
        if not environment.is_chromeos_system_job():
            # The chroot has its own shell we don't need to copy (and probably
            # shouldn't because of library differences).
            shutil.copy(os.path.realpath('/bin/sh'),
                        os.path.join(minijail_bin, 'sh'))

        runner = MinijailLibFuzzerRunner(fuzzer_path, minijail_chroot)
    elif environment.platform() == 'FUCHSIA':
        runner = FuchsiaQemuLibFuzzerRunner(fuzzer_path)
    else:
        runner = LibFuzzerRunner(fuzzer_path)

    return runner
예제 #2
0
 def test_minijail(self):
   """Test minijail process command."""
   with minijail.MinijailChroot() as chroot:
     runner = minijail.MinijailProcessRunner(chroot, '/bin/ls')
     self.assertListEqual(runner.get_command(), [
         '/sbin/minijail', '-U', '-m', '0 1000 1', '-T', 'static', '-c', '0',
         '-n', '-v', '-p', '-l', '-I', '-k', 'proc,/proc,proc,1', '-P',
         chroot.directory, '-b',
         '%s,/tmp,1' % chroot.tmp_directory, '-b', '/lib,/lib,0', '-b',
         '/lib64,/lib64,0', '-b', '/usr/lib,/usr/lib,0', '/bin/ls'
     ])
예제 #3
0
    def test_chroot_bindings(self):
        """Tests chroot setup with additional bind dirs."""
        chroot_directory = None
        with minijail.MinijailChroot(bindings=[
                minijail.ChrootBinding('/foo/bar', '/bar', False),
        ]) as chroot:
            chroot_directory = chroot.directory
            self.assertListEqual(
                sorted(os.listdir(chroot_directory)),
                ['bar', 'dev', 'lib', 'lib32', 'lib64', 'proc', 'tmp', 'usr'])

        self.assertEqual(chroot.get_binding('/foo/bar'),
                         minijail.ChrootBinding('/foo/bar', '/bar', False))
        self.assertFalse(os.path.exists(chroot_directory))
예제 #4
0
  def test_minijail_pid(self, mock_tempfile, _):
    """Test minijail process command writing to pid file."""
    mock_tempfile.return_value.name = '/temp_pid'

    with minijail.MinijailChroot() as chroot:
      runner = minijail.MinijailProcessRunner(chroot, 'bin/ls')
      process = runner.run()
      self.assertListEqual(process.command, [
          '/sbin/minijail', '-f', '/temp_pid', '-U', '-m', '0 1000 1', '-T',
          'static', '-c', '0', '-n', '-v', '-p', '-l', '-I', '-k',
          'proc,/proc,proc,1', '-P', chroot.directory, '-b',
          '%s,/tmp,1' % chroot.tmp_directory, '-b', '/lib,/lib,0', '-b',
          '/lib64,/lib64,0', '-b', '/usr/lib,/usr/lib,0', 'bin/ls'
      ])
예제 #5
0
 def test_minijail_bindings(self):
   """Test minijail process command with additional bind dirs."""
   with minijail.MinijailChroot(bindings=[
       minijail.ChrootBinding('/foo/bar', '/bar', True),
       minijail.ChrootBinding('/foo/barr', '/barr', False),
   ]) as chroot:
     runner = minijail.MinijailProcessRunner(chroot, '/bin/ls')
     self.assertListEqual(runner.get_command(), [
         '/sbin/minijail', '-U', '-m', '0 1000 1', '-T', 'static', '-c', '0',
         '-n', '-v', '-p', '-l', '-I', '-k', 'proc,/proc,proc,1', '-P',
         chroot.directory, '-b',
         '%s,/tmp,1' % chroot.tmp_directory, '-b', '/lib,/lib,0', '-b',
         '/lib64,/lib64,0', '-b', '/usr/lib,/usr/lib,0', '-b',
         '/foo/bar,/bar,1', '-b', '/foo/barr,/barr,0', '/bin/ls'
     ])
예제 #6
0
  def test_minijail_env_vars(self, mock_popen):
    """Test passing of env vars."""
    os.environ['ASAN_OPTIONS'] = 'asan_option=1'
    os.environ['AFL_OPTION'] = 'afl_option=1'
    os.environ['MSAN_OPTIONS'] = 'msan_option=1'
    os.environ['UBSAN_OPTIONS'] = 'ubsan_option=1'
    os.environ['SECRET'] = 'secret'
    os.environ['OTHER'] = 'other'

    with minijail.MinijailChroot() as chroot:
      runner = minijail.MinijailProcessRunner(chroot, 'binary')
      runner.run(env={'MSAN_OPTIONS': 'override=1', 'NAME': 'VALUE'})

      self.assertDictEqual({
          'MSAN_OPTIONS': 'override=1',
          'PATH': '/bin:/usr/bin',
      }, mock_popen.call_args[1]['env'])
예제 #7
0
    def test_chroot(self):
        """Tests basic chroot setup."""
        chroot_directory = None
        with minijail.MinijailChroot() as chroot:
            chroot_directory = chroot.directory
            self.assertListEqual(
                sorted(os.listdir(chroot_directory)),
                ['dev', 'lib', 'lib32', 'lib64', 'proc', 'tmp', 'usr'])

            self.assertEqual(
                chroot.get_binding(chroot.tmp_directory),
                minijail.ChrootBinding(chroot.tmp_directory, '/tmp', True))

            for directory in ['/lib', '/lib32', '/lib64', '/usr/lib']:
                self.assertEqual(
                    chroot.get_binding(directory),
                    minijail.ChrootBinding(directory, directory, False))

            self.assertIsNone(chroot.get_binding('/usr'))

        self.assertFalse(os.path.exists(chroot_directory))