From 6b618eac7db87a2d80038c272e1c6fe879e5e9a7 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Thu, 20 Mar 2025 23:08:57 +0530 Subject: [PATCH 1/6] restricting execution permissions to root user/ owner --- src/core/src/core_logic/TimerManager.py | 2 +- src/extension/src/ActionHandler.py | 2 +- src/extension/src/ProcessHandler.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/src/core_logic/TimerManager.py b/src/core/src/core_logic/TimerManager.py index e10fa0cab..532dfdeef 100644 --- a/src/core/src/core_logic/TimerManager.py +++ b/src/core/src/core_logic/TimerManager.py @@ -114,5 +114,5 @@ def create_timer_unit_file(self, desc, on_unit_active_sec="3h", on_boot_sec="15m timer_unit_content = timer_unit_content_template.format(desc, on_boot_sec, on_unit_active_sec) timer_unit_path = self.__systemd_timer_unit_path.format(self.service_name) self.env_layer.file_system.write_with_retry(timer_unit_path, timer_unit_content) - self.env_layer.run_command_output("sudo chmod a+x " + timer_unit_path) + self.env_layer.run_command_output("sudo chmod 644 " + timer_unit_path) # endregion \ No newline at end of file diff --git a/src/extension/src/ActionHandler.py b/src/extension/src/ActionHandler.py index 9e753c6d4..5f1ac4fd7 100644 --- a/src/extension/src/ActionHandler.py +++ b/src/extension/src/ActionHandler.py @@ -352,7 +352,7 @@ def disable(self): "\r\n# Copyright 2021 Microsoft Corporation" + \ "\r\n printf \"Auto-assessment was paused by the Azure Linux Patch Extension.\"" self.env_layer.file_system.write_with_retry(auto_assess_sh_path, auto_assess_sh_data) - self.env_layer.run_command_output("chmod a+x " + auto_assess_sh_path) + self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) # Clear temp folder self.ext_env_handler.delete_temp_folder_contents() diff --git a/src/extension/src/ProcessHandler.py b/src/extension/src/ProcessHandler.py index da140603c..7025e4009 100644 --- a/src/extension/src/ProcessHandler.py +++ b/src/extension/src/ProcessHandler.py @@ -126,7 +126,7 @@ def stage_auto_assess_sh_safely(self, core_process_command): if os.path.exists(auto_assess_sh_path): os.remove(auto_assess_sh_path) self.env_layer.file_system.write_with_retry(auto_assess_sh_path, auto_assess_sh_data) - self.env_layer.run_command_output("chmod a+x " + auto_assess_sh_path) + self.env_layer.run_command_output("chmod 644 " + auto_assess_sh_path) self.logger.log_debug("Completed staging auto assessment shell script with latest config.") except Exception as error: From ad4aa6356ae2aa93f6663eefdb0db457de908546 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Thu, 20 Mar 2025 23:55:04 +0530 Subject: [PATCH 2/6] service manager to 644 and assess.sh to 744 --- src/core/src/core_logic/ServiceManager.py | 2 +- src/extension/src/ProcessHandler.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/src/core_logic/ServiceManager.py b/src/core/src/core_logic/ServiceManager.py index 6e865a6e9..385bd0867 100644 --- a/src/core/src/core_logic/ServiceManager.py +++ b/src/core/src/core_logic/ServiceManager.py @@ -101,7 +101,7 @@ def create_service_unit_file(self, exec_start, desc, after="network.target", ser service_unit_content = service_unit_content_template.format(desc, after, service_type, exec_start, wanted_by) service_unit_path = self.__systemd_service_unit_path.format(self.service_name) self.env_layer.file_system.write_with_retry(service_unit_path, service_unit_content) - self.env_layer.run_command_output("sudo chmod a+x " + service_unit_path) + self.env_layer.run_command_output("sudo chmod 644 " + service_unit_path) # endregion diff --git a/src/extension/src/ProcessHandler.py b/src/extension/src/ProcessHandler.py index 7025e4009..f54567c0e 100644 --- a/src/extension/src/ProcessHandler.py +++ b/src/extension/src/ProcessHandler.py @@ -126,7 +126,7 @@ def stage_auto_assess_sh_safely(self, core_process_command): if os.path.exists(auto_assess_sh_path): os.remove(auto_assess_sh_path) self.env_layer.file_system.write_with_retry(auto_assess_sh_path, auto_assess_sh_data) - self.env_layer.run_command_output("chmod 644 " + auto_assess_sh_path) + self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) self.logger.log_debug("Completed staging auto assessment shell script with latest config.") except Exception as error: From d8ff7b25dc103bbe207a414c1d6f8dbe390dad43 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Fri, 21 Mar 2025 19:40:54 +0530 Subject: [PATCH 3/6] code comment for explanation --- src/core/src/core_logic/ServiceManager.py | 2 +- src/core/src/core_logic/TimerManager.py | 2 +- src/extension/src/ActionHandler.py | 2 +- src/extension/src/ProcessHandler.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/src/core_logic/ServiceManager.py b/src/core/src/core_logic/ServiceManager.py index 385bd0867..00f87e15b 100644 --- a/src/core/src/core_logic/ServiceManager.py +++ b/src/core/src/core_logic/ServiceManager.py @@ -101,7 +101,7 @@ def create_service_unit_file(self, exec_start, desc, after="network.target", ser service_unit_content = service_unit_content_template.format(desc, after, service_type, exec_start, wanted_by) service_unit_path = self.__systemd_service_unit_path.format(self.service_name) self.env_layer.file_system.write_with_retry(service_unit_path, service_unit_content) - self.env_layer.run_command_output("sudo chmod 644 " + service_unit_path) + self.env_layer.run_command_output("sudo chmod 644 " + service_unit_path) # 644 = Owner: RW; Group: R; Others: R # endregion diff --git a/src/core/src/core_logic/TimerManager.py b/src/core/src/core_logic/TimerManager.py index 532dfdeef..c256c2316 100644 --- a/src/core/src/core_logic/TimerManager.py +++ b/src/core/src/core_logic/TimerManager.py @@ -114,5 +114,5 @@ def create_timer_unit_file(self, desc, on_unit_active_sec="3h", on_boot_sec="15m timer_unit_content = timer_unit_content_template.format(desc, on_boot_sec, on_unit_active_sec) timer_unit_path = self.__systemd_timer_unit_path.format(self.service_name) self.env_layer.file_system.write_with_retry(timer_unit_path, timer_unit_content) - self.env_layer.run_command_output("sudo chmod 644 " + timer_unit_path) + self.env_layer.run_command_output("sudo chmod 644 " + timer_unit_path) # 644 = Owner: RW; Group: R; Others: R # endregion \ No newline at end of file diff --git a/src/extension/src/ActionHandler.py b/src/extension/src/ActionHandler.py index 5f1ac4fd7..98ca85ba8 100644 --- a/src/extension/src/ActionHandler.py +++ b/src/extension/src/ActionHandler.py @@ -352,7 +352,7 @@ def disable(self): "\r\n# Copyright 2021 Microsoft Corporation" + \ "\r\n printf \"Auto-assessment was paused by the Azure Linux Patch Extension.\"" self.env_layer.file_system.write_with_retry(auto_assess_sh_path, auto_assess_sh_data) - self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) + self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) # 744 = Owner: RWX; Group: R; Others: R # Clear temp folder self.ext_env_handler.delete_temp_folder_contents() diff --git a/src/extension/src/ProcessHandler.py b/src/extension/src/ProcessHandler.py index f54567c0e..93e8e2529 100644 --- a/src/extension/src/ProcessHandler.py +++ b/src/extension/src/ProcessHandler.py @@ -126,7 +126,7 @@ def stage_auto_assess_sh_safely(self, core_process_command): if os.path.exists(auto_assess_sh_path): os.remove(auto_assess_sh_path) self.env_layer.file_system.write_with_retry(auto_assess_sh_path, auto_assess_sh_data) - self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) + self.env_layer.run_command_output("chmod 744 " + auto_assess_sh_path) # 744 = Owner: RWX; Group: R; Others: R self.logger.log_debug("Completed staging auto assessment shell script with latest config.") except Exception as error: From 7c3d79119467772360c16dd3b172faa91d3fd928 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Fri, 21 Mar 2025 22:23:28 +0530 Subject: [PATCH 4/6] new test for service manager and file permissions --- src/core/tests/Test_ServiceManager.py | 50 +++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/core/tests/Test_ServiceManager.py diff --git a/src/core/tests/Test_ServiceManager.py b/src/core/tests/Test_ServiceManager.py new file mode 100644 index 000000000..0bf5cba75 --- /dev/null +++ b/src/core/tests/Test_ServiceManager.py @@ -0,0 +1,50 @@ +# Copyright 2023 Microsoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Requires Python 2.7+ + +import unittest + +from core.tests.library.ArgumentComposer import ArgumentComposer +from core.tests.library.RuntimeCompositor import RuntimeCompositor +from core.src.core_logic.ServiceManager import ServiceManager +from core.src.core_logic.ServiceManager import ServiceInfo + +class TestServiceManager(unittest.TestCase): + def setUp(self): + self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) + self.container = self.runtime.container + + def tearDown(self): + self.runtime.stop() + + def mock_run_command_to_set_service_file_permission(self, cmd, no_output=False, chk_err=False): + parts = cmd.split() + if parts[1] == "chmod" and parts[2] == "644": + return 0, "permissions set" + else: + raise Exception + + def mock_write_with_retry_valid(self, file_path_or_handle, data, mode='a+'): + return + + def test_create_service_unit_file(self): + service_manager = ServiceManager(self.runtime.env_layer, self.runtime.execution_config, self.runtime.composite_logger, self.runtime.telemetry_writer, ServiceInfo("AutoAssessment","Auto assessment service","path")) + service_manager.env_layer.run_command_output = self.mock_run_command_to_set_service_file_permission + service_manager.env_layer.file_system.write_with_retry = self.mock_write_with_retry_valid + service_manager.create_service_unit_file(exec_start="/bin/bash " + service_manager.service_exec_path, desc="Microsoft Azure Linux Patch Extension - Auto Assessment") + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 72deaa39e50ca30c5b8092ad4da8284153dbffd0 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Fri, 21 Mar 2025 22:29:37 +0530 Subject: [PATCH 5/6] Tests for timer manager --- src/core/tests/Test_TimerManager.py | 50 +++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/core/tests/Test_TimerManager.py diff --git a/src/core/tests/Test_TimerManager.py b/src/core/tests/Test_TimerManager.py new file mode 100644 index 000000000..8c64df6d9 --- /dev/null +++ b/src/core/tests/Test_TimerManager.py @@ -0,0 +1,50 @@ +# Copyright 2023 Microsoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Requires Python 2.7+ + +import unittest + +from core.tests.library.ArgumentComposer import ArgumentComposer +from core.tests.library.RuntimeCompositor import RuntimeCompositor +from core.src.core_logic.TimerManager import TimerManager +from core.src.core_logic.ServiceManager import ServiceInfo + +class TestTimerManager(unittest.TestCase): + def setUp(self): + self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) + self.container = self.runtime.container + + def tearDown(self): + self.runtime.stop() + + def mock_run_command_to_set_service_file_permission(self, cmd, no_output=False, chk_err=False): + parts = cmd.split() + if parts[1] == "chmod" and parts[2] == "644": + return 0, "permissions set" + else: + raise Exception + + def mock_write_with_retry_valid(self, file_path_or_handle, data, mode='a+'): + return + + def test_create_timer_unit_file(self): + service_manager = TimerManager(self.runtime.env_layer, self.runtime.execution_config, self.runtime.composite_logger, self.runtime.telemetry_writer, ServiceInfo("AutoAssessment","Auto assessment service","path")) + service_manager.env_layer.run_command_output = self.mock_run_command_to_set_service_file_permission + service_manager.env_layer.file_system.write_with_retry = self.mock_write_with_retry_valid + service_manager.create_timer_unit_file(desc="Microsoft Azure Linux Patch Extension - Auto Assessment Timer") + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 7c41e052be0ab5afa7cee729d6497e4a54e45d83 Mon Sep 17 00:00:00 2001 From: Nikhil Mengaram Date: Fri, 21 Mar 2025 22:40:18 +0530 Subject: [PATCH 6/6] nit comments - newline etc --- src/core/src/core_logic/TimerManager.py | 2 +- src/core/tests/Test_ServiceManager.py | 4 ++-- src/core/tests/Test_TimerManager.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/src/core_logic/TimerManager.py b/src/core/src/core_logic/TimerManager.py index c256c2316..df9556b54 100644 --- a/src/core/src/core_logic/TimerManager.py +++ b/src/core/src/core_logic/TimerManager.py @@ -115,4 +115,4 @@ def create_timer_unit_file(self, desc, on_unit_active_sec="3h", on_boot_sec="15m timer_unit_path = self.__systemd_timer_unit_path.format(self.service_name) self.env_layer.file_system.write_with_retry(timer_unit_path, timer_unit_content) self.env_layer.run_command_output("sudo chmod 644 " + timer_unit_path) # 644 = Owner: RW; Group: R; Others: R - # endregion \ No newline at end of file + # endregion diff --git a/src/core/tests/Test_ServiceManager.py b/src/core/tests/Test_ServiceManager.py index 0bf5cba75..7de69a689 100644 --- a/src/core/tests/Test_ServiceManager.py +++ b/src/core/tests/Test_ServiceManager.py @@ -1,4 +1,4 @@ -# Copyright 2023 Microsoft Corporation +# Copyright 2025 Microsoft Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -47,4 +47,4 @@ def test_create_service_unit_file(self): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/src/core/tests/Test_TimerManager.py b/src/core/tests/Test_TimerManager.py index 8c64df6d9..8dcf49b49 100644 --- a/src/core/tests/Test_TimerManager.py +++ b/src/core/tests/Test_TimerManager.py @@ -1,4 +1,4 @@ -# Copyright 2023 Microsoft Corporation +# Copyright 2025 Microsoft Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -47,4 +47,4 @@ def test_create_timer_unit_file(self): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main()