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.
This commit is contained in:
Chris Meyers 2021-02-23 10:01:51 -05:00 committed by Ryan Petrello
parent 3358e568b5
commit de4d73d656
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
2 changed files with 15 additions and 4 deletions

View File

@ -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 [],

View File

@ -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)):