From 2fb656fd991d788ed54e098815d93458e46f069e Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Fri, 24 Nov 2023 15:54:09 +0000 Subject: [PATCH] fix: Don't loosen the permissions of the log file (#4628) Reference:https://github.com/canonical/cloud-init/commit/2fb656fd991d788ed54e098815d93458e46f069e Previous implementations loosened permissions in non-default scenarios. Fixes GH-4243 --- cloudinit/stages.py | 15 ++++++++++++++- cloudinit/tests/test_stages.py | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/cloudinit/stages.py b/cloudinit/stages.py index 633f57a..5e7733a 100644 --- a/cloudinit/stages.py +++ b/cloudinit/stages.py @@ -15,6 +15,7 @@ from cloudinit.settings import ( FREQUENCIES, CLOUD_CONFIG, PER_INSTANCE, RUN_CLOUD_CONFIG) from cloudinit import handlers +from contextlib import suppress # Default handlers (used if not overridden) from cloudinit.handlers.boot_hook import BootHookPartHandler @@ -146,13 +147,25 @@ class Init(object): def initialize(self): self._initialize_filesystem() + @staticmethod + def _get_strictest_mode(mode_1: int, mode_2: int) -> int: + return mode_1 & mode_2 + def _initialize_filesystem(self): + mode = 0o640 + util.ensure_dirs(self._initial_subdirs()) log_file = util.get_cfg_option_str(self.cfg, 'def_log_file') if log_file: # At this point the log file should have already been created # in the setupLogging function of log.py - util.ensure_file(log_file, mode=0o640, preserve_mode=False) + with suppress(OSError): + mode = self._get_strictest_mode( + 0o640, util.get_permissions(log_file) + ) + + # set file mode to the strictest of 0o640 and the current mode + util.ensure_file(log_file, mode, preserve_mode=False) perms = self.cfg.get('syslog_fix_perms') if not perms: perms = {} diff --git a/cloudinit/tests/test_stages.py b/cloudinit/tests/test_stages.py index d5c9c0e..42facb7 100644 --- a/cloudinit/tests/test_stages.py +++ b/cloudinit/tests/test_stages.py @@ -3,6 +3,7 @@ """Tests related to cloudinit.stages module.""" import os +import pytest from cloudinit import stages from cloudinit import sources @@ -341,4 +342,19 @@ class TestInit(CiTestCase): self.init.distro.apply_network_config.assert_called_with( net_cfg, bring_up=True) +@pytest.mark.parametrize( + "mode_1, mode_2, expected", + [ + (0o777, 0o640, 0o640), + (0o640, 0o777, 0o640), + (0o640, 0o541, 0o440), + (0o111, 0o050, 0o010), + (0o631, 0o640, 0o600), + (0o661, 0o640, 0o640), + (0o453, 0o611, 0o411), + ], +) +def test_strictest_permissions(mode_1, mode_2, expected): + assert expected == stages.Init._get_strictest_mode(mode_1, mode_2) + # vi: ts=4 expandtab -- 2.27.0