diff options
author | Clint Byrum <clint@fewbar.com> | 2013-04-08 17:55:15 -0700 |
---|---|---|
committer | Clint Byrum <clint@fewbar.com> | 2013-04-10 15:13:48 -0700 |
commit | 97f016304e397dee7fa2ca10c5b37f72d799f078 (patch) | |
tree | e4da82f59d6fbd2278e1b23b4027c23586100e09 | |
parent | e0f26667c4383392be367a73fa91c095daa14269 (diff) | |
download | heat-cfntools-97f016304e397dee7fa2ca10c5b37f72d799f078.tar.gz |
Cache metadata in /var/cache instead of /tmp1.2.2
/tmp is unsafe if a user were to somehow be able to create the file
before it was cached there they can issue commands to cfn-init that
would likely elevate their permissions.
Fixes bug #1164756
Change-Id: I54e1e1be178274cb0a2b50f54e859e004e1f1c78
-rw-r--r-- | heat_cfntools/cfntools/cfn_helper.py | 18 | ||||
-rw-r--r-- | heat_cfntools/tests/test_cfn_helper.py | 26 |
2 files changed, 40 insertions, 4 deletions
diff --git a/heat_cfntools/cfntools/cfn_helper.py b/heat_cfntools/cfntools/cfn_helper.py index 27f883b..7bb8cc0 100644 --- a/heat_cfntools/cfntools/cfn_helper.py +++ b/heat_cfntools/cfntools/cfn_helper.py @@ -1077,7 +1077,7 @@ class Metadata(object): self, meta_str=None, default_path='/var/lib/heat-cfntools/cfn-init-data', - last_path='/tmp/last_metadata'): + last_path='/var/cache/heat-cfntools/last_metadata'): """ Read the metadata from the given filename """ @@ -1091,13 +1091,14 @@ class Metadata(object): # If reading remote metadata fails, we fall-back on local files # in order to get the most up-to-date version, we try: - # /tmp/last_metadata, followed by + # /var/cache/heat-cfntools/last_metadata, followed by # /var/lib/heat-cfntools/cfn-init-data # This should allow us to do the right thing both during the # first cfn-init run (when we only have cfn-init-data), and # in the event of a temporary interruption to connectivity - # affecting cfn-hup, in which case we want to use last_metadata - # or the logic below could re-run a stale cfn-init-data + # affecting cfn-hup, in which case we want to use the locally + # cached metadata or the logic below could re-run a stale + # cfn-init-data fd = None for filepath in [last_path, default_path]: try: @@ -1136,6 +1137,15 @@ class Metadata(object): if old_md5 != current_md5: self._has_changed = True + # if cache dir does not exist try to create it + cache_dir = os.path.dirname(last_path) + if not os.path.isdir(cache_dir): + try: + os.makedirs(cache_dir, mode=0700) + except IOError as e: + LOG.warn('could not create metadata cache dir %s [%s]' % + (cache_dir, e)) + return # save current metadata to file tmp_mdpath = last_path with open(tmp_mdpath, 'w+') as cf: diff --git a/heat_cfntools/tests/test_cfn_helper.py b/heat_cfntools/tests/test_cfn_helper.py index 5f27e90..aad782b 100644 --- a/heat_cfntools/tests/test_cfn_helper.py +++ b/heat_cfntools/tests/test_cfn_helper.py @@ -570,6 +570,32 @@ class TestMetadataRetrieve(testtools.TestCase): self.assertDictEqual(md_data, md._metadata) self.assertEqual(md_str, str(md)) + def test_metadata_creates_cache(self): + temp_home = tempfile.mkdtemp() + + def cleanup_temp_home(thome): + os.unlink(os.path.join(thome, 'cache', 'last_metadata')) + os.rmdir(os.path.join(thome, 'cache')) + os.rmdir(os.path.join(thome)) + + self.addCleanup(cleanup_temp_home, temp_home) + + last_path = os.path.join(temp_home, 'cache', 'last_metadata') + md_data = {"AWS::CloudFormation::Init": {"config": {"files": { + "/tmp/foo": {"content": "bar"}}}}} + md_str = json.dumps(md_data) + md = cfn_helper.Metadata('teststack', None) + + self.assertFalse(os.path.exists(last_path), + "last_metadata file already exists") + md.retrieve(meta_str=md_str, last_path=last_path) + self.assertTrue(os.path.exists(last_path), + "last_metadata file should exist") + # Ensure created dirs and file have right perms + self.assertTrue(os.stat(last_path).st_mode & 0600 == 0600) + self.assertTrue( + os.stat(os.path.dirname(last_path)).st_mode & 0700 == 0700) + def test_is_valid_metadata(self): md_data = {"AWS::CloudFormation::Init": {"config": {"files": { "/tmp/foo": {"content": "bar"}}}}} |