Skip to content

Commit 5fb47fb

Browse files
committed
Refactor the inline Python commands into a Python binary.
This is needed when `python3` does not exist in the runtime environment.
1 parent 4bafba5 commit 5fb47fb

9 files changed

Lines changed: 70 additions & 13 deletions

File tree

fuzzing/engines/BUILD

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ cc_fuzzing_engine(
2323
name = "libfuzzer",
2424
display_name = "libFuzzer",
2525
launcher = "libfuzzer_launcher.sh",
26+
launcher_data = {
27+
"//fuzzing/tools:realpath": "REALPATH_PATH",
28+
},
2629
library = ":libfuzzer_stub",
2730
visibility = ["//visibility:public"],
2831
)
@@ -46,6 +49,7 @@ cc_fuzzing_engine(
4649
launcher = "honggfuzz_launcher.sh",
4750
launcher_data = {
4851
"@honggfuzz//:honggfuzz": "HONGGFUZZ_PATH",
52+
"//fuzzing/tools:realpath": "REALPATH_PATH",
4953
},
5054
library = "@honggfuzz//:honggfuzz_engine",
5155
visibility = ["//visibility:public"],
@@ -58,6 +62,9 @@ cc_fuzzing_engine(
5862
name = "replay",
5963
display_name = "Replay",
6064
launcher = "replay_launcher.sh",
65+
launcher_data = {
66+
"//fuzzing/tools:realpath": "REALPATH_PATH",
67+
},
6168
library = "//fuzzing/replay:replay_main",
6269
visibility = ["//visibility:public"],
6370
)
@@ -69,6 +76,9 @@ java_fuzzing_engine(
6976
name = "jazzer",
7077
display_name = "Jazzer",
7178
launcher = "jazzer_launcher.sh",
79+
launcher_data = {
80+
"//fuzzing/tools:realpath": "REALPATH_PATH",
81+
},
7282
library = "@jazzer//agent:jazzer_api_compile_only",
7383
visibility = ["//visibility:public"],
7484
)

fuzzing/engines/honggfuzz_launcher.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
command_line="$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' ${HONGGFUZZ_PATH})"
15+
command_line="$("${REALPATH_PATH}" ${HONGGFUZZ_PATH})"
1616
command_line+=("--workspace=${FUZZER_OUTPUT_ROOT}")
1717

1818
if [[ -n "${FUZZER_SEED_CORPUS_DIR}" ]]; then

fuzzing/engines/jazzer_launcher.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# engine. The launch configuration is supplied by the launcher script through
1717
# environment variables.
1818

19-
command_line=("$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' ${FUZZER_BINARY})")
19+
command_line=("$("${REALPATH_PATH}" ${FUZZER_BINARY})")
2020

2121
# libFuzzer flags (compatible with Jazzer).
2222

fuzzing/engines/libfuzzer_launcher.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# libFuzzer engine. The launch configuration is supplied by the launcher
1717
# script through environment variables.
1818

19-
command_line=("$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' ${FUZZER_BINARY})")
19+
command_line=("$("${REALPATH_PATH}" ${FUZZER_BINARY})")
2020

2121
# libFuzzer flags.
2222

fuzzing/engines/replay_launcher.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ if (( ! FUZZER_IS_REGRESSION )); then
1616
echo "NOTE: Non-regression mode is not supported by the replay engine."
1717
fi
1818

19-
command_line=("$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' ${FUZZER_BINARY})")
19+
command_line=("$("${REALPATH_PATH}" ${FUZZER_BINARY})")
2020
if [[ -n "${FUZZER_SEED_CORPUS_DIR}" ]]; then
2121
command_line+=("${FUZZER_SEED_CORPUS_DIR}")
2222
fi

fuzzing/private/engine.bzl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@ def _make_fuzzing_engine_info(ctx):
3737
if data_env_var:
3838
if data_env_var in env_vars:
3939
fail("Multiple data dependencies map to variable '%s'." % data_env_var)
40-
if len(data_files) != 1:
41-
fail("Data dependency for variable '%s' doesn't map to exactly one file." % data_env_var)
42-
env_vars[data_env_var] = data_files[0]
40+
if len(data_files) == 1:
41+
env_vars[data_env_var] = data_files[0]
42+
elif data_label.files_to_run.executable:
43+
env_vars[data_env_var] = data_label.files_to_run.executable
44+
else:
45+
fail("Data dependency for variable '%s' is not a single file or executable." % data_env_var)
4346
launcher_runfiles = launcher_runfiles.merge(ctx.runfiles(files = data_files))
4447
launcher_runfiles = launcher_runfiles.merge(data_label[DefaultInfo].default_runfiles)
4548

fuzzing/private/java_utils.bzl

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,18 @@ source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/
106106
107107
# Export the env variables required for subprocesses to find their runfiles.
108108
runfiles_export_envvars
109+
"""
109110

111+
script_format_part = """
110112
# Determine the path to load libjvm.so from, either relative to the location of
111113
# the java binary or to $JAVA_HOME, if set. On OSS-Fuzz, the path is provided in
112114
# JVM_LD_LIBRARY_PATH.
113-
JAVA_BIN=$(python3 -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(which java)")
114-
JAVA_HOME=${JAVA_HOME:-${JAVA_BIN%/bin/java}}
115+
JAVA_BIN=$("$(rlocation {realpath})" "$(which java)")
116+
JAVA_HOME=${{JAVA_HOME:-${{JAVA_BIN%/bin/java}}}}
115117
# The location of libjvm.so relative to the JDK differs between JDK <= 8 and 9+.
116-
JVM_LD_LIBRARY_PATH=${JVM_LD_LIBRARY_PATH:-"$JAVA_HOME/lib/server:$JAVA_HOME/lib/amd64/server"}
117-
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$JVM_LD_LIBRARY_PATH
118-
"""
118+
JVM_LD_LIBRARY_PATH=${{JVM_LD_LIBRARY_PATH:-"$JAVA_HOME/lib/server:$JAVA_HOME/lib/amd64/server"}}
119+
export LD_LIBRARY_PATH=${{LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}}$JVM_LD_LIBRARY_PATH
119120
120-
script_format_part = """
121121
source "$(rlocation {sanitizer_options})"
122122
exec "$(rlocation {driver})" \
123123
--agent_path="$(rlocation {agent})" \
@@ -136,6 +136,7 @@ exec "$(rlocation {driver})" \
136136
deploy_jar = runfile_path(ctx, ctx.file.target_deploy_jar),
137137
driver = runfile_path(ctx, driver),
138138
native_dirs = ":".join(native_dirs),
139+
realpath = runfile_path(ctx, ctx.executable._realpath),
139140
sanitizer_options = runfile_path(ctx, ctx.file.sanitizer_options),
140141
)
141142
ctx.actions.write(script, script_content, is_executable = True)
@@ -232,6 +233,9 @@ def _jazzer_fuzz_binary_impl(ctx):
232233

233234
runfiles = runfiles.merge(ctx.runfiles([ctx.file.sanitizer_options]))
234235

236+
runfiles = runfiles.merge(ctx.runfiles([ctx.executable._realpath]))
237+
runfiles = runfiles.merge(ctx.attr._realpath[DefaultInfo].default_runfiles)
238+
235239
script = _jazzer_fuzz_binary_script(ctx, native_libs, driver)
236240
return [DefaultInfo(executable = script, runfiles = runfiles)]
237241

@@ -283,6 +287,12 @@ Rule that creates a binary that invokes Jazzer on the specified target.
283287
allow_single_file = [".jar"],
284288
mandatory = True,
285289
),
290+
"_realpath": attr.label(
291+
doc = "The realpath util needed by the binary script.",
292+
default = "//fuzzing/tools:realpath",
293+
executable = True,
294+
cfg = "target",
295+
),
286296
"_allowlist_function_transition": attr.label(
287297
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
288298
),

fuzzing/tools/BUILD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ py_binary(
3636
deps = [requirement("absl-py")],
3737
)
3838

39+
py_binary(
40+
name = "realpath",
41+
srcs = ["realpath.py"],
42+
python_version = "PY3",
43+
visibility = ["//visibility:public"],
44+
)
45+
3946
py_binary(
4047
name = "validate_dict",
4148
srcs = ["validate_dict.py"],

fuzzing/tools/realpath.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Lint as: python3
16+
"""
17+
Gets the realpath of a input path.
18+
19+
This is a portable replacement of `readlink -f`/`realpath`.
20+
"""
21+
22+
import os, sys
23+
24+
if len(sys.argv) < 2:
25+
print("Need an argument for the input path.", file=sys.stderr)
26+
sys.exit(1)
27+
print(os.path.realpath(sys.argv[1]))

0 commit comments

Comments
 (0)