diff --git a/67829.patch b/67829.patch deleted file mode 100644 index 87bb60f..0000000 --- a/67829.patch +++ /dev/null @@ -1,109 +0,0 @@ -From b36f6897b4b959bc6306214f82a213a466d2cda6 Mon Sep 17 00:00:00 2001 -From: s-hertel -Date: Thu, 27 Feb 2020 15:21:37 -0500 -Subject: [PATCH 1/2] subversion module - provide password securely with svn - command line option --password-from-stdin when possible, and provide a - warning otherwise - ---- - changelogs/fragments/subversion_password.yaml | 9 ++++++++ - .../modules/source_control/subversion.py | 21 ++++++++++++++++--- - 2 files changed, 27 insertions(+), 3 deletions(-) - create mode 100644 changelogs/fragments/subversion_password.yaml - -diff --git a/changelogs/fragments/subversion_password.yaml b/changelogs/fragments/subversion_password.yaml -new file mode 100644 -index 0000000000000..42e09fb1a0752 ---- /dev/null -+++ b/changelogs/fragments/subversion_password.yaml -@@ -0,0 +1,9 @@ -+bugfixes: -+- > -+ **security issue** - The ``subversion`` module provided the password -+ via the svn command line option ``--password`` and can be retrieved -+ from the host's /proc//cmdline file. Update the module to use -+ the secure ``--password-from-stdin`` option instead, and add a warning -+ in the module and in the documentation if svn version is too old to -+ support it. -+ (CVE-2020-1739) -diff --git a/lib/ansible/modules/source_control/subversion.py b/lib/ansible/modules/source_control/subversion.py -index c7625f620263c..bcd6cdec7c6f1 100644 ---- a/lib/ansible/modules/source_control/subversion.py -+++ b/lib/ansible/modules/source_control/subversion.py -@@ -56,7 +56,9 @@ - - C(--username) parameter passed to svn. - password: - description: -- - C(--password) parameter passed to svn. -+ - C(--password) parameter passed to svn when svn is less than version 1.10.0. This is not secure and -+ the password will be leaked to argv. -+ - C(--password-from-stdin) parameter when svn is greater or equal to version 1.10.0. - executable: - description: - - Path to svn executable to use. If not supplied, -@@ -111,6 +113,8 @@ - import os - import re - -+from distutils.version import LooseVersion -+ - from ansible.module_utils.basic import AnsibleModule - - -@@ -124,6 +128,10 @@ def __init__(self, module, dest, repo, revision, username, password, svn_path): - self.password = password - self.svn_path = svn_path - -+ def has_option_password_from_stdin(self): -+ rc, version, err = self.module.run_command([self.svn_path, '--version', '--quiet'], check_rc=True) -+ return LooseVersion(version) >= LooseVersion('1.10.0') -+ - def _exec(self, args, check_rc=True): - '''Execute a subversion command, and return output. If check_rc is False, returns the return code instead of the output.''' - bits = [ -@@ -132,12 +140,19 @@ def _exec(self, args, check_rc=True): - '--trust-server-cert', - '--no-auth-cache', - ] -+ stdin_data = None - if self.username: - bits.extend(["--username", self.username]) - if self.password: -- bits.extend(["--password", self.password]) -+ if self.has_option_password_from_stdin(): -+ bits.extend(["--password-from-stdin"]) -+ stdin_data = self.password -+ else: -+ self.module.warn("The authentication provided will be used on the svn command line and is not secure. " -+ "To securely pass credentials, upgrade svn to version 1.10.0 or greater.") -+ bits.extend(["--password", self.password]) - bits.extend(args) -- rc, out, err = self.module.run_command(bits, check_rc) -+ rc, out, err = self.module.run_command(bits, check_rc, data=stdin_data) - - if check_rc: - return out.splitlines() - -From 001892f3cdd5a43d13fed10ec419be1360815104 Mon Sep 17 00:00:00 2001 -From: Sloane Hertel -Date: Mon, 2 Mar 2020 15:23:44 -0500 -Subject: [PATCH 2/2] Update lib/ansible/modules/source_control/subversion.py - -Co-Authored-By: Sam Doran ---- - lib/ansible/modules/source_control/subversion.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/ansible/modules/source_control/subversion.py b/lib/ansible/modules/source_control/subversion.py -index bcd6cdec7c6f1..1e60529a062e3 100644 ---- a/lib/ansible/modules/source_control/subversion.py -+++ b/lib/ansible/modules/source_control/subversion.py -@@ -145,7 +145,7 @@ def _exec(self, args, check_rc=True): - bits.extend(["--username", self.username]) - if self.password: - if self.has_option_password_from_stdin(): -- bits.extend(["--password-from-stdin"]) -+ bits.append("--password-from-stdin") - stdin_data = self.password - else: - self.module.warn("The authentication provided will be used on the svn command line and is not secure. " diff --git a/67935.patch b/67935.patch deleted file mode 100644 index f44ec26..0000000 --- a/67935.patch +++ /dev/null @@ -1,191 +0,0 @@ -From aaf549d7870b8687209a3282841b59207735b676 Mon Sep 17 00:00:00 2001 -From: Sam Doran -Date: Fri, 28 Feb 2020 17:56:21 -0500 -Subject: [PATCH] win_unzip - normalize and compare paths to prevent path - traversal (#67799) - -* Actually inspect the paths and prevent escape -* Add integration tests -* Generate zip files for use in integration test -* Adjust error message - -(cherry picked from commit d30c57ab22db24f6901166fcc3155667bdd3443f) ---- - .../win-unzip-check-extraction-path.yml | 4 ++ - lib/ansible/modules/windows/win_unzip.ps1 | 9 +++ - .../files/create_crafty_zip_files.py | 65 +++++++++++++++++++ - .../targets/win_unzip/tasks/main.yml | 57 +++++++++++++++- - 4 files changed, 134 insertions(+), 1 deletion(-) - create mode 100644 changelogs/fragments/win-unzip-check-extraction-path.yml - create mode 100644 test/integration/targets/win_unzip/files/create_crafty_zip_files.py - -diff --git a/changelogs/fragments/win-unzip-check-extraction-path.yml b/changelogs/fragments/win-unzip-check-extraction-path.yml -new file mode 100644 -index 0000000000000..1a6b6133d66b9 ---- /dev/null -+++ b/changelogs/fragments/win-unzip-check-extraction-path.yml -@@ -0,0 +1,4 @@ -+bugfixes: -+ - > -+ **security issue** win_unzip - normalize paths in archive to ensure extracted -+ files do not escape from the target directory (CVE-2020-1737) -diff --git a/lib/ansible/modules/windows/win_unzip.ps1 b/lib/ansible/modules/windows/win_unzip.ps1 -index 234c774c3a6cb..b49e808845d73 100644 ---- a/lib/ansible/modules/windows/win_unzip.ps1 -+++ b/lib/ansible/modules/windows/win_unzip.ps1 -@@ -40,6 +40,15 @@ Function Extract-Zip($src, $dest) { - $entry_target_path = [System.IO.Path]::Combine($dest, $archive_name) - $entry_dir = [System.IO.Path]::GetDirectoryName($entry_target_path) - -+ # Normalize paths for further evaluation -+ $full_target_path = [System.IO.Path]::GetFullPath($entry_target_path) -+ $full_dest_path = [System.IO.Path]::GetFullPath($dest + [System.IO.Path]::DirectorySeparatorChar) -+ -+ # Ensure file in the archive does not escape the extraction path -+ if (-not $full_target_path.StartsWith($full_dest_path)) { -+ Fail-Json -obj $result -message "Error unzipping '$src' to '$dest'! Filename contains relative paths which would extract outside the destination: $entry_target_path" -+ } -+ - if (-not (Test-Path -LiteralPath $entry_dir)) { - New-Item -Path $entry_dir -ItemType Directory -WhatIf:$check_mode | Out-Null - $result.changed = $true -diff --git a/test/integration/targets/win_unzip/files/create_crafty_zip_files.py b/test/integration/targets/win_unzip/files/create_crafty_zip_files.py -new file mode 100644 -index 0000000000000..8845b486294c3 ---- /dev/null -+++ b/test/integration/targets/win_unzip/files/create_crafty_zip_files.py -@@ -0,0 +1,65 @@ -+#!/usr/bin/env python -+# -*- coding: utf-8 -*- -+ -+# Copyright (c) 2020 Ansible Project -+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -+ -+from __future__ import absolute_import, division, print_function -+__metaclass__ = type -+ -+import os -+import shutil -+import sys -+import zipfile -+ -+# Each key is a zip file and the vaule is the list of files that will be created -+# and placed in the archive -+zip_files = { -+ 'hat1': [r'hat/..\rabbit.txt'], -+ 'hat2': [r'hat/..\..\rabbit.txt'], -+ 'handcuffs': [r'..\..\houidini.txt'], -+ 'prison': [r'..\houidini.txt'], -+} -+ -+# Accept an argument of where to create the files, defaulting to -+# the current working directory. -+try: -+ output_dir = sys.argv[1] -+except IndexError: -+ output_dir = os.getcwd() -+ -+if not os.path.isdir(output_dir): -+ os.mkdir(output_dir) -+ -+os.chdir(output_dir) -+ -+for name, files in zip_files.items(): -+ # Create the files to go in the zip archive -+ for entry in files: -+ dirname = os.path.dirname(entry) -+ if dirname: -+ if os.path.isdir(dirname): -+ shutil.rmtree(dirname) -+ os.mkdir(dirname) -+ -+ with open(entry, 'w') as e: -+ e.write('escape!\n') -+ -+ # Create the zip archive with the files -+ filename = '%s.zip' % name -+ if os.path.isfile(filename): -+ os.unlink(filename) -+ -+ with zipfile.ZipFile(filename, 'w') as zf: -+ for entry in files: -+ zf.write(entry) -+ -+ # Cleanup -+ if dirname: -+ shutil.rmtree(dirname) -+ -+ for entry in files: -+ try: -+ os.unlink(entry) -+ except OSError: -+ pass -diff --git a/test/integration/targets/win_unzip/tasks/main.yml b/test/integration/targets/win_unzip/tasks/main.yml -index 2dab84be563b0..a9b8f1ca22998 100644 ---- a/test/integration/targets/win_unzip/tasks/main.yml -+++ b/test/integration/targets/win_unzip/tasks/main.yml -@@ -1,4 +1,3 @@ ----- - - name: create test directory - win_file: - path: '{{ win_unzip_dir }}\output' -@@ -114,3 +113,59 @@ - - unzip_delete is changed - - unzip_delete.removed - - not unzip_delete_actual.stat.exists -+ -+# Path traversal tests (CVE-2020-1737) -+- name: Create zip files -+ script: create_crafty_zip_files.py {{ output_dir }} -+ delegate_to: localhost -+ -+- name: Copy zip files to Windows host -+ win_copy: -+ src: "{{ output_dir }}/{{ item }}.zip" -+ dest: "{{ win_unzip_dir }}/" -+ loop: -+ - hat1 -+ - hat2 -+ - handcuffs -+ - prison -+ -+- name: Perform first trick -+ win_unzip: -+ src: '{{ win_unzip_dir }}\hat1.zip' -+ dest: '{{ win_unzip_dir }}\output' -+ register: hat_trick1 -+ -+- name: Check for file -+ win_stat: -+ path: '{{ win_unzip_dir }}\output\rabbit.txt' -+ register: rabbit -+ -+- name: Perform next tricks (which should all fail) -+ win_unzip: -+ src: '{{ win_unzip_dir }}\{{ item }}.zip' -+ dest: '{{ win_unzip_dir }}\output' -+ ignore_errors: yes -+ register: escape -+ loop: -+ - hat2 -+ - handcuffs -+ - prison -+ -+- name: Search for files -+ win_find: -+ recurse: yes -+ paths: -+ - '{{ win_unzip_dir }}' -+ patterns: -+ - '*houdini.txt' -+ - '*rabbit.txt' -+ register: files -+ -+- name: Check results -+ assert: -+ that: -+ - rabbit.stat.exists -+ - hat_trick1 is success -+ - escape.results | map(attribute='failed') | unique | list == [True] -+ - files.matched == 1 -+ - files.files[0]['filename'] == 'rabbit.txt' diff --git a/ansible.spec b/ansible.spec index 9db3566..8c05b2c 100644 --- a/ansible.spec +++ b/ansible.spec @@ -9,8 +9,8 @@ Name: ansible Summary: SSH-based configuration management, deployment, and task execution system -Version: 2.9.6 -Release: 3%{?dist} +Version: 2.9.7 +Release: 1%{?dist} License: GPLv3+ Source0: https://releases.ansible.com/ansible/%{name}-%{version}.tar.gz @@ -24,12 +24,6 @@ Patch100: ansible-newer-jinja.patch Url: http://ansible.com BuildArch: noarch -# fix for CVE-2020-1737, https://github.com/ansible/ansible/pull/67935 -Patch0: https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/67935.patch - -# fix for CVE-2020-1739, https://github.com/ansible/ansible/pull/67829 -Patch1: https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/67829.patch - # Disable failing test Patch2: ansible-2.9.6-disable-test_build_requirement_from_path_no_version.patch @@ -92,7 +86,7 @@ Requires: python%{python3_pkgversion}-paramiko Requires: python%{python3_pkgversion}-cryptography # accelerate is the only thing that makes keyczar mandatory. Since accelerate # is deprecated, just ignore it -#Requires: python%{python3_pkgversion}-keyczar +#Requires: python%%{python3_pkgversion}-keyczar Requires: python%{python3_pkgversion}-setuptools Requires: python%{python3_pkgversion}-six Requires: python%{python3_pkgversion}-jinja2 @@ -132,8 +126,6 @@ This package installs extensive documentation for ansible %prep %setup -q -n %{name}-%{version} -%patch0 -p1 -%patch1 -p1 %patch2 -p1 %if 0%{?with_python3} @@ -149,6 +141,8 @@ cp -a . %{py3dir} %if 0%{?with_python3} pushd %{py3dir} +# disable the python -s shbang flag as we want to be able to find non system modules +%global py3_shbang_opts %(echo %{py3_shbang_opts} | sed 's/-s//') %py3_build %if %with_docs @@ -288,6 +282,11 @@ cp -pr docs/docsite/rst . %endif %changelog +* Sat Apr 18 2020 Kevin Fenzi - 2.9.7-1 +- Update to 2.9.7. +- fixes CVE-2020-1733 CVE-2020-1735 CVE-2020-1740 CVE-2020-1746 CVE-2020-1753 CVE-2020-10684 CVE-2020-10685 CVE-2020-10691 +- Drop the -s from the shebang to allow ansible to use locally installed modules. + * Mon Apr 06 2020 Igor Raits - 2.9.6-3 - Ship ansible-test in both (py2 and py3) variants diff --git a/sources b/sources index 8d89c0b..40a73a1 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (ansible-2.9.6.tar.gz) = 7111fd72b4e029b2f661bfb849b4323b69ea796f8a069ad3120e8de390effa670180c69ca0fd5e0a1c2e444db6d574a52d530a2b0343c76cd81ba963b3c3a7cb +SHA512 (ansible-2.9.7.tar.gz) = ce029441bcafdc5b44c9fda69f183d4defea84ead5628164caf87306cb97efec68c11b2cce728e90f28290640c320549486a6b4e823710f638d1d2e7c35675a4