Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-efs-utils for openSUSE:Factory checked in at 2023-01-03 15:06:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-efs-utils (Old) and /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1563 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-efs-utils" Tue Jan 3 15:06:22 2023 rev:13 rq:1046505 version:1.34.4 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-efs-utils/aws-efs-utils.changes 2022-12-03 10:03:37.547236717 +0100 +++ /work/SRC/openSUSE:Factory/.aws-efs-utils.new.1563/aws-efs-utils.changes 2023-01-03 15:06:37.454950713 +0100 @@ -1,0 +2,8 @@ +Tue Jan 3 10:22:00 UTC 2023 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 1.34.4 + * Fix potential tlsport selection collision by using + state file as tlsport lock file +- Use RPM macros for directory paths (bsc#1191055) + +------------------------------------------------------------------- Old: ---- efs-utils-1.34.3.tar.gz New: ---- efs-utils-1.34.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-efs-utils.spec ++++++ --- /var/tmp/diff_new_pack.w3Bgj3/_old 2023-01-03 15:06:37.894953282 +0100 +++ /var/tmp/diff_new_pack.w3Bgj3/_new 2023-01-03 15:06:37.898953305 +0100 @@ -1,7 +1,7 @@ # # spec file for package aws-efs-utils # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: aws-efs-utils -Version: 1.34.3 +Version: 1.34.4 Release: 0 Summary: Utilities for using the EFS file systems License: MIT @@ -73,16 +73,15 @@ mkdir -p %{buildroot}%{_unitdir} install -p -m 644 %{_builddir}/efs-utils-%{version}/dist/amazon-efs-mount-watchdog.service %{buildroot}%{_unitdir} -mkdir -p %{buildroot}/sbin -mkdir -p %{buildroot}/usr/sbin mkdir -p %{buildroot}%{_bindir} +mkdir -p %{buildroot}%{_sbindir} mkdir -p %{buildroot}%{_localstatedir}/log/amazon/efs mkdir -p %{buildroot}%{_mandir}/man8 mkdir -p %{buildroot}%{_sysconfdir}/amazon/efs install -p -m 644 %{_builddir}/efs-utils-%{version}/dist/efs-utils.conf %{buildroot}%{_sysconfdir}/amazon/efs install -p -m 444 %{_builddir}/efs-utils-%{version}/dist/efs-utils.crt %{buildroot}%{_sysconfdir}/amazon/efs -install -p -m 755 %{_builddir}/efs-utils-%{version}/src/mount_efs/__init__.py %{buildroot}/sbin/mount.efs +install -p -m 755 %{_builddir}/efs-utils-%{version}/src/mount_efs/__init__.py %{buildroot}%{_sbindir}/mount.efs install -p -m 755 %{_builddir}/efs-utils-%{version}/src/watchdog/__init__.py %{buildroot}%{_bindir}/amazon-efs-mount-watchdog install -p -m 644 %{_builddir}/efs-utils-%{version}/man/mount.efs.8 %{buildroot}%{_mandir}/man8 @@ -109,10 +108,10 @@ %{_sysconfdir}/amazon %config %{_sysconfdir}/amazon/efs/efs-utils.conf %config %{_sysconfdir}/amazon/efs/efs-utils.crt -/sbin/mount.efs +%{_sbindir}/mount.efs %{_bindir}/amazon-efs-mount-watchdog %{_sbindir}/rcamazon-efs-mount-watchdog -/var/log/amazon +%{_var}/log/amazon %{_mandir}/man8/mount.efs.8.gz %changelog ++++++ efs-utils-1.34.3.tar.gz -> efs-utils-1.34.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/amazon-efs-utils.spec new/efs-utils-1.34.4/amazon-efs-utils.spec --- old/efs-utils-1.34.3/amazon-efs-utils.spec 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/amazon-efs-utils.spec 2022-12-14 07:13:07.000000000 +0100 @@ -35,7 +35,7 @@ %endif Name : amazon-efs-utils -Version : 1.34.3 +Version : 1.34.4 Release : 1%{platform} Summary : This package provides utilities for simplifying the use of EFS file systems @@ -137,6 +137,9 @@ %clean %changelog +* Tue Dec 13 2022 Ryan Stankiewicz <[email protected]> - 1.34.4 +- Fix potential tlsport selection collision by using state file as tlsport lock file. + * Thu Dec 1 2022 Preetham Puneeth Munipalli <[email protected]> - 1.34.3 - Fix potential tlsport selection race condition by closing socket right before establishing stunnel - Fix stunnel constantly restart issue when upgrading from 1.32.1 and before version to latest version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/build-deb.sh new/efs-utils-1.34.4/build-deb.sh --- old/efs-utils-1.34.3/build-deb.sh 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/build-deb.sh 2022-12-14 07:13:07.000000000 +0100 @@ -11,7 +11,7 @@ BASE_DIR=$(pwd) BUILD_ROOT=${BASE_DIR}/build/debbuild -VERSION=1.34.3 +VERSION=1.34.4 RELEASE=1 DEB_SYSTEM_RELEASE_PATH=/etc/os-release diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/config.ini new/efs-utils-1.34.4/config.ini --- old/efs-utils-1.34.3/config.ini 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/config.ini 2022-12-14 07:13:07.000000000 +0100 @@ -7,5 +7,5 @@ # [global] -version=1.34.3 +version=1.34.4 release=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/dist/amazon-efs-utils.control new/efs-utils-1.34.4/dist/amazon-efs-utils.control --- old/efs-utils-1.34.3/dist/amazon-efs-utils.control 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/dist/amazon-efs-utils.control 2022-12-14 07:13:07.000000000 +0100 @@ -1,6 +1,6 @@ Package: amazon-efs-utils Architecture: all -Version: 1.34.3 +Version: 1.34.4 Section: utils Depends: python3, nfs-common, stunnel4 (>= 4.56), openssl (>= 1.0.2), util-linux Priority: optional diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/src/mount_efs/__init__.py new/efs-utils-1.34.4/src/mount_efs/__init__.py --- old/efs-utils-1.34.3/src/mount_efs/__init__.py 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/src/mount_efs/__init__.py 2022-12-14 07:13:07.000000000 +0100 @@ -85,7 +85,7 @@ BOTOCORE_PRESENT = False -VERSION = "1.34.3" +VERSION = "1.34.4" SERVICE = "elasticfilesystem" AMAZON_LINUX_2_RELEASE_ID = "Amazon Linux release 2 (Karoo)" @@ -939,7 +939,7 @@ return lower_bound, upper_bound -def choose_tls_port_and_get_bind_sock(config, options): +def choose_tls_port_and_get_bind_sock(config, options, state_file_dir): if "tlsport" in options: ports_to_try = [int(options["tlsport"])] else: @@ -951,10 +951,14 @@ random.shuffle(ports_to_try) if "netns" not in options: - tls_port_sock = find_tls_port_in_range_and_get_bind_sock(ports_to_try) + tls_port_sock = find_tls_port_in_range_and_get_bind_sock( + ports_to_try, state_file_dir + ) else: with NetNS(nspath=options["netns"]): - tls_port_sock = find_tls_port_in_range_and_get_bind_sock(ports_to_try) + tls_port_sock = find_tls_port_in_range_and_get_bind_sock( + ports_to_try, state_file_dir + ) if tls_port_sock: return tls_port_sock @@ -971,20 +975,44 @@ ) -def find_tls_port_in_range_and_get_bind_sock(ports_to_try): +def find_tls_port_in_range_and_get_bind_sock(ports_to_try, state_file_dir): sock = socket.socket() for tls_port in ports_to_try: + mount = find_existing_mount_using_tls_port(state_file_dir, tls_port) + if mount: + logging.debug( + "Skip binding TLS port %s as it is already assigned to %s", + tls_port, + mount, + ) + continue try: logging.info("binding %s", tls_port) sock.bind(("localhost", tls_port)) return sock except socket.error as e: - logging.info(e) + logging.warning(e) continue sock.close() return None +def find_existing_mount_using_tls_port(state_file_dir, tls_port): + if not os.path.exists(state_file_dir): + logging.debug( + "State file dir %s does not exist, assuming no existing mount using tls port %s", + state_file_dir, + tls_port, + ) + return None + + for fname in os.listdir(state_file_dir): + if fname.endswith(".%s" % tls_port): + return fname + + return None + + def is_ocsp_enabled(config, options): if "ocsp" in options: return True @@ -1301,6 +1329,24 @@ return state_file +def rewrite_tls_tunnel_state_file(state, state_file_dir, state_file): + with open(os.path.join(state_file_dir, state_file), "w") as f: + json.dump(state, f) + return state_file + + +def update_tls_tunnel_temp_state_file_with_tunnel_pid( + temp_tls_state_file, state_file_dir, stunnel_pid +): + with open(os.path.join(state_file_dir, temp_tls_state_file), "r") as f: + state = json.load(f) + state["pid"] = stunnel_pid + temp_tls_state_file = rewrite_tls_tunnel_state_file( + state, state_file_dir, temp_tls_state_file + ) + return temp_tls_state_file + + def test_tunnel_process(tunnel_proc, fs_id): tunnel_proc.poll() if tunnel_proc.returncode is not None: @@ -1478,7 +1524,7 @@ state_file_dir=STATE_FILE_DIR, fallback_ip_address=None, ): - tls_port_sock = choose_tls_port_and_get_bind_sock(config, options) + tls_port_sock = choose_tls_port_and_get_bind_sock(config, options, state_file_dir) tls_port = get_tls_port_from_sock(tls_port_sock) try: @@ -1560,6 +1606,18 @@ tunnel_args = [_stunnel_bin(), stunnel_config_file] if "netns" in options: tunnel_args = ["nsenter", "--net=" + options["netns"]] + tunnel_args + + # This temp state file is acting like a tlsport lock file, which is why pid =- 1 + temp_tls_state_file = write_tls_tunnel_state_file( + fs_id, + mountpoint, + tls_port, + -1, + tunnel_args, + [stunnel_config_file], + state_file_dir, + cert_details=cert_details, + ) finally: # Always close the socket we created when choosing TLS port only until now to # 1. avoid concurrent TLS mount port collision 2. enable stunnel process to bind the port @@ -1577,15 +1635,8 @@ ) logging.info("Started TLS tunnel, pid: %d", tunnel_proc.pid) - temp_tls_state_file = write_tls_tunnel_state_file( - fs_id, - mountpoint, - tls_port, - tunnel_proc.pid, - tunnel_args, - [stunnel_config_file], - state_file_dir, - cert_details=cert_details, + update_tls_tunnel_temp_state_file_with_tunnel_pid( + temp_tls_state_file, state_file_dir, tunnel_proc.pid ) if "netns" not in options: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/src/watchdog/__init__.py new/efs-utils-1.34.4/src/watchdog/__init__.py --- old/efs-utils-1.34.3/src/watchdog/__init__.py 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/src/watchdog/__init__.py 2022-12-14 07:13:07.000000000 +0100 @@ -56,7 +56,7 @@ AMAZON_LINUX_2_RELEASE_ID, AMAZON_LINUX_2_PRETTY_NAME, ] -VERSION = "1.34.3" +VERSION = "1.34.4" SERVICE = "elasticfilesystem" CONFIG_FILE = "/etc/amazon/efs/efs-utils.conf" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/test/mount_efs_test/test_bootstrap_tls.py new/efs-utils-1.34.4/test/mount_efs_test/test_bootstrap_tls.py --- old/efs-utils-1.34.3/test/mount_efs_test/test_bootstrap_tls.py 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/test/mount_efs_test/test_bootstrap_tls.py 2022-12-14 07:13:07.000000000 +0100 @@ -44,6 +44,10 @@ mocker.patch("mount_efs.create_certificate") mocker.patch("os.rename") mocker.patch("os.kill") + mocker.patch( + "mount_efs.update_tls_tunnel_temp_state_file_with_tunnel_pid", + return_value="~mocktempfile", + ) process_mock = MagicMock() process_mock.communicate.return_value = ( @@ -72,6 +76,10 @@ ) mocker.patch("mount_efs.write_tls_tunnel_state_file", return_value="~mocktempfile") mocker.patch("os.kill") + mocker.patch( + "mount_efs.update_tls_tunnel_temp_state_file_with_tunnel_pid", + return_value="~mocktempfile", + ) write_config_mock = mocker.patch( "mount_efs.write_stunnel_config_file", return_value=EXPECTED_STUNNEL_CONFIG_FILE @@ -115,6 +123,7 @@ assert not os.path.exists(state_file_dir) mocker.patch("mount_efs._stunnel_bin", return_value="/usr/bin/stunnel") + mocker.patch("mount_efs.find_existing_mount_using_tls_port", return_value=None) with mount_efs.bootstrap_tls( MOCK_CONFIG, INIT_SYSTEM, DNS_NAME, FS_ID, MOUNT_POINT, {}, state_file_dir ): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/efs-utils-1.34.3/test/mount_efs_test/test_choose_tls_port.py new/efs-utils-1.34.4/test/mount_efs_test/test_choose_tls_port.py --- old/efs-utils-1.34.3/test/mount_efs_test/test_choose_tls_port.py 2022-12-02 12:17:58.000000000 +0100 +++ new/efs-utils-1.34.4/test/mount_efs_test/test_choose_tls_port.py 2022-12-14 07:13:07.000000000 +0100 @@ -3,9 +3,12 @@ # Licensed under the MIT License. See the LICENSE accompanying this file # for the specific language governing permissions and limitations under # the License. - +import logging import random import socket +import sys +import tempfile +import unittest from unittest.mock import MagicMock import pytest @@ -45,18 +48,20 @@ return config -def test_choose_tls_port_first_try(mocker): +def test_choose_tls_port_first_try(mocker, tmpdir): sock_mock = MagicMock() sock_mock.getsockname.return_value = ("local_host", DEFAULT_TLS_PORT) mocker.patch("socket.socket", return_value=sock_mock) options = {} - tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock( + _get_config(), options, str(tmpdir) + ) tls_port = mount_efs.get_tls_port_from_sock(tls_port_sock) assert DEFAULT_TLS_PORT_RANGE_LOW <= tls_port <= DEFAULT_TLS_PORT_RANGE_HIGH -def test_choose_tls_port_second_try(mocker): +def test_choose_tls_port_second_try(mocker, tmpdir): bad_sock = MagicMock() bad_sock.bind.side_effect = [socket.error, None] bad_sock.getsockname.return_value = ("local_host", DEFAULT_TLS_PORT) @@ -64,7 +69,9 @@ mocker.patch("socket.socket", return_value=bad_sock) - tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock( + _get_config(), options, str(tmpdir) + ) tls_port = mount_efs.get_tls_port_from_sock(tls_port_sock) assert DEFAULT_TLS_PORT_RANGE_LOW <= tls_port <= DEFAULT_TLS_PORT_RANGE_HIGH @@ -72,7 +79,31 @@ assert 1 == bad_sock.getsockname.call_count -def test_choose_tls_port_never_succeeds(mocker, capsys): [email protected](sys.version_info < (3, 6), reason="requires python3.6") +def test_choose_tls_port_collision(mocker, tmpdir, caplog): + """Ensure we don't choose a port that is pending mount""" + sock = MagicMock() + mocker.patch("socket.socket", return_value=sock) + mocker.patch( + "random.shuffle", + return_value=range(DEFAULT_TLS_PORT_RANGE_LOW, DEFAULT_TLS_PORT_RANGE_HIGH), + ) + + port_suffix = ".%s" % str(DEFAULT_TLS_PORT_RANGE_LOW) + temp_state_file = tempfile.NamedTemporaryFile( + suffix=port_suffix, prefix="~", dir=tmpdir + ) + + options = {} + with caplog.at_level(logging.DEBUG): + mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options, tmpdir) + + temp_state_file.close() + sock.bind.assert_called_once_with(("localhost", DEFAULT_TLS_PORT_RANGE_LOW + 1)) + assert "Skip binding TLS port" in caplog.text + + +def test_choose_tls_port_never_succeeds(mocker, tmpdir, capsys): bad_sock = MagicMock() bad_sock.bind.side_effect = socket.error() options = {} @@ -80,7 +111,7 @@ mocker.patch("socket.socket", return_value=bad_sock) with pytest.raises(SystemExit) as ex: - mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options, str(tmpdir)) assert 0 != ex.value.code @@ -93,19 +124,21 @@ ) -def test_choose_tls_port_option_specified(mocker): +def test_choose_tls_port_option_specified(mocker, tmpdir): sock_mock = MagicMock() sock_mock.getsockname.return_value = ("local_host", DEFAULT_TLS_PORT) mocker.patch("socket.socket", return_value=sock_mock) options = {"tlsport": DEFAULT_TLS_PORT} - tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + tls_port_sock = mount_efs.choose_tls_port_and_get_bind_sock( + _get_config(), options, str(tmpdir) + ) tls_port = mount_efs.get_tls_port_from_sock(tls_port_sock) assert DEFAULT_TLS_PORT == tls_port -def test_choose_tls_port_option_specified_unavailable(mocker, capsys): +def test_choose_tls_port_option_specified_unavailable(mocker, tmpdir, capsys): bad_sock = MagicMock() bad_sock.bind.side_effect = socket.error() options = {"tlsport": 1000} @@ -113,7 +146,7 @@ mocker.patch("socket.socket", return_value=bad_sock) with pytest.raises(SystemExit) as ex: - mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options, str(tmpdir)) assert 0 != ex.value.code @@ -123,13 +156,13 @@ assert 1 == bad_sock.bind.call_count -def test_choose_tls_port_under_netns(mocker, capsys): +def test_choose_tls_port_under_netns(mocker, tmpdir): mocker.patch("builtins.open") setns_mock = mocker.patch("mount_efs.setns", return_value=(None, None)) mocker.patch("socket.socket", return_value=MagicMock()) options = {"netns": "/proc/1000/ns/net"} - mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options) + mount_efs.choose_tls_port_and_get_bind_sock(_get_config(), options, str(tmpdir)) utils.assert_called(setns_mock)
