From 1395b2790402f76a7182bd96aca1f66440f448b3 Mon Sep 17 00:00:00 2001 From: Nicolas Dumazet Date: Sat, 29 Aug 2026 14:10:12 +0200 Subject: [PATCH 1/3] fix(protoc_authenticity): avoid depending on coreutils grep/cat in shell action ProtocAuthenticityCheck's run_shell action runs unqualified with no declared env/PATH, so it inherits an empty action environment. On systems without an FHS-style /bin:/usr/bin (e.g. NixOS), bash's compiled-in fallback PATH doesn't resolve 'grep' or 'cat', and the action fails with 'command not found' even though bash itself was found via an explicit toolchain path. Replace grep/cat with a single 'read' plus bash's [[ ]] pattern matching and 'echo', so the version check only depends on bash builtins. --- .../oss/toolchains/prebuilt/protoc_authenticity.bzl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl index f05eb9c5af1d2..2cfa66c9e0f0d 100644 --- a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl +++ b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl @@ -22,19 +22,19 @@ def _protoc_authenticity_impl(ctx): toolchain = toolchains.PROTO_TOOLCHAIN, command = """\ {protoc} --version > {validation_output} - grep -q -e "-dev$" {validation_output} && {{ + IFS= read -r version_line < {validation_output} + [[ $version_line == *-dev ]] && {{ echo 'WARNING: Detected a development version of protoc. Development versions are not validated for authenticity. To ensure a secure build, please use a released version of protoc.' exit 0 }} - grep -q "^libprotoc {RELEASE_VERSION}" {validation_output} || {{ + [[ $version_line == "libprotoc {RELEASE_VERSION}"* ]] || {{ echo '{severity}: protoc version does not match protobuf Bazel module; we do not support this. It is considered undefined behavior that is expected to break in the future even if it appears to work today.' echo '{suppression_note}' echo 'Expected: libprotoc {RELEASE_VERSION}' - echo -n 'Actual: ' - cat {validation_output} + echo "Actual: $version_line" exit {mismatch_exit_code} }} >&2 """.format( From ec2c07b3f8bec8b2f1a0942d228e9ce65988ec08 Mon Sep 17 00:00:00 2001 From: Nicolas Dumazet Date: Sat, 29 Aug 2026 14:55:33 +0200 Subject: [PATCH 2/3] fix(bootstrap_compiler): avoid depending on coreutils dirname in bootstrap protoc invocation _extra_proto_path builds a -I flag via $$(dirname $(location ...)), run inside a genrule shell action with no declared env/PATH. On systems without an FHS-style /bin:/usr/bin (e.g. NixOS), this fails with 'dirname: command not found'. Replace it with bash parameter expansion (${var%/*}) over a variable assigned earlier in the same command, so the path directory-name computation depends only on bash builtins. --- upb_generator/bootstrap_compiler.bzl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/upb_generator/bootstrap_compiler.bzl b/upb_generator/bootstrap_compiler.bzl index 93dee5b53541b..8ca48a16c9ce3 100644 --- a/upb_generator/bootstrap_compiler.bzl +++ b/upb_generator/bootstrap_compiler.bzl @@ -27,7 +27,10 @@ def _c_library_with_default_copts(**kwargs): _stages = ["_stage0", "_stage1", ""] _protoc = "//src/google/protobuf/compiler/release:protoc_minimal" -_extra_proto_path = "-I$$(dirname $(location //:descriptor_proto_srcs))/../.. " +# Uses bash parameter expansion (${var%/*}) instead of the external `dirname` +# binary, which may not be resolvable in a sandboxed action with no PATH. +_extra_proto_path_setup = "descriptor_proto_dir=$(location //:descriptor_proto_srcs); " +_extra_proto_path = "-I$${descriptor_proto_dir%/*}/../.. " # This visibility is used automatically for anything used by the bootstrapping process. _bootstrap_visibility = [ @@ -121,6 +124,7 @@ def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix, third outs = ["bootstrap_generated_sources/" + f.replace("third_party", third_party_dir) for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")], tools = [_protoc, _upbc("upb", 0)], cmd = + _extra_proto_path_setup + "$(location " + _protoc + ") " + "-I. -I$(GENDIR)/" + strip_prefix + " " + _extra_proto_path + "--plugin=protoc-gen-upb=$(location " + _upbc("upb", 0) + ") " + @@ -150,7 +154,8 @@ def _generate_stage1_proto(name, src_files, src_rules, generator, kwargs): name = "gen_{}_{}_stage1".format(name, generator), srcs = src_rules, outs = _generated_hdrs_and_srcs(src_files, "stage1", generator), - cmd = "$(location " + _protoc + ") " + + cmd = _extra_proto_path_setup + + "$(location " + _protoc + ") " + "--plugin=protoc-gen-" + generator + "=$(location " + _upbc(generator, 0) + ") " + _extra_proto_path + "--" + generator + "_out=bootstrap_stage=1:$(RULEDIR)/stage1 " + From a7beb0a93fa5eac7ea9a5ee8dca029849c2f6c87 Mon Sep 17 00:00:00 2001 From: Nicolas Dumazet Date: Sat, 29 Aug 2026 15:56:33 +0200 Subject: [PATCH 3/3] Fix formatting of echo statement for actual version --- bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl index 2cfa66c9e0f0d..5ff3b3f02cc7b 100644 --- a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl +++ b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl @@ -34,7 +34,7 @@ def _protoc_authenticity_impl(ctx): It is considered undefined behavior that is expected to break in the future even if it appears to work today.' echo '{suppression_note}' echo 'Expected: libprotoc {RELEASE_VERSION}' - echo "Actual: $version_line" + echo "Actual: $version_line" exit {mismatch_exit_code} }} >&2 """.format(