High severityNVD Advisory· Published Aug 20, 2012· Updated Apr 29, 2026
CVE-2012-3447
CVE-2012-3447
Description
virt/disk/api.py in OpenStack Compute (Nova) 2012.1.x before 2012.1.2 and Folsom before Folsom-3 allows remote authenticated users to overwrite arbitrary files via a symlink attack on a file in an image that uses a symlink that is only readable by root. NOTE: this vulnerability exists because of an incomplete fix for CVE-2012-3361.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
novaPyPI | < 12.0.0 | 12.0.0 |
Affected products
2Patches
2d9577ce9f266Prohibit file injection writing to host filesystem
4 files changed · +23 −1
nova/rootwrap/compute.py+4 −0 modified@@ -189,6 +189,10 @@ # nova/virt/libvirt/utils.py: 'qemu-img' filters.CommandFilter("/usr/bin/qemu-img", "root"), + # nova/virt/disk/api.py: 'readlink', '-e' + filters.CommandFilter("/usr/bin/readlink", "root"), + filters.CommandFilter("/bin/readlink", "root"), + # nova/virt/disk/api.py: 'touch', target filters.CommandFilter("/usr/bin/touch", "root"),
nova/tests/test_virt.py+12 −0 modified@@ -18,6 +18,7 @@ from nova import exception from nova import flags from nova import test +from nova import utils from nova.virt.disk import api as disk_api from nova.virt import driver @@ -86,6 +87,17 @@ def test_swap_is_usable(self): class TestVirtDisk(test.TestCase): + def setUp(self): + super(TestVirtDisk, self).setUp() + + real_execute = utils.execute + + def nonroot_execute(*cmd_parts, **kwargs): + kwargs.pop('run_as_root', None) + return real_execute(*cmd_parts, **kwargs) + + self.stubs.Set(utils, 'execute', nonroot_execute) + def test_check_safe_path(self): ret = disk_api._join_and_check_path_within_fs('/foo', 'etc', 'something.conf')
nova/tests/test_xenapi.py+4 −0 modified@@ -597,9 +597,13 @@ def _tee_handler(cmd, **kwargs): self._tee_executed = True return '', '' + def _readlink_handler(cmd_parts, **kwargs): + return os.path.realpath(cmd_parts[2]), '' + fake_utils.fake_execute_set_repliers([ # Capture the tee .../etc/network/interfaces command (r'tee.*interfaces', _tee_handler), + (r'readlink -nm.*', _readlink_handler), ]) self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL,
nova/virt/disk/api.py+3 −1 modified@@ -314,7 +314,9 @@ def _join_and_check_path_within_fs(fs, *args): mounted guest fs. Trying to be clever and specifying a path with '..' in it will hit this safeguard. ''' - absolute_path = os.path.realpath(os.path.join(fs, *args)) + absolute_path, _err = utils.execute('readlink', '-nm', + os.path.join(fs, *args), + run_as_root=True) if not absolute_path.startswith(os.path.realpath(fs) + '/'): raise exception.Invalid(_('injected file path not valid')) return absolute_path
ce4b2e27be45Prohibit file injection writing to host filesystem
3 files changed · +36 −17
nova/tests/test_virt.py+29 −16 modified@@ -99,22 +99,6 @@ def fake_execute(*cmd, **kwargs): self.stubs.Set(utils, 'execute', fake_execute) - def test_check_safe_path(self): - ret = disk_api._join_and_check_path_within_fs('/foo', 'etc', - 'something.conf') - self.assertEquals(ret, '/foo/etc/something.conf') - - def test_check_unsafe_path(self): - self.assertRaises(exception.Invalid, - disk_api._join_and_check_path_within_fs, - '/foo', 'etc/../../../something.conf') - - def test_inject_files_with_bad_path(self): - self.assertRaises(exception.Invalid, - disk_api._inject_file_into_fs, - '/tmp', '/etc/../../../../etc/passwd', - 'hax') - def test_lxc_destroy_container(self): def proc_mounts(self, mount_point): @@ -165,3 +149,32 @@ def proc_mounts(self, mount_point): self.executes.pop() self.assertEqual(self.executes, expected_commands) + + +class TestVirtDiskPaths(test.TestCase): + def setUp(self): + super(TestVirtDiskPaths, self).setUp() + + real_execute = utils.execute + + def nonroot_execute(*cmd_parts, **kwargs): + kwargs.pop('run_as_root', None) + return real_execute(*cmd_parts, **kwargs) + + self.stubs.Set(utils, 'execute', nonroot_execute) + + def test_check_safe_path(self): + ret = disk_api._join_and_check_path_within_fs('/foo', 'etc', + 'something.conf') + self.assertEquals(ret, '/foo/etc/something.conf') + + def test_check_unsafe_path(self): + self.assertRaises(exception.Invalid, + disk_api._join_and_check_path_within_fs, + '/foo', 'etc/../../../something.conf') + + def test_inject_files_with_bad_path(self): + self.assertRaises(exception.Invalid, + disk_api._inject_file_into_fs, + '/tmp', '/etc/../../../../etc/passwd', + 'hax')
nova/tests/test_xenapi.py+4 −0 modified@@ -677,9 +677,13 @@ def _tee_handler(cmd, **kwargs): self._tee_executed = True return '', '' + def _readlink_handler(cmd_parts, **kwargs): + return os.path.realpath(cmd_parts[2]), '' + fake_utils.fake_execute_set_repliers([ # Capture the tee .../etc/network/interfaces command (r'tee.*interfaces', _tee_handler), + (r'readlink -nm.*', _readlink_handler), ]) self._test_spawn(IMAGE_MACHINE, IMAGE_KERNEL,
nova/virt/disk/api.py+3 −1 modified@@ -363,7 +363,9 @@ def _join_and_check_path_within_fs(fs, *args): mounted guest fs. Trying to be clever and specifying a path with '..' in it will hit this safeguard. ''' - absolute_path = os.path.realpath(os.path.join(fs, *args)) + absolute_path, _err = utils.execute('readlink', '-nm', + os.path.join(fs, *args), + run_as_root=True) if not absolute_path.startswith(os.path.realpath(fs) + '/'): raise exception.Invalid(_('injected file path not valid')) return absolute_path
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
13- github.com/openstack/nova/commit/ce4b2e27be45a85b310237615c47eb53f37bb5f3nvdExploitPatchWEB
- github.com/openstack/nova/commit/d9577ce9f266166a297488445b5b0c93c1ddb368nvdExploitPatchWEB
- github.com/advisories/GHSA-xc4g-7vw8-924hghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2012-3447ghsaADVISORY
- www.openwall.com/lists/oss-security/2012/08/07/1nvdWEB
- bugs.launchpad.net/nova/+bug/1031311nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- exchange.xforce.ibmcloud.com/vulnerabilities/77539nvdWEB
- github.com/pypa/advisory-database/tree/main/vulns/nova/PYSEC-2012-21.yamlghsaWEB
- review.openstack.orgghsaWEB
- web.archive.org/web/20120824003029/http://www.securityfocus.com/bid/54869ghsaWEB
- www.securityfocus.com/bid/54869nvd
- review.openstack.orgnvd
News mentions
0No linked articles in our index yet.