From b2dfc27d3f9d6f5c334f61b72f2eec25ebd0b6c2 Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 1 Aug 2024 12:34:19 +0100 Subject: [PATCH] fix: make `chmod` hermetic Uses `uutils/coreutils` on most platforms, falls backto host `chmod` otherwise. Removes failure checking[1] as we now "trust" that things are OK. [1]: https://github.com/bazelbuild/rules_python/pull/2024#issuecomment-2234449232 --- python/private/python_repositories.bzl | 95 ++++++++++++++++++-------- 1 file changed, 67 insertions(+), 28 deletions(-) diff --git a/python/private/python_repositories.bzl b/python/private/python_repositories.bzl index ea3dd3533f..ff8e99fdc7 100644 --- a/python/private/python_repositories.bzl +++ b/python/private/python_repositories.bzl @@ -106,6 +106,63 @@ def is_standalone_interpreter(rctx, python_interpreter_path, *, logger = None): logger = logger, ).return_code == 0 +def _chmod(rctx, platform = None): + if platform == None: + platform = "{}-{}".format(rctx.os.arch, rctx.os.name) + map = { + "aarch64-macos": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-aarch64-apple-darwin.tar.gz", + integrity = "sha256-BjAeGgJ8+sLCIwmokCOkfelCCLtnNRH49QcFnrDq8a4=", + binary = "coreutils-0.0.27-coreutils-0.0.27-aarch64-apple-darwin/coreutils", + ), + "aarch64-linux": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-aarch64-unknown-linux-musl.tar.gz", + integrity = "sha256-doU+ZfTyA5I8RSwDAcsOkEI3BZXFuFwBfEbg+diS06g=", + binary = "coreutils-0.0.27-aarch64-unknown-linux-musl/coreutils", + ), + "arm-linux": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-arm-unknown-linux-gnueabihf.tar.gz", + integrity = "rmrDzyyfPUkAEqhXJegox53j4x/Cp/XfIiaWziHEQr4=", + binary = "coreutils-0.0.27-arm-unknown-linux-gnueabihf/coreutils", + ), + "i386-linux": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-i686-unknown-linux-musl.tar.gz", + integrity = "8LZQ/Pf5hHNTS0csAtB4dXGOI9HAlbkgv21Z8zJ5Lfc=", + binary = "coreutils-0.0.27-i686-unknown-linux-musl/coreutils", + ), + "amd64-macos": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-x86_64-apple-darwin.tar.gz", + integrity = "1ivz4ue8/ROUYhPh22Bg2ASPgC6MKMulR52nLgZvTBo=", + binary = "coreutils-0.0.27-x86_64-apple-darwin/coreutils", + ), + "amd64-windows": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-x86_64-pc-windows-msvc.zip", + integrity = "DC4H+hQX51aHoFudV39n7u217NDcNL9AiG4o4edboV0=", + binary = "coreutils-0.0.27-x86_64-pc-windows-msvc/coreutils.exe", + ), + "amd64-linux": struct( + url = "https://github.com/uutils/coreutils/releases/download/0.0.27/coreutils-0.0.27-x86_64-unknown-linux-musl.tar.gz", + integrity = "sha256-tM+hJd16cCjflJyMwsCaevPYZMiBkIKZJm7/XC+760w=", + binary = "coreutils-0.0.27-x86_64-unknown-linux-musl/coreutils", + ), + } + if platform not in map: + fail(platform) # TODO: remove this before merge + repo_utils.which_checked(rctx, "chmod") + data = map[platform] + output = rctx.path(".coreutils") + rctx.download_and_extract( + url = data.url, + integrity = data.integrity, + output = output, + ) + chmod = output.get_child("chmod") + binary = output.get_child(data.binary) + if not binary.exists: + fail("Invalid `coreutils` link: {}".format(binary)) + rctx.symlink(binary, chmod) + return chmod + def _python_repository_impl(rctx): if rctx.attr.distutils and rctx.attr.distutils_content: fail("Only one of (distutils, distutils_content) should be set.") @@ -196,36 +253,18 @@ def _python_repository_impl(rctx): # * The pycs are not deterministic (they contain timestamps) # * Multiple processes trying to write the same pycs can result in errors. if not rctx.attr.ignore_root_user_error: - if "windows" not in platform: - lib_dir = "lib" if "windows" not in platform else "Lib" + lib_dir = "lib" if "windows" not in platform else "Lib" - repo_utils.execute_checked( - rctx, - op = "python_repository.MakeReadOnly", - arguments = [repo_utils.which_checked(rctx, "chmod"), "-R", "ugo-w", lib_dir], - logger = logger, - ) - exec_result = repo_utils.execute_unchecked( - rctx, - op = "python_repository.TestReadOnly", - arguments = [repo_utils.which_checked(rctx, "touch"), "{}/.test".format(lib_dir)], - logger = logger, - ) + chmod = _chmod(rctx) + + repo_utils.execute_checked( + rctx, + op = "python_repository.MakeReadOnly", + arguments = [chmod, "-R", "ugo-w", lib_dir], + logger = logger, + ) - # The issue with running as root is the installation is no longer - # read-only, so the problems due to pyc can resurface. - if exec_result.return_code == 0: - stdout = repo_utils.execute_checked_stdout( - rctx, - op = "python_repository.GetUserId", - arguments = [repo_utils.which_checked(rctx, "id"), "-u"], - logger = logger, - ) - uid = int(stdout.strip()) - if uid == 0: - fail("The current user is root, please run as non-root when using the hermetic Python interpreter. See https://github.com/bazelbuild/rules_python/pull/713.") - else: - fail("The current user has CAP_DAC_OVERRIDE set, please drop this capability when using the hermetic Python interpreter. See https://github.com/bazelbuild/rules_python/pull/713.") + rctx.delete(chmod.dirname) python_bin = "python.exe" if ("windows" in platform) else "bin/python3"