From de4d73d65607e8f350a798131e5792e82830078b Mon Sep 17 00:00:00 2001 From: Chris Meyers Date: Tue, 23 Feb 2021 10:01:51 -0500 Subject: [PATCH] jailed tasks can not share files * Permission changes in bubblewrap shared directories persist when the jailed tasks finish execution. Effectively, this allows playbooks executing as awx to share files with lower privileged users on the system. * To prevent this, we wrap the directory that we intend to share with bubblewrap in another directory that is owned by awx with permissions 700. The wrapped directory permissions can be changed by the jailed task while the wrapper directory can not. * Given `/tmp/bwrap_3_abcd/awx_3_1234/` `bwrap_3_abcd` is the wrapper directory and `awx_3_1234` is the wrapped directory. --- awx/main/tasks.py | 17 ++++++++++++++--- awx/main/utils/common.py | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/awx/main/tasks.py b/awx/main/tasks.py index e6cc61b7dd..c88e9a4fff 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -893,10 +893,19 @@ class BaseTask(object): ''' Create a temporary directory for job-related files. ''' - path = tempfile.mkdtemp(prefix='awx_%s_' % instance.pk, dir=settings.AWX_PROOT_BASE_PATH) - os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + bwrap_path = tempfile.mkdtemp( + prefix=f'bwrap_{instance.pk}_', + dir=settings.AWX_PROOT_BASE_PATH + ) + os.chmod(bwrap_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) if settings.AWX_CLEANUP_PATHS: - self.cleanup_paths.append(path) + self.cleanup_paths.append(bwrap_path) + + path = tempfile.mkdtemp( + prefix='awx_%s_' % instance.pk, + dir=bwrap_path, + ) + os.chmod(path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) runner_project_folder = os.path.join(path, 'project') if not os.path.exists(runner_project_folder): # Ansible Runner requires that this directory exists. @@ -1008,6 +1017,8 @@ class BaseTask(object): '/etc/ssh', '/var/lib/awx', '/var/log', + '/home', + '/var/tmp', settings.PROJECTS_ROOT, settings.JOBOUTPUT_ROOT, ] + getattr(settings, 'AWX_PROOT_HIDE_PATHS', None) or [], diff --git a/awx/main/utils/common.py b/awx/main/utils/common.py index 283a028f3f..8b3065e113 100644 --- a/awx/main/utils/common.py +++ b/awx/main/utils/common.py @@ -863,7 +863,7 @@ def wrap_args_with_proot(args, cwd, **kwargs): new_args = [getattr(settings, 'AWX_PROOT_CMD', 'bwrap'), '--unshare-pid', '--dev-bind', '/', '/', '--proc', '/proc'] hide_paths = [settings.AWX_PROOT_BASE_PATH] if not kwargs.get('isolated'): - hide_paths.extend(['/etc/tower', '/var/lib/awx', '/var/log', '/etc/ssh', + hide_paths.extend(['/etc/tower', '/var/lib/awx', '/var/log', '/etc/ssh', '/var/tmp', '/home', settings.PROJECTS_ROOT, settings.JOBOUTPUT_ROOT]) hide_paths.extend(getattr(settings, 'AWX_PROOT_HIDE_PATHS', None) or []) for path in sorted(set(hide_paths)):