From 5015e6892fa64b5df5e62826cd5cfd57d72ddfc3 Mon Sep 17 00:00:00 2001 From: Kevin Fenzi Date: Jun 09 2019 07:04:10 +0000 Subject: Update to 2.8.1. Fixes bug #1718131 Sync up Requires/Buildrequires with upstream. Add patch for python 3.8 building. Fixes bug #1712531 Add patch for CVE-2019-10156. --- diff --git a/.gitignore b/.gitignore index 58218a5..ea5930d 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,4 @@ /ansible-2.8.0rc1.tar.gz /ansible-2.8.0rc3.tar.gz /ansible-2.8.0.tar.gz +/ansible-2.8.1.tar.gz diff --git a/56806.patch b/56806.patch new file mode 100644 index 0000000..2fa1666 --- /dev/null +++ b/56806.patch @@ -0,0 +1,70 @@ +From 702e044b90fd0a0524fa4574648fe7dae4d4f2fe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +Date: Wed, 22 May 2019 21:31:22 +0200 +Subject: [PATCH] Don't change dictionary keys during iteration + +With Python 3.8.0a4+, we get the following RuntimeError in Fedora: + +PYTHONPATH=../../lib ../bin/dump_keywords.py --template-dir=../templates --output-dir=rst/reference_appendices/ -d ./keyword_desc.yml +Traceback (most recent call last): + File "../bin/dump_keywords.py", line 49, in + for a in oblist[name]: +RuntimeError: dictionary keys changed during iteration + +And: + + def populate(self): + super(Interfaces, self).populate() + self.facts['all_ipv4_addresses'] = list() + self.facts['all_ipv6_addresses'] = list() + + data = self.responses[0] + interfaces = self.parse_interfaces(data) + +> for key in interfaces.keys(): +E RuntimeError: dictionary keys changed during iteration + +In TestDellos9Facts.test_dellos9_facts_gather_subset_default +and TestDellos9Facts.test_dellos9_facts_gather_subset_interfaces. + +Python change: https://github.com/python/cpython/pull/12596 + +Downstream bug: https://bugzilla.redhat.com/show_bug.cgi?id=1712531 +--- + docs/bin/dump_keywords.py | 2 +- + lib/ansible/modules/network/dellos9/dellos9_facts.py | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/docs/bin/dump_keywords.py b/docs/bin/dump_keywords.py +index 30056a6fc8cc..e25171126576 100755 +--- a/docs/bin/dump_keywords.py ++++ b/docs/bin/dump_keywords.py +@@ -46,7 +46,7 @@ + oblist[name] = dict((x, aobj.__dict__['_attributes'][x]) for x in aobj.__dict__['_attributes'] if 'private' not in x or not x.private) + + # pick up docs if they exist +- for a in oblist[name]: ++ for a in list(oblist[name]): + if a in docs: + oblist[name][a] = docs[a] + else: +diff --git a/lib/ansible/modules/network/dellos9/dellos9_facts.py b/lib/ansible/modules/network/dellos9/dellos9_facts.py +index b7abedf5527d..5818644430b6 100644 +--- a/lib/ansible/modules/network/dellos9/dellos9_facts.py ++++ b/lib/ansible/modules/network/dellos9/dellos9_facts.py +@@ -252,13 +252,13 @@ def populate(self): + data = self.responses[0] + interfaces = self.parse_interfaces(data) + +- for key in interfaces.keys(): ++ for key in list(interfaces.keys()): + if "ManagementEthernet" in key: + temp_parsed = interfaces[key] + del interfaces[key] + interfaces.update(self.parse_mgmt_interfaces(temp_parsed)) + +- for key in interfaces.keys(): ++ for key in list(interfaces.keys()): + if "Vlan" in key: + temp_parsed = interfaces[key] + del interfaces[key] diff --git a/57188.patch b/57188.patch new file mode 100644 index 0000000..c309bb1 --- /dev/null +++ b/57188.patch @@ -0,0 +1,247 @@ +From 8254c266f962d5febe46396d5083bb9c1da74840 Mon Sep 17 00:00:00 2001 +From: Brian Coca +Date: Tue, 4 Jun 2019 08:43:15 -0400 +Subject: [PATCH 1/2] just dont pass locals + + - also fix globals + - added tests +--- + changelogs/fragments/fix_safe_eval.yml | 2 + + lib/ansible/template/__init__.py | 2 +- + lib/ansible/template/safe_eval.py | 8 ++- + .../targets/template/corner_cases.yml | 51 +++++++++++++++++++ + test/integration/targets/template/runme.sh | 4 ++ + 5 files changed, 64 insertions(+), 3 deletions(-) + create mode 100644 changelogs/fragments/fix_safe_eval.yml + create mode 100644 test/integration/targets/template/corner_cases.yml + +diff --git a/changelogs/fragments/fix_safe_eval.yml b/changelogs/fragments/fix_safe_eval.yml +new file mode 100644 +index 000000000000..19220b34ffb1 +--- /dev/null ++++ b/changelogs/fragments/fix_safe_eval.yml +@@ -0,0 +1,2 @@ ++bugfixes: ++ - Handle improper variable substitution that was happening in safe_eval, it was always meant to just do 'type enforcement' and have Jinja2 deal with all variable interpolation. Also see CVE-2019-10156 +diff --git a/lib/ansible/template/__init__.py b/lib/ansible/template/__init__.py +index f88b7165db1f..ec4bf6771379 100644 +--- a/lib/ansible/template/__init__.py ++++ b/lib/ansible/template/__init__.py +@@ -543,7 +543,7 @@ def template(self, variable, convert_bare=False, preserve_trailing_newlines=True + # if this looks like a dictionary or list, convert it to such using the safe_eval method + if (result.startswith("{") and not result.startswith(self.environment.variable_start_string)) or \ + result.startswith("[") or result in ("True", "False"): +- eval_results = safe_eval(result, locals=self._available_variables, include_exceptions=True) ++ eval_results = safe_eval(result, include_exceptions=True) + if eval_results[1] is None: + result = eval_results[0] + if unsafe: +diff --git a/lib/ansible/template/safe_eval.py b/lib/ansible/template/safe_eval.py +index 9c70be4a897d..4f5b856180af 100644 +--- a/lib/ansible/template/safe_eval.py ++++ b/lib/ansible/template/safe_eval.py +@@ -42,10 +42,14 @@ def safe_eval(expr, locals=None, include_exceptions=False): + + # define certain JSON types + # eg. JSON booleans are unknown to python eval() +- JSON_TYPES = { ++ OUR_GLOBALS = { ++ '__builtins__': {}, # avoid global builtins as per eval docs + 'false': False, + 'null': None, + 'true': True, ++ # also add back some builtins we do need ++ 'True': True, ++ 'False': False, + } + + # this is the whitelist of AST nodes we are going to +@@ -138,7 +142,7 @@ def generic_visit(self, node, inside_call=False): + # Note: passing our own globals and locals here constrains what + # callables (and other identifiers) are recognized. this is in + # addition to the filtering of builtins done in CleansingNodeVisitor +- result = eval(compiled, JSON_TYPES, dict(locals)) ++ result = eval(compiled, OUR_GLOBALS, dict(locals)) + + if include_exceptions: + return (result, None) +diff --git a/test/integration/targets/template/corner_cases.yml b/test/integration/targets/template/corner_cases.yml +new file mode 100644 +index 000000000000..48782f79590c +--- /dev/null ++++ b/test/integration/targets/template/corner_cases.yml +@@ -0,0 +1,51 @@ ++- name: test tempating corner cases ++ hosts: localhost ++ gather_facts: false ++ vars: ++ empty_list: [] ++ dont: I SHOULD NOT BE TEMPLATED ++ other: I WORK ++ tasks: ++ - name: 'ensure we are not interpolating data from outside of j2 delmiters' ++ assert: ++ that: ++ - '"I SHOULD NOT BE TEMPLATED" not in adjacent' ++ - globals1 == "[[], globals()]" ++ - globals2 == "[[], globals]" ++ vars: ++ adjacent: "{{ empty_list }} + [dont]" ++ globals1: "[{{ empty_list }}, globals()]" ++ globals2: "[{{ empty_list }}, globals]" ++ ++ - name: 'ensure we can add lists' ++ assert: ++ that: ++ - (empty_list + [other]) == [other] ++ - (empty_list + [other, other]) == [other, other] ++ - (dont_exist|default([]) + [other]) == [other] ++ - ([other] + [empty_list, other]) == [other, [], other] ++ ++ - name: 'ensure comments go away and we still dont interpolate in string' ++ assert: ++ that: ++ - 'comm1 == " + [dont]"' ++ - 'comm2 == " #} + [dont]"' ++ vars: ++ comm1: '{# {{nothing}} {# #} + [dont]' ++ comm2: "{# {{nothing}} {# #} #} + [dont]" ++ ++ - name: test additions with facts, set them up ++ set_fact: ++ inames: [] ++ iname: "{{ prefix ~ '-options' }}" ++ iname_1: "{{ prefix ~ '-options-1' }}" ++ vars: ++ prefix: 'bo' ++ ++ - name: add the facts ++ set_fact: ++ inames: '{{ inames + [iname, iname_1] }}' ++ ++ - assert: ++ that: ++ - inames == ['bo-options', 'bo-options-1'] +diff --git a/test/integration/targets/template/runme.sh b/test/integration/targets/template/runme.sh +index 2b58bc92dd3e..c4f50b1c7e28 100755 +--- a/test/integration/targets/template/runme.sh ++++ b/test/integration/targets/template/runme.sh +@@ -12,3 +12,7 @@ ansible-playbook ansible_managed.yml -c ansible_managed.cfg -i ../../inventory + + # Test for #42585 + ANSIBLE_ROLES_PATH=../ ansible-playbook custom_template.yml -i ../../inventory -e @../../integration_config.yml -v "$@" ++ ++ ++# Test for several corner cases #57188 ++ansible-playbook corner_cases.yml -v "$@" + +From fbda0028750a17a032d83dad9d1fb284f9ea68a4 Mon Sep 17 00:00:00 2001 +From: Brian Coca +Date: Thu, 6 Jun 2019 13:26:14 -0400 +Subject: [PATCH 2/2] fixed tests + +--- + .../targets/docker_image/tasks/tests/old-options.yml | 2 +- + test/integration/targets/meraki_static_route/tasks/main.yml | 6 +++--- + test/integration/targets/netapp_eseries_host/tasks/run.yml | 4 ++-- + test/integration/targets/postgresql/tasks/main.yml | 2 +- + test/legacy/ovs.yaml | 4 ++-- + 5 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/test/integration/targets/docker_image/tasks/tests/old-options.yml b/test/integration/targets/docker_image/tasks/tests/old-options.yml +index 5571cf96fabc..5824a56d1fec 100644 +--- a/test/integration/targets/docker_image/tasks/tests/old-options.yml ++++ b/test/integration/targets/docker_image/tasks/tests/old-options.yml +@@ -5,7 +5,7 @@ + + - name: Registering image name + set_fact: +- inames: "{{ inames }} + [iname]" ++ inames: "{{ inames + [iname]}}" + + #################################################################### + ## build ########################################################### +diff --git a/test/integration/targets/meraki_static_route/tasks/main.yml b/test/integration/targets/meraki_static_route/tasks/main.yml +index 322e36f855e7..10ba31eab975 100644 +--- a/test/integration/targets/meraki_static_route/tasks/main.yml ++++ b/test/integration/targets/meraki_static_route/tasks/main.yml +@@ -35,7 +35,7 @@ + register: create_route + + - set_fact: +- route_ids: "{{ route_ids }} + [ '{{ create_route.data.id }}' ]" ++ route_ids: "{{ route_ids + [create_route.data.id] }}" + + - name: Create second static_route + meraki_static_route: +@@ -50,7 +50,7 @@ + register: second_create + + - set_fact: +- route_ids: "{{ route_ids }} + [ '{{ second_create.data.id }}' ]" ++ route_ids: "{{ route_ids + [second_create.data.id] }}" + + - assert: + that: +@@ -167,4 +167,4 @@ + state: absent + org_name: '{{test_org_name}}' + net_name: IntTestNetwork +- delegate_to: localhost +\ No newline at end of file ++ delegate_to: localhost +diff --git a/test/integration/targets/netapp_eseries_host/tasks/run.yml b/test/integration/targets/netapp_eseries_host/tasks/run.yml +index fd0a8d5fa209..70519b4b9423 100644 +--- a/test/integration/targets/netapp_eseries_host/tasks/run.yml ++++ b/test/integration/targets/netapp_eseries_host/tasks/run.yml +@@ -204,7 +204,7 @@ + set_fact: + port_info: [] + - set_fact: +- port_info: "{{ port_info }} + [{{ item[0] |combine(item[1]) }}]" ++ port_info: "{{ port_info + [item[0] |combine(item[1])] }}" + loop: "{{ tmp }}" + + # Compile list of expected host port information for verifying changes +@@ -225,7 +225,7 @@ + set_fact: + expected_port_info: [] + - set_fact: +- expected_port_info: "{{ expected_port_info }} + [{{ item[0] |combine(item[1]) }}]" ++ expected_port_info: "{{ expected_port_info + [ item[0] |combine(item[1]) ] }}" + loop: "{{ tmp }}" + + # Verify that each host object has the expected protocol type and address/port +diff --git a/test/integration/targets/postgresql/tasks/main.yml b/test/integration/targets/postgresql/tasks/main.yml +index d395b2820f13..5d3a21b61e71 100644 +--- a/test/integration/targets/postgresql/tasks/main.yml ++++ b/test/integration/targets/postgresql/tasks/main.yml +@@ -235,7 +235,7 @@ + - 'yes' + + - set_fact: +- encryption_values: '{{ encryption_values }} + ["no"]' ++ encryption_values: '{{ encryption_values + ["no"]}}' + when: postgres_version_resp.stdout is version('10', '<=') + + - include: test_password.yml +diff --git a/test/legacy/ovs.yaml b/test/legacy/ovs.yaml +index 4eff414f1de8..35d3acc0fd2f 100644 +--- a/test/legacy/ovs.yaml ++++ b/test/legacy/ovs.yaml +@@ -22,7 +22,7 @@ + when: "limit_to in ['*', 'openvswitch_db']" + rescue: + - set_fact: +- failed_modules: "{{ failed_modules }} + [ 'openvswitch_db' ]" ++ failed_modules: "{{ failed_modules + [ 'openvswitch_db' ]}}" + test_failed: true + + +@@ -33,4 +33,4 @@ + - name: Has any previous test failed? + fail: + msg: "One or more tests failed, check log for details" +- when: test_failed +\ No newline at end of file ++ when: test_failed diff --git a/ansible.spec b/ansible.spec index c3cdcb2..a81fb1f 100644 --- a/ansible.spec +++ b/ansible.spec @@ -29,16 +29,19 @@ Name: ansible Summary: SSH-based configuration management, deployment, and task execution system -Version: 2.8.0 -Release: 2%{?dist} +Version: 2.8.1 +Release: 1%{?dist} License: GPLv3+ Source0: https://releases.ansible.com/ansible/%{name}-%{version}.tar.gz -# This patch adds compat for the tojson filter in jinja2 -# Older versions do not have this filer. -# Upstream at https://github.com/ansible/ansible/pull/56596 -Patch1: https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/56596.patch +# Patch for CVE-2019-10156 +# https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/57188 +Patch1: https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/57188.patch + +# Patch for python 3.8 +# https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/56806 +Patch2: https://patch-diff.githubusercontent.com/raw/ansible/ansible/pull/56806.patch # Patch to utilize a newer jinja2 package on epel6 # Non-upstreamable as it creates a dependency on a specific version of jinja. @@ -79,9 +82,9 @@ BuildRequires: asciidoc # We don't run tests on epel6, so don't bother pulling these in there. %if (0%{?fedora} || 0%{?rhel} > 6) BuildRequires: PyYAML -BuildRequires: python-crypto +BuildRequires: python2-cryptography +BuildRequires: python2-crypto BuildRequires: python-paramiko -BuildRequires: python-keyczar BuildRequires: python-six BuildRequires: python-nose BuildRequires: python-coverage @@ -123,9 +126,8 @@ BuildRequires: python-jinja2 %endif Requires: PyYAML -Requires: python-crypto +Requires: python2-cryptography Requires: python-paramiko -Requires: python-keyczar Requires: python-httplib2 Requires: python-setuptools Requires: python-six @@ -188,7 +190,9 @@ BuildRequires: python3-setuptools # For tests BuildRequires: python3-PyYAML BuildRequires: python3-paramiko +BuildRequires: python3-cryptography BuildRequires: python3-crypto +BuildRequires: python3-pbkdf2 BuildRequires: python3-packaging BuildRequires: python3-pexpect BuildRequires: python3-winrm @@ -220,7 +224,7 @@ BuildRequires: python3-jinja2 Requires: python3-PyYAML Requires: python3-paramiko -Requires: python3-crypto +Requires: python3-cryptography # accelerate is the only thing that makes keyczar mandatory. Since accelerate # is deprecated, just ignore it #Requires: python3-keyczar @@ -263,7 +267,8 @@ This package installs extensive documentation for ansible %prep %setup -q -n %{name}-%{version} -%patch1 -p1 +%patch1 -p1 +%patch2 -p1 %if 0%{?rhel} == 6 %patch100 -p1 @@ -445,6 +450,12 @@ popd %endif %changelog +* Sun Jun 09 2019 Kevin Fenzi - 2.8.1-1 +- Update to 2.8.1. Fixes bug #1718131 +- Sync up Requires/Buildrequires with upstream. +- Add patch for python 3.8 building. Fixes bug #1712531 +- Add patch for CVE-2019-10156. + * Fri May 17 2019 Kevin Fenzi - 2.8.0-2 - Fixes for various releases build/test issues. diff --git a/sources b/sources index 19fd2bd..a8d56b7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (ansible-2.8.0.tar.gz) = fab8a0ac00e947e47ab606bee0a15e8c031f900b5e6fc68540429db0035ffdf3144e18e1d2265ac07bbea0a78873b85c43e636ee51ecfe14f3d612d2c54eb29c +SHA512 (ansible-2.8.1.tar.gz) = 08be80584edfe28f11fe750735ade117deaf3a7c98fe15fb2fa0e3a5ed0c3f98cd126b60386e51d15ce275e8f1fc3eda0177bb56e0823b2f2b7702cc0e35be92