From 839f8fb3471f92c8df8a80a214779520ab18d045 Mon Sep 17 00:00:00 2001 From: Jonathan Thiessen Date: Mon, 28 Apr 2025 17:11:21 -0700 Subject: [PATCH] Avoid a few cases of chmod-after-creation --- clanModules/dyndns/default.nix | 14 +++++++++----- docs/nix/deploy-docs.nix | 3 +-- pkgs/clan-cli/clan_cli/vars/generate.py | 11 +++++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/clanModules/dyndns/default.nix b/clanModules/dyndns/default.nix index 3d686dd7a..aea0f70cd 100644 --- a/clanModules/dyndns/default.nix +++ b/clanModules/dyndns/default.nix @@ -210,14 +210,18 @@ in data_dir = Path('data') data_dir.mkdir(mode=0o770, exist_ok=True) + # Create a temporary config file + # with appropriate permissions + tmp_config_path = data_dir / '.config.json' + tmp_config_path.touch(mode=0o660, exist_ok=False) + # Write the config with secrets back - config_path = data_dir / 'config.json' - with open(config_path, 'w') as f: + with open(tmp_config_path, 'w') as f: f.write(json.dumps(config, indent=4)) - # Set file permissions to read and write - # only by the user and group - config_path.chmod(0o660) + # Move config into place + config_path = data_dir / 'config.json' + tmp_config_path.rename(config_path) # Set file permissions to read # and write only by the user and group diff --git a/docs/nix/deploy-docs.nix b/docs/nix/deploy-docs.nix index a2b9259d3..3a73f71cd 100644 --- a/docs/nix/deploy-docs.nix +++ b/docs/nix/deploy-docs.nix @@ -26,8 +26,7 @@ writeShellScriptBin "deploy-docs" '' trap "rm -rf $tmpdir" EXIT if [ -n "''${SSH_HOMEPAGE_KEY-}" ]; then - echo "$SSH_HOMEPAGE_KEY" > "$tmpdir/ssh_key" - chmod 600 "$tmpdir/ssh_key" + ( umask 0177 && echo "$SSH_HOMEPAGE_KEY" > "$tmpdir/ssh_key" ) sshExtraArgs="-i $tmpdir/ssh_key" else sshExtraArgs= diff --git a/pkgs/clan-cli/clan_cli/vars/generate.py b/pkgs/clan-cli/clan_cli/vars/generate.py index 761f1914e..32e0b64bc 100644 --- a/pkgs/clan-cli/clan_cli/vars/generate.py +++ b/pkgs/clan-cli/clan_cli/vars/generate.py @@ -148,12 +148,15 @@ def dependencies_as_dir( ) -> None: for dep_generator, files in decrypted_dependencies.items(): dep_generator_dir = tmpdir / dep_generator - dep_generator_dir.mkdir() - dep_generator_dir.chmod(0o700) + # Explicitly specify parents and exist_ok default values for clarity + dep_generator_dir.mkdir(mode=0o700, parents=False, exist_ok=False) for file_name, file in files.items(): file_path = dep_generator_dir / file_name - file_path.touch() - file_path.chmod(0o600) + # Avoid the file creation and chmod race + # If the file already existed, + # we'd have to create a temp one and rename instead; + # however, this is a clean dir so there shouldn't be any collisions + file_path.touch(mode=0o600, exist_ok=False) file_path.write_bytes(file)