Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/clusterfuzz/_internal/bot/fuzzers/libfuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,16 @@ class LibFuzzerRunner(new_process.ModifierProcessRunnerMixin,
new_process.UnicodeProcessRunner, LibFuzzerCommon):
"""libFuzzer runner (when minijail is not used)."""

def __init__(self, executable_path, default_args=None):
def __init__(self, executable_path, default_args=None, cwd=None):
"""Inits the LibFuzzerRunner.

Args:
executable_path: Path to the fuzzer executable.
default_args: Default arguments to always pass to the fuzzer.
cwd: Optional current working directory for the process.
"""
super().__init__(executable_path=executable_path, default_args=default_args)
super().__init__(
executable_path=executable_path, default_args=default_args, cwd=cwd)

def fuzz(self,
corpus_directories,
Expand Down Expand Up @@ -1133,6 +1135,10 @@ def get_runner(fuzzer_path, temp_dir=None, use_minijail=None):
temp_dir = fuzzer_utils.get_temp_dir()

build_dir = environment.get_value('BUILD_DIR')

cwd = build_dir if environment.get_value(
'FUZZ_TARGET_CWD_IS_BUILD_DIR') else None
Comment thread
notvictorl marked this conversation as resolved.

is_android = environment.is_android()
is_fuchsia = environment.platform() == 'FUCHSIA'

Expand All @@ -1141,6 +1147,7 @@ def get_runner(fuzzer_path, temp_dir=None, use_minijail=None):
os.chmod(fuzzer_path, 0o755)

is_chromeos_system_job = environment.is_chromeos_system_job()

if is_chromeos_system_job:
minijail_chroot = minijail.ChromeOSChroot(build_dir)
elif use_minijail:
Expand Down Expand Up @@ -1185,7 +1192,11 @@ def get_runner(fuzzer_path, temp_dir=None, use_minijail=None):
elif is_android:
runner = AndroidLibFuzzerRunner(fuzzer_path, build_dir)
else:
runner = LibFuzzerRunner(fuzzer_path)
runner = LibFuzzerRunner(fuzzer_path, cwd=cwd)

if cwd and not isinstance(runner, LibFuzzerRunner):
logs.warning('FUZZ_TARGET_CWD_IS_BUILD_DIR is only supported for standard '
'LibFuzzerRunner and will be ignored.')

return runner

Expand Down
12 changes: 11 additions & 1 deletion src/clusterfuzz/_internal/system/new_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,14 @@ class ProcessRunner:
executable_path: Path to the executable to be run.
default_args: An optional sequence of arguments that are always passed to
the executable when run.
cwd: Optional current working directory for the process.
"""

def __init__(self, executable_path, default_args=None):
def __init__(self, executable_path, default_args=None, cwd=None):
"""Inits ProcessRunner."""
self._executable_path = executable_path
self._default_args = []
self.cwd = cwd

if default_args:
self.default_args.extend(default_args)
Expand Down Expand Up @@ -332,6 +334,14 @@ def run(self,
if extra_env is not None:
env.update(extra_env)

if self.cwd:
if 'cwd' in popen_args:
logs.warning(f'Detected two cwd arguments for popen ({self.cwd} and '
f'{popen_args["cwd"]}). Using {popen_args["cwd"]}')
else:
logs.info(f'Executing process with custom cwd: {self.cwd}')
popen_args['cwd'] = self.cwd

return ChildProcess(
subprocess.Popen(
command,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
import os
import shutil
import unittest
from unittest import mock

from clusterfuzz._internal.bot.fuzzers import engine_common
from clusterfuzz._internal.bot.fuzzers import libfuzzer
from clusterfuzz._internal.bot.fuzzers import strategy_selection
from clusterfuzz._internal.bot.fuzzers.libFuzzer import fuzzer
from clusterfuzz._internal.fuzzing import strategy
from clusterfuzz._internal.system import environment
from clusterfuzz._internal.tests.test_libs import helpers as test_helpers

TESTDATA_PATH = os.path.join(os.path.dirname(__file__), 'libfuzzer_test_data')
Expand Down Expand Up @@ -177,5 +179,35 @@ def do_strategy(self, *args, **kwargs):
libfuzzer.should_set_fork_flag(existing_arguments, MockPool()))


class GetRunnerTest(unittest.TestCase):
"""Tests for get_runner."""

def setUp(self):
test_helpers.patch_environ(self)

@mock.patch('os.chmod')
def test_cwd_is_build_dir(self, _):
"""Test that FUZZ_TARGET_CWD_IS_BUILD_DIR causes cwd to be set to BUILD_DIR"""
environment.set_value('BUILD_DIR', '/build/dir')
environment.set_value('FUZZ_TARGET_CWD_IS_BUILD_DIR', True)
environment.set_value('USE_MINIJAIL', False)

runner = libfuzzer.get_runner('/fake/path')
Comment thread
dylanjew marked this conversation as resolved.

self.assertIsInstance(runner, libfuzzer.LibFuzzerRunner)
self.assertEqual(runner.cwd, '/build/dir')

@mock.patch('os.chmod')
def test_no_default_cwd(self, _):
"""Test that cwd is None when FUZZ_TARGET_CWD_IS_BUILD_DIR is not set."""
environment.set_value('BUILD_DIR', '/build/dir')
environment.set_value('USE_MINIJAIL', False)

runner = libfuzzer.get_runner('fake/path')

self.assertIsInstance(runner, libfuzzer.LibFuzzerRunner)
self.assertIsNone(runner.cwd)


if __name__ == '__main__':
unittest.main()
16 changes: 16 additions & 0 deletions src/clusterfuzz/_internal/tests/core/system/new_process_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@ def test_results_timeout(self):
self.assertLess(abs(results.time_executed - 0.5), self.TIME_ERROR)
self.assertTrue(results.timed_out)

def test_cwd(self):
"""Test that cwd is passed to Popen."""
with mock.patch('subprocess.Popen') as mock_popen:
runner = new_process.ProcessRunner(
'/test/path', default_args=['-arg1'], cwd='/working/dir')

runner.run()
Comment thread
notvictorl marked this conversation as resolved.

mock_popen.assert_called_with(
['/test/path', '-arg1'],
env=mock.ANY,
stdin=mock.ANY,
stdout=mock.ANY,
stderr=mock.ANY,
cwd='/working/dir')

def test_timeout(self):
"""Tests timeout signals."""
with mock.patch('subprocess.Popen', mock_popen_factory(1.0, '',
Expand Down
Loading