[controller ansiballz] escape directory regex (#74270)
Change: - We were passing a directory name directly to re.compile(). If the directory isn't valid regex (or is) this can have odd side effects, such as crashing. - Fix a few other similar cases, but less likely to be a real issue. Test Plan: - New test Signed-off-by: Rick Elrod <rick@elrod.me>
This commit is contained in:
parent
cf4a9fcd0f
commit
7ef3dc2b8b
6 changed files with 27 additions and 3 deletions
|
@ -0,0 +1,4 @@
|
||||||
|
bugfixes:
|
||||||
|
- >-
|
||||||
|
ansiballz - avoid treating path to site_packages as regex; escape it.
|
||||||
|
This prevents a crash when ansible is installed to, or running from, an oddly named directory like ``ansi[ble``
|
|
@ -417,7 +417,7 @@ else:
|
||||||
# Do this instead of getting site-packages from distutils.sysconfig so we work when we
|
# Do this instead of getting site-packages from distutils.sysconfig so we work when we
|
||||||
# haven't been installed
|
# haven't been installed
|
||||||
site_packages = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
site_packages = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||||
CORE_LIBRARY_PATH_RE = re.compile(r'%s/(?P<path>ansible/modules/.*)\.(py|ps1)$' % site_packages)
|
CORE_LIBRARY_PATH_RE = re.compile(r'%s/(?P<path>ansible/modules/.*)\.(py|ps1)$' % re.escape(site_packages))
|
||||||
COLLECTION_PATH_RE = re.compile(r'/(?P<path>ansible_collections/[^/]+/[^/]+/plugins/modules/.*)\.(py|ps1)$')
|
COLLECTION_PATH_RE = re.compile(r'/(?P<path>ansible_collections/[^/]+/[^/]+/plugins/modules/.*)\.(py|ps1)$')
|
||||||
|
|
||||||
# Detect new-style Python modules by looking for required imports:
|
# Detect new-style Python modules by looking for required imports:
|
||||||
|
|
|
@ -1173,7 +1173,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
|
|
||||||
# try to figure out if we are missing interpreter
|
# try to figure out if we are missing interpreter
|
||||||
if self._used_interpreter is not None:
|
if self._used_interpreter is not None:
|
||||||
match = re.compile('%s: (?:No such file or directory|not found)' % self._used_interpreter.lstrip('!#'))
|
interpreter = re.escape(self._used_interpreter.lstrip('!#'))
|
||||||
|
match = re.compile('%s: (?:No such file or directory|not found)' % interpreter)
|
||||||
if match.search(data['module_stderr']) or match.search(data['module_stdout']):
|
if match.search(data['module_stderr']) or match.search(data['module_stdout']):
|
||||||
data['msg'] = "The module failed to execute correctly, you probably need to set the interpreter."
|
data['msg'] = "The module failed to execute correctly, you probably need to set the interpreter."
|
||||||
|
|
||||||
|
|
|
@ -133,7 +133,7 @@ def clean_facts(facts):
|
||||||
# next we remove any connection plugin specific vars
|
# next we remove any connection plugin specific vars
|
||||||
for conn_path in connection_loader.all(path_only=True):
|
for conn_path in connection_loader.all(path_only=True):
|
||||||
conn_name = os.path.splitext(os.path.basename(conn_path))[0]
|
conn_name = os.path.splitext(os.path.basename(conn_path))[0]
|
||||||
re_key = re.compile('^ansible_%s_' % conn_name)
|
re_key = re.compile('^ansible_%s_' % re.escape(conn_name))
|
||||||
for fact_key in fact_keys:
|
for fact_key in fact_keys:
|
||||||
# most lightweight VM or container tech creates devices with this pattern, this avoids filtering them out
|
# most lightweight VM or container tech creates devices with this pattern, this avoids filtering them out
|
||||||
if (re_key.match(fact_key) and not fact_key.endswith(('_bridge', '_gwbridge'))) or fact_key.startswith('ansible_become_'):
|
if (re_key.match(fact_key) and not fact_key.endswith(('_bridge', '_gwbridge'))) or fact_key.startswith('ansible_become_'):
|
||||||
|
|
15
test/integration/targets/ansible/module_common_regex_regression.sh
Executable file
15
test/integration/targets/ansible/module_common_regex_regression.sh
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# #74270 -- ensure we escape directory names before passing to re.compile()
|
||||||
|
# particularly in module_common.
|
||||||
|
|
||||||
|
set -eux
|
||||||
|
|
||||||
|
lib_path=$(python -c 'import os, ansible; print(os.path.dirname(os.path.dirname(ansible.__file__)))')
|
||||||
|
bad_dir="${OUTPUT_DIR}/ansi[ble"
|
||||||
|
|
||||||
|
mkdir "${bad_dir}"
|
||||||
|
cp -a "${lib_path}" "${bad_dir}"
|
||||||
|
|
||||||
|
PYTHONPATH="${bad_dir}/lib" ansible -m ping localhost -i ../../inventory "$@"
|
||||||
|
rm -rf "${bad_dir}"
|
|
@ -80,3 +80,7 @@ if ansible-playbook -i ../../inventory --extra-vars ./vars.yml playbook.yml; the
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ansible-playbook -i ../../inventory --extra-vars @./vars.yml playbook.yml
|
ansible-playbook -i ../../inventory --extra-vars @./vars.yml playbook.yml
|
||||||
|
|
||||||
|
# #74270 -- ensure we escape directory names before passing to re.compile()
|
||||||
|
# particularly in module_common.
|
||||||
|
bash module_common_regex_regression.sh
|
||||||
|
|
Loading…
Reference in a new issue