From 59db1a21a211b2415350e46b13e11a26c885e1cc Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Thu, 15 Oct 2026 16:23:35 +0000 Subject: [PATCH] tine: build with umask 022 images.md promises 0755 for directories, but Buck creates the directories in its outputs with its own umask. A builder with umask 0002 (Debian/Ubuntu default) produced group-writable directories in every image, which sshd refuses. Signed-off-by: Martin Pitt --- bin/BUCK | 20 +++++++++++++++++++- bin/tine.py | 3 +++ bin/umask_test.bzl | 21 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 bin/umask_test.bzl diff --git a/bin/BUCK b/bin/BUCK index 07a09eff..94d66bdf 100644 --- a/bin/BUCK +++ b/bin/BUCK @@ -3,8 +3,9 @@ """The command a checkout builds through.""" -load("//box:test.bzl", "box_python_test") +load("//box:test.bzl", "box_python_test", "box_sh_test") load("//python:defs.bzl", "tine_python_library") +load(":umask_test.bzl", "umask_probe") # How the launcher reads the cache settings and talks to a running shim, for the round trip in # tests/, which judges a build by the shim's own counters. @@ -34,3 +35,20 @@ box_python_test( "//:buckconfig", ], ) + +umask_probe(name = "umask-probe") + +# The launcher runs Buck with umask 022, so that a builder's own umask does not reach image +# directories; this fails when built with a umask such as 0002 without that. +box_sh_test( + name = "umask-test", + args = ["$(location :umask-probe)/directory"], + box = "//tools:dev.box", + script = """ +mode=$(stat -c %a "$1") +if [ "$mode" != 755 ]; then + echo "ERROR: $1 has mode $mode, expected 755" >&2 + exit 1 +fi +""", +) diff --git a/bin/tine.py b/bin/tine.py index 9a41029a..16a662a5 100644 --- a/bin/tine.py +++ b/bin/tine.py @@ -1722,6 +1722,9 @@ def before_shim( def buck_command(argv: list[str]) -> None: + # Buck stores no directory mode and creates directories in its outputs with its own umask. + # Normalize that to the 0755 that images.md promises. + os.umask(0o022) root = project_root(cwd()) ensure_home(root) settings = project_settings(root) diff --git a/bin/umask_test.bzl b/bin/umask_test.bzl new file mode 100644 index 00000000..2b066a69 --- /dev/null +++ b/bin/umask_test.bzl @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: Amutable GmbH +# SPDX-License-Identifier: MPL-2.0 + +"""An action that creates a directory, to test the umask the launcher runs Buck with.""" + +load("//box:runtime.bzl", "BoxInfo", "box_run") + +def _umask_probe_impl(ctx: AnalysisContext) -> list[Provider]: + out = ctx.actions.declare_output("probe", dir = True) + ctx.actions.run( + cmd_args(box_run(box = ctx.attrs._box[BoxInfo]), "mkdir", "-p", cmd_args(out.as_output(), format = "{}/directory")), + category = "umask_probe", + ) + return [DefaultInfo(default_output = out)] + +umask_probe = rule( + impl = _umask_probe_impl, + attrs = { + "_box": attrs.exec_dep(providers = [BoxInfo], default = "tine//tools:dev.box"), + }, +)